blob: 1906df6247d532387a77d94b64bd379f9135f653 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkerefc30292011-11-10 14:43:23 +00004 * Copyright (C) 2006-2011, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
Paul Bakkerad8d3542012-02-16 15:28:14 +000026 * The ITU-T X.509 standard defines a certificate format for PKI.
Paul Bakker5121ce52009-01-03 21:22:43 +000027 *
Paul Bakker5121ce52009-01-03 21:22:43 +000028 * http://www.ietf.org/rfc/rfc3279.txt
Paul Bakkerad8d3542012-02-16 15:28:14 +000029 * http://www.ietf.org/rfc/rfc3280.txt
Paul Bakker5121ce52009-01-03 21:22:43 +000030 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000042#include "polarssl/asn1.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000043#include "polarssl/pem.h"
Paul Bakker40e46942009-01-03 21:51:57 +000044#include "polarssl/des.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010045#if defined(POLARSSL_MD2_C)
Paul Bakker40e46942009-01-03 21:51:57 +000046#include "polarssl/md2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010047#endif
48#if defined(POLARSSL_MD4_C)
Paul Bakker40e46942009-01-03 21:51:57 +000049#include "polarssl/md4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010050#endif
51#if defined(POLARSSL_MD5_C)
Paul Bakker40e46942009-01-03 21:51:57 +000052#include "polarssl/md5.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010053#endif
54#if defined(POLARSSL_SHA1_C)
Paul Bakker40e46942009-01-03 21:51:57 +000055#include "polarssl/sha1.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010056#endif
57#if defined(POLARSSL_SHA2_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000058#include "polarssl/sha2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010059#endif
60#if defined(POLARSSL_SHA4_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000061#include "polarssl/sha4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010062#endif
Paul Bakker1b57b062011-01-06 15:48:19 +000063#include "polarssl/dhm.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000064
65#include <string.h>
66#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000067#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000068#include <windows.h>
69#else
Paul Bakker5121ce52009-01-03 21:22:43 +000070#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000071#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000072
Paul Bakker335db3f2011-04-25 15:28:35 +000073#if defined(POLARSSL_FS_IO)
74#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000075#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000076#include <sys/types.h>
77#include <dirent.h>
78#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000079#endif
80
Paul Bakker5121ce52009-01-03 21:22:43 +000081/*
Paul Bakker5121ce52009-01-03 21:22:43 +000082 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
83 */
84static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000085 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000086 int *ver )
87{
Paul Bakker23986e52011-04-24 08:57:21 +000088 int ret;
89 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000090
91 if( ( ret = asn1_get_tag( p, end, &len,
92 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
93 {
Paul Bakker40e46942009-01-03 21:51:57 +000094 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +000095 {
96 *ver = 0;
97 return( 0 );
98 }
Paul Bakker5121ce52009-01-03 21:22:43 +000099
100 return( ret );
101 }
102
103 end = *p + len;
104
105 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000106 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000109 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000110 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000111
112 return( 0 );
113}
114
115/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000116 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000117 */
118static int x509_crl_get_version( unsigned char **p,
119 const unsigned char *end,
120 int *ver )
121{
122 int ret;
123
124 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
125 {
126 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000127 {
128 *ver = 0;
129 return( 0 );
130 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000131
132 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
133 }
134
135 return( 0 );
136}
137
138/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000139 * CertificateSerialNumber ::= INTEGER
140 */
141static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000142 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000143 x509_buf *serial )
144{
145 int ret;
146
147 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000148 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000149 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000150
151 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
152 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000153 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000154 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000155
156 serial->tag = *(*p)++;
157
158 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000159 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000160
161 serial->p = *p;
162 *p += serial->len;
163
164 return( 0 );
165}
166
167/*
168 * AlgorithmIdentifier ::= SEQUENCE {
169 * algorithm OBJECT IDENTIFIER,
170 * parameters ANY DEFINED BY algorithm OPTIONAL }
171 */
172static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000173 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000174 x509_buf *alg )
175{
Paul Bakker23986e52011-04-24 08:57:21 +0000176 int ret;
177 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000178
179 if( ( ret = asn1_get_tag( p, end, &len,
180 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000181 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000182
183 end = *p + len;
184 alg->tag = **p;
185
186 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000187 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
189 alg->p = *p;
190 *p += alg->len;
191
192 if( *p == end )
193 return( 0 );
194
195 /*
196 * assume the algorithm parameters must be NULL
197 */
198 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000199 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000200
201 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000202 return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
Paul Bakker40e46942009-01-03 21:51:57 +0000203 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000204
205 return( 0 );
206}
207
208/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000209 * AttributeTypeAndValue ::= SEQUENCE {
210 * type AttributeType,
211 * value AttributeValue }
212 *
213 * AttributeType ::= OBJECT IDENTIFIER
214 *
215 * AttributeValue ::= ANY DEFINED BY AttributeType
216 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000217static int x509_get_attr_type_value( unsigned char **p,
218 const unsigned char *end,
219 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000220{
Paul Bakker23986e52011-04-24 08:57:21 +0000221 int ret;
222 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000223 x509_buf *oid;
224 x509_buf *val;
225
226 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000228 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000229
Paul Bakker5121ce52009-01-03 21:22:43 +0000230 oid = &cur->oid;
231 oid->tag = **p;
232
233 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000234 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000235
236 oid->p = *p;
237 *p += oid->len;
238
239 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000240 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000241 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
243 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
244 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
245 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000246 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000247 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
249 val = &cur->val;
250 val->tag = *(*p)++;
251
252 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000253 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255 val->p = *p;
256 *p += val->len;
257
258 cur->next = NULL;
259
Paul Bakker400ff6f2011-02-20 10:40:16 +0000260 return( 0 );
261}
262
263/*
264 * RelativeDistinguishedName ::=
265 * SET OF AttributeTypeAndValue
266 *
267 * AttributeTypeAndValue ::= SEQUENCE {
268 * type AttributeType,
269 * value AttributeValue }
270 *
271 * AttributeType ::= OBJECT IDENTIFIER
272 *
273 * AttributeValue ::= ANY DEFINED BY AttributeType
274 */
275static int x509_get_name( unsigned char **p,
276 const unsigned char *end,
277 x509_name *cur )
278{
Paul Bakker23986e52011-04-24 08:57:21 +0000279 int ret;
280 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000281 const unsigned char *end2;
282 x509_name *use;
283
284 if( ( ret = asn1_get_tag( p, end, &len,
285 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000286 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000287
288 end2 = end;
289 end = *p + len;
290 use = cur;
291
292 do
293 {
294 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
295 return( ret );
296
297 if( *p != end )
298 {
299 use->next = (x509_name *) malloc(
300 sizeof( x509_name ) );
301
302 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000303 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000304
305 memset( use->next, 0, sizeof( x509_name ) );
306
307 use = use->next;
308 }
309 }
310 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
312 /*
313 * recurse until end of SEQUENCE is reached
314 */
315 if( *p == end2 )
316 return( 0 );
317
318 cur->next = (x509_name *) malloc(
319 sizeof( x509_name ) );
320
321 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000322 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
Paul Bakker430ffbe2012-05-01 08:14:20 +0000324 memset( cur->next, 0, sizeof( x509_name ) );
325
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 return( x509_get_name( p, end2, cur->next ) );
327}
328
329/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 * Time ::= CHOICE {
331 * utcTime UTCTime,
332 * generalTime GeneralizedTime }
333 */
Paul Bakker91200182010-02-18 21:26:15 +0000334static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000335 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000336 x509_time *time )
337{
Paul Bakker23986e52011-04-24 08:57:21 +0000338 int ret;
339 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000340 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000341 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000342
Paul Bakker91200182010-02-18 21:26:15 +0000343 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000344 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
345 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000346
Paul Bakker91200182010-02-18 21:26:15 +0000347 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000348
Paul Bakker91200182010-02-18 21:26:15 +0000349 if ( tag == ASN1_UTC_TIME )
350 {
351 (*p)++;
352 ret = asn1_get_len( p, end, &len );
353
354 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000355 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000356
Paul Bakker91200182010-02-18 21:26:15 +0000357 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000358 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
359 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000360
Paul Bakker91200182010-02-18 21:26:15 +0000361 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
362 &time->year, &time->mon, &time->day,
363 &time->hour, &time->min, &time->sec ) < 5 )
364 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000365
Paul Bakker400ff6f2011-02-20 10:40:16 +0000366 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000367 time->year += 1900;
368
369 *p += len;
370
371 return( 0 );
372 }
373 else if ( tag == ASN1_GENERALIZED_TIME )
374 {
375 (*p)++;
376 ret = asn1_get_len( p, end, &len );
377
378 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000379 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000380
381 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000382 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
383 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000384
385 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
386 &time->year, &time->mon, &time->day,
387 &time->hour, &time->min, &time->sec ) < 5 )
388 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
389
390 *p += len;
391
392 return( 0 );
393 }
394 else
Paul Bakker9d781402011-05-09 16:17:09 +0000395 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000396}
397
398
399/*
400 * Validity ::= SEQUENCE {
401 * notBefore Time,
402 * notAfter Time }
403 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000404static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000405 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 x509_time *from,
407 x509_time *to )
408{
Paul Bakker23986e52011-04-24 08:57:21 +0000409 int ret;
410 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 if( ( ret = asn1_get_tag( p, end, &len,
413 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000414 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
416 end = *p + len;
417
Paul Bakker91200182010-02-18 21:26:15 +0000418 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000419 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Paul Bakker91200182010-02-18 21:26:15 +0000421 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000422 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
424 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000425 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000426 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
428 return( 0 );
429}
430
431/*
432 * SubjectPublicKeyInfo ::= SEQUENCE {
433 * algorithm AlgorithmIdentifier,
434 * subjectPublicKey BIT STRING }
435 */
436static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000437 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 x509_buf *pk_alg_oid,
439 mpi *N, mpi *E )
440{
Paul Bakker65a19092013-06-06 21:14:58 +0200441 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000442 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000443 unsigned char *end2;
444
445 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
446 return( ret );
447
448 /*
449 * only RSA public keys handled at this time
450 */
Paul Bakker65a19092013-06-06 21:14:58 +0200451 if( pk_alg_oid->len != 9 ||
452 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker400ff6f2011-02-20 10:40:16 +0000453 {
Paul Bakkered56b222011-07-13 11:26:43 +0000454 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker65a19092013-06-06 21:14:58 +0200455 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000458 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
460 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000461 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000462 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
464 end2 = *p + len;
465
466 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000467 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
469 /*
470 * RSAPublicKey ::= SEQUENCE {
471 * modulus INTEGER, -- n
472 * publicExponent INTEGER -- e
473 * }
474 */
475 if( ( ret = asn1_get_tag( p, end2, &len,
476 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000477 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
479 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000480 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000481 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
483 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
484 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000485 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
487 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000488 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000489 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
491 return( 0 );
492}
493
494static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000495 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 x509_buf *sig )
497{
Paul Bakker23986e52011-04-24 08:57:21 +0000498 int ret;
499 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
Paul Bakker8afa70d2012-02-11 18:42:45 +0000501 if( ( end - *p ) < 1 )
502 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
503 POLARSSL_ERR_ASN1_OUT_OF_DATA );
504
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 sig->tag = **p;
506
507 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000508 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
Paul Bakker74111d32011-01-15 16:57:55 +0000510
Paul Bakker5121ce52009-01-03 21:22:43 +0000511 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000512 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000513
514 sig->len = len;
515 sig->p = *p;
516
517 *p += len;
518
519 return( 0 );
520}
521
522/*
523 * X.509 v2/v3 unique identifier (not parsed)
524 */
525static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000526 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000527 x509_buf *uid, int n )
528{
529 int ret;
530
531 if( *p == end )
532 return( 0 );
533
534 uid->tag = **p;
535
536 if( ( ret = asn1_get_tag( p, end, &uid->len,
537 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
538 {
Paul Bakker40e46942009-01-03 21:51:57 +0000539 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000540 return( 0 );
541
542 return( ret );
543 }
544
545 uid->p = *p;
546 *p += uid->len;
547
548 return( 0 );
549}
550
551/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000552 * X.509 Extensions (No parsing of extensions, pointer should
553 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000554 */
555static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000556 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000557 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000558{
Paul Bakker23986e52011-04-24 08:57:21 +0000559 int ret;
560 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000561
562 if( *p == end )
563 return( 0 );
564
565 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000566
Paul Bakker5121ce52009-01-03 21:22:43 +0000567 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000568 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000569 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
571 ext->p = *p;
572 end = *p + ext->len;
573
574 /*
575 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
576 *
577 * Extension ::= SEQUENCE {
578 * extnID OBJECT IDENTIFIER,
579 * critical BOOLEAN DEFAULT FALSE,
580 * extnValue OCTET STRING }
581 */
582 if( ( ret = asn1_get_tag( p, end, &len,
583 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000584 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
586 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000587 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000588 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000589
Paul Bakkerd98030e2009-05-02 15:13:40 +0000590 return( 0 );
591}
592
593/*
594 * X.509 CRL v2 extensions (no extensions parsed yet.)
595 */
596static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000597 const unsigned char *end,
598 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000599{
Paul Bakker23986e52011-04-24 08:57:21 +0000600 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000601 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000602
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000603 /* Get explicit tag */
604 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000605 {
606 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
607 return( 0 );
608
609 return( ret );
610 }
611
612 while( *p < end )
613 {
614 if( ( ret = asn1_get_tag( p, end, &len,
615 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000616 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000617
618 *p += len;
619 }
620
621 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000622 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000623 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
624
625 return( 0 );
626}
627
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000628/*
629 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
630 */
631static int x509_get_crl_entry_ext( unsigned char **p,
632 const unsigned char *end,
633 x509_buf *ext )
634{
635 int ret;
636 size_t len = 0;
637
638 /* OPTIONAL */
639 if (end <= *p)
640 return( 0 );
641
642 ext->tag = **p;
643 ext->p = *p;
644
645 /*
646 * Get CRL-entry extension sequence header
647 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
648 */
649 if( ( ret = asn1_get_tag( p, end, &ext->len,
650 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
651 {
652 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
653 {
654 ext->p = NULL;
655 return( 0 );
656 }
657 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
658 }
659
660 end = *p + ext->len;
661
662 if( end != *p + ext->len )
663 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
664 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
665
666 while( *p < end )
667 {
668 if( ( ret = asn1_get_tag( p, end, &len,
669 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
670 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
671
672 *p += len;
673 }
674
675 if( *p != end )
676 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
677 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
678
679 return( 0 );
680}
681
Paul Bakker74111d32011-01-15 16:57:55 +0000682static int x509_get_basic_constraints( unsigned char **p,
683 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000684 int *ca_istrue,
685 int *max_pathlen )
686{
Paul Bakker23986e52011-04-24 08:57:21 +0000687 int ret;
688 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000689
690 /*
691 * BasicConstraints ::= SEQUENCE {
692 * cA BOOLEAN DEFAULT FALSE,
693 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
694 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000695 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000696 *max_pathlen = 0; /* endless */
697
698 if( ( ret = asn1_get_tag( p, end, &len,
699 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000700 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000701
702 if( *p == end )
703 return 0;
704
Paul Bakker3cccddb2011-01-16 21:46:31 +0000705 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000706 {
707 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000708 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000709
710 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000711 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000712
Paul Bakker3cccddb2011-01-16 21:46:31 +0000713 if( *ca_istrue != 0 )
714 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000715 }
716
717 if( *p == end )
718 return 0;
719
720 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000721 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000722
723 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000724 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000725 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
726
727 (*max_pathlen)++;
728
Paul Bakker74111d32011-01-15 16:57:55 +0000729 return 0;
730}
731
732static int x509_get_ns_cert_type( unsigned char **p,
733 const unsigned char *end,
734 unsigned char *ns_cert_type)
735{
736 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000737 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000738
739 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000740 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000741
742 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000743 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000744 POLARSSL_ERR_ASN1_INVALID_LENGTH );
745
746 /* Get actual bitstring */
747 *ns_cert_type = *bs.p;
748 return 0;
749}
750
751static int x509_get_key_usage( unsigned char **p,
752 const unsigned char *end,
753 unsigned char *key_usage)
754{
755 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000756 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000757
758 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000759 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000760
Paul Bakker94a67962012-08-23 13:03:52 +0000761 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000762 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000763 POLARSSL_ERR_ASN1_INVALID_LENGTH );
764
765 /* Get actual bitstring */
766 *key_usage = *bs.p;
767 return 0;
768}
769
Paul Bakkerd98030e2009-05-02 15:13:40 +0000770/*
Paul Bakker74111d32011-01-15 16:57:55 +0000771 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
772 *
773 * KeyPurposeId ::= OBJECT IDENTIFIER
774 */
775static int x509_get_ext_key_usage( unsigned char **p,
776 const unsigned char *end,
777 x509_sequence *ext_key_usage)
778{
779 int ret;
780
781 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000782 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000783
784 /* Sequence length must be >= 1 */
785 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000786 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000787 POLARSSL_ERR_ASN1_INVALID_LENGTH );
788
789 return 0;
790}
791
792/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000793 * SubjectAltName ::= GeneralNames
794 *
795 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
796 *
797 * GeneralName ::= CHOICE {
798 * otherName [0] OtherName,
799 * rfc822Name [1] IA5String,
800 * dNSName [2] IA5String,
801 * x400Address [3] ORAddress,
802 * directoryName [4] Name,
803 * ediPartyName [5] EDIPartyName,
804 * uniformResourceIdentifier [6] IA5String,
805 * iPAddress [7] OCTET STRING,
806 * registeredID [8] OBJECT IDENTIFIER }
807 *
808 * OtherName ::= SEQUENCE {
809 * type-id OBJECT IDENTIFIER,
810 * value [0] EXPLICIT ANY DEFINED BY type-id }
811 *
812 * EDIPartyName ::= SEQUENCE {
813 * nameAssigner [0] DirectoryString OPTIONAL,
814 * partyName [1] DirectoryString }
815 *
816 * NOTE: PolarSSL only parses and uses dNSName at this point.
817 */
818static int x509_get_subject_alt_name( unsigned char **p,
819 const unsigned char *end,
820 x509_sequence *subject_alt_name )
821{
822 int ret;
823 size_t len, tag_len;
824 asn1_buf *buf;
825 unsigned char tag;
826 asn1_sequence *cur = subject_alt_name;
827
828 /* Get main sequence tag */
829 if( ( ret = asn1_get_tag( p, end, &len,
830 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
831 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
832
833 if( *p + len != end )
834 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
835 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
836
837 while( *p < end )
838 {
839 if( ( end - *p ) < 1 )
840 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
841 POLARSSL_ERR_ASN1_OUT_OF_DATA );
842
843 tag = **p;
844 (*p)++;
845 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
846 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
847
848 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
849 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
850 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
851
852 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
853 {
854 *p += tag_len;
855 continue;
856 }
857
858 buf = &(cur->buf);
859 buf->tag = tag;
860 buf->p = *p;
861 buf->len = tag_len;
862 *p += buf->len;
863
864 /* Allocate and assign next pointer */
865 if (*p < end)
866 {
867 cur->next = (asn1_sequence *) malloc(
868 sizeof( asn1_sequence ) );
869
870 if( cur->next == NULL )
871 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
872 POLARSSL_ERR_ASN1_MALLOC_FAILED );
873
Paul Bakker535e97d2012-08-23 10:49:55 +0000874 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000875 cur = cur->next;
876 }
877 }
878
879 /* Set final sequence entry's next pointer to NULL */
880 cur->next = NULL;
881
882 if( *p != end )
883 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
884 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
885
886 return( 0 );
887}
888
889/*
Paul Bakker74111d32011-01-15 16:57:55 +0000890 * X.509 v3 extensions
891 *
892 * TODO: Perform all of the basic constraints tests required by the RFC
893 * TODO: Set values for undetected extensions to a sane default?
894 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000895 */
896static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000897 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000898 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000899{
Paul Bakker23986e52011-04-24 08:57:21 +0000900 int ret;
901 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000902 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000903
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000904 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000905 {
906 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
907 return( 0 );
908
909 return( ret );
910 }
911
Paul Bakker5121ce52009-01-03 21:22:43 +0000912 while( *p < end )
913 {
Paul Bakker74111d32011-01-15 16:57:55 +0000914 /*
915 * Extension ::= SEQUENCE {
916 * extnID OBJECT IDENTIFIER,
917 * critical BOOLEAN DEFAULT FALSE,
918 * extnValue OCTET STRING }
919 */
920 x509_buf extn_oid = {0, 0, NULL};
921 int is_critical = 0; /* DEFAULT FALSE */
922
Paul Bakker5121ce52009-01-03 21:22:43 +0000923 if( ( ret = asn1_get_tag( p, end, &len,
924 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000925 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000927 end_ext_data = *p + len;
928
Paul Bakker74111d32011-01-15 16:57:55 +0000929 /* Get extension ID */
930 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Paul Bakker74111d32011-01-15 16:57:55 +0000932 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000933 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
Paul Bakker74111d32011-01-15 16:57:55 +0000935 extn_oid.p = *p;
936 *p += extn_oid.len;
937
938 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000939 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000940 POLARSSL_ERR_ASN1_OUT_OF_DATA );
941
942 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000943 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000944 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000945 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Paul Bakker74111d32011-01-15 16:57:55 +0000947 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000948 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000950 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000952 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000953
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000954 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000955 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000956 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957
Paul Bakker74111d32011-01-15 16:57:55 +0000958 /*
959 * Detect supported extensions
960 */
961 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
962 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000963 {
Paul Bakker74111d32011-01-15 16:57:55 +0000964 /* Parse basic constraints */
965 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000966 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000967 return ( ret );
968 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000969 }
Paul Bakker74111d32011-01-15 16:57:55 +0000970 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
971 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
972 {
973 /* Parse netscape certificate type */
974 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
975 &crt->ns_cert_type ) ) != 0 )
976 return ( ret );
977 crt->ext_types |= EXT_NS_CERT_TYPE;
978 }
979 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
980 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
981 {
982 /* Parse key usage */
983 if( ( ret = x509_get_key_usage( p, end_ext_octet,
984 &crt->key_usage ) ) != 0 )
985 return ( ret );
986 crt->ext_types |= EXT_KEY_USAGE;
987 }
988 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
989 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
990 {
991 /* Parse extended key usage */
992 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
993 &crt->ext_key_usage ) ) != 0 )
994 return ( ret );
995 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
996 }
Paul Bakkera8cd2392012-02-11 16:09:32 +0000997 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
998 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
999 {
1000 /* Parse extended key usage */
1001 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1002 &crt->subject_alt_names ) ) != 0 )
1003 return ( ret );
1004 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1005 }
Paul Bakker74111d32011-01-15 16:57:55 +00001006 else
1007 {
1008 /* No parser found, skip extension */
1009 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001010
Paul Bakker5c721f92011-07-27 16:51:09 +00001011#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001012 if( is_critical )
1013 {
1014 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001015 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001016 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1017 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001018#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001019 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 }
1021
1022 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001023 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001024 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Paul Bakker5121ce52009-01-03 21:22:43 +00001026 return( 0 );
1027}
1028
1029/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001030 * X.509 CRL Entries
1031 */
1032static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001033 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001034 x509_crl_entry *entry )
1035{
Paul Bakker23986e52011-04-24 08:57:21 +00001036 int ret;
1037 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001038 x509_crl_entry *cur_entry = entry;
1039
1040 if( *p == end )
1041 return( 0 );
1042
Paul Bakker9be19372009-07-27 20:21:53 +00001043 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001044 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1045 {
1046 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1047 return( 0 );
1048
1049 return( ret );
1050 }
1051
Paul Bakker9be19372009-07-27 20:21:53 +00001052 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001053
1054 while( *p < end )
1055 {
Paul Bakker23986e52011-04-24 08:57:21 +00001056 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001057 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001058
1059 if( ( ret = asn1_get_tag( p, end, &len2,
1060 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1061 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001062 return( ret );
1063 }
1064
Paul Bakker9be19372009-07-27 20:21:53 +00001065 cur_entry->raw.tag = **p;
1066 cur_entry->raw.p = *p;
1067 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001068 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001069
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001070 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001071 return( ret );
1072
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001073 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001074 return( ret );
1075
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001076 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001077 return( ret );
1078
Paul Bakker74111d32011-01-15 16:57:55 +00001079 if ( *p < end )
1080 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001081 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001082
1083 if( cur_entry->next == NULL )
1084 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1085
Paul Bakkerd98030e2009-05-02 15:13:40 +00001086 cur_entry = cur_entry->next;
1087 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1088 }
1089 }
1090
1091 return( 0 );
1092}
1093
Paul Bakker27d66162010-03-17 06:56:01 +00001094static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1095{
1096 if( sig_oid->len == 9 &&
1097 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1098 {
1099 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1100 {
1101 *sig_alg = sig_oid->p[8];
1102 return( 0 );
1103 }
1104
1105 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1106 {
1107 *sig_alg = sig_oid->p[8];
1108 return( 0 );
1109 }
1110
1111 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1112 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001113 if( sig_oid->len == 5 &&
1114 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1115 {
1116 *sig_alg = SIG_RSA_SHA1;
1117 return( 0 );
1118 }
Paul Bakker27d66162010-03-17 06:56:01 +00001119
1120 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1121}
1122
Paul Bakkerd98030e2009-05-02 15:13:40 +00001123/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001124 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001125 */
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001126int x509parse_crt_der( x509_cert *crt, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001127{
Paul Bakker23986e52011-04-24 08:57:21 +00001128 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001129 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001130 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001131
Paul Bakker320a4b52009-03-28 18:52:39 +00001132 /*
1133 * Check for valid input
1134 */
1135 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001136 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001137
Paul Bakker96743fc2011-02-12 14:30:57 +00001138 p = (unsigned char *) malloc( len = buflen );
1139
1140 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001141 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001142
1143 memcpy( p, buf, buflen );
1144
1145 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001146
1147 crt->raw.p = p;
1148 crt->raw.len = len;
1149 end = p + len;
1150
1151 /*
1152 * Certificate ::= SEQUENCE {
1153 * tbsCertificate TBSCertificate,
1154 * signatureAlgorithm AlgorithmIdentifier,
1155 * signatureValue BIT STRING }
1156 */
1157 if( ( ret = asn1_get_tag( &p, end, &len,
1158 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1159 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001160 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001161 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001162 }
1163
Paul Bakkerb00ca422012-09-25 12:10:00 +00001164 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001165 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001166 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001167 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001168 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001169 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001170 crt_end = p + len;
1171
Paul Bakker5121ce52009-01-03 21:22:43 +00001172 /*
1173 * TBSCertificate ::= SEQUENCE {
1174 */
1175 crt->tbs.p = p;
1176
1177 if( ( ret = asn1_get_tag( &p, end, &len,
1178 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1179 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001180 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001181 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001182 }
1183
1184 end = p + len;
1185 crt->tbs.len = end - crt->tbs.p;
1186
1187 /*
1188 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1189 *
1190 * CertificateSerialNumber ::= INTEGER
1191 *
1192 * signature AlgorithmIdentifier
1193 */
1194 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1195 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1196 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1197 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001198 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001199 return( ret );
1200 }
1201
1202 crt->version++;
1203
1204 if( crt->version > 3 )
1205 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001206 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001207 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001208 }
1209
Paul Bakker27d66162010-03-17 06:56:01 +00001210 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001212 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001213 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001214 }
1215
1216 /*
1217 * issuer Name
1218 */
1219 crt->issuer_raw.p = p;
1220
1221 if( ( ret = asn1_get_tag( &p, end, &len,
1222 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1223 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001224 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001225 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001226 }
1227
1228 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1229 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001230 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001231 return( ret );
1232 }
1233
1234 crt->issuer_raw.len = p - crt->issuer_raw.p;
1235
1236 /*
1237 * Validity ::= SEQUENCE {
1238 * notBefore Time,
1239 * notAfter Time }
1240 *
1241 */
1242 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1243 &crt->valid_to ) ) != 0 )
1244 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001245 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001246 return( ret );
1247 }
1248
1249 /*
1250 * subject Name
1251 */
1252 crt->subject_raw.p = p;
1253
1254 if( ( ret = asn1_get_tag( &p, end, &len,
1255 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1256 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001257 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001258 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 }
1260
Paul Bakkercefb3962012-06-27 11:51:09 +00001261 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001262 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001263 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001264 return( ret );
1265 }
1266
1267 crt->subject_raw.len = p - crt->subject_raw.p;
1268
1269 /*
1270 * SubjectPublicKeyInfo ::= SEQUENCE
1271 * algorithm AlgorithmIdentifier,
1272 * subjectPublicKey BIT STRING }
1273 */
1274 if( ( ret = asn1_get_tag( &p, end, &len,
1275 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1276 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001277 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001278 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001279 }
1280
1281 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1282 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1283 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001284 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001285 return( ret );
1286 }
1287
1288 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1289 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001290 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001291 return( ret );
1292 }
1293
1294 crt->rsa.len = mpi_size( &crt->rsa.N );
1295
1296 /*
1297 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1298 * -- If present, version shall be v2 or v3
1299 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1300 * -- If present, version shall be v2 or v3
1301 * extensions [3] EXPLICIT Extensions OPTIONAL
1302 * -- If present, version shall be v3
1303 */
1304 if( crt->version == 2 || crt->version == 3 )
1305 {
1306 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1307 if( ret != 0 )
1308 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001309 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001310 return( ret );
1311 }
1312 }
1313
1314 if( crt->version == 2 || crt->version == 3 )
1315 {
1316 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1317 if( ret != 0 )
1318 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001319 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001320 return( ret );
1321 }
1322 }
1323
1324 if( crt->version == 3 )
1325 {
Paul Bakker74111d32011-01-15 16:57:55 +00001326 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001327 if( ret != 0 )
1328 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001329 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 return( ret );
1331 }
1332 }
1333
1334 if( p != end )
1335 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001336 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001337 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001338 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001339 }
1340
Paul Bakkerb00ca422012-09-25 12:10:00 +00001341 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001342
1343 /*
1344 * signatureAlgorithm AlgorithmIdentifier,
1345 * signatureValue BIT STRING
1346 */
1347 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1348 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001349 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 return( ret );
1351 }
1352
Paul Bakker535e97d2012-08-23 10:49:55 +00001353 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1354 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001355 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001356 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001357 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001358 }
1359
1360 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1361 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001362 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001363 return( ret );
1364 }
1365
1366 if( p != end )
1367 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001368 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001369 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001370 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001371 }
1372
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001373 return( 0 );
1374}
1375
1376/*
1377 * Parse one or more PEM certificates from a buffer and add them to the chained list
1378 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001379int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001380{
Paul Bakker69e095c2011-12-10 21:55:01 +00001381 int ret, success = 0, first_error = 0, total_failed = 0;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001382 x509_cert *crt, *prev = NULL;
1383 int buf_format = X509_FORMAT_DER;
1384
1385 crt = chain;
1386
1387 /*
1388 * Check for valid input
1389 */
1390 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001391 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001392
1393 while( crt->version != 0 && crt->next != NULL )
1394 {
1395 prev = crt;
1396 crt = crt->next;
1397 }
1398
1399 /*
1400 * Add new certificate on the end of the chain if needed.
1401 */
1402 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001403 {
1404 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1405
Paul Bakker7d06ad22009-05-02 15:53:56 +00001406 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001407 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001408
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001409 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001410 crt = crt->next;
1411 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001412 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001413
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001414 /*
1415 * Determine buffer content. Buffer contains either one DER certificate or
1416 * one or more PEM certificates.
1417 */
1418#if defined(POLARSSL_PEM_C)
Paul Bakkereae09db2013-06-06 12:35:54 +02001419 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001420 buf_format = X509_FORMAT_PEM;
1421#endif
1422
1423 if( buf_format == X509_FORMAT_DER )
1424 return x509parse_crt_der( crt, buf, buflen );
1425
1426#if defined(POLARSSL_PEM_C)
1427 if( buf_format == X509_FORMAT_PEM )
1428 {
1429 pem_context pem;
1430
1431 while( buflen > 0 )
1432 {
1433 size_t use_len;
1434 pem_init( &pem );
1435
1436 ret = pem_read_buffer( &pem,
1437 "-----BEGIN CERTIFICATE-----",
1438 "-----END CERTIFICATE-----",
1439 buf, NULL, 0, &use_len );
1440
1441 if( ret == 0 )
1442 {
1443 /*
1444 * Was PEM encoded
1445 */
1446 buflen -= use_len;
1447 buf += use_len;
1448 }
Paul Bakker64171862013-06-06 15:01:18 +02001449 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1450 {
1451 return( ret );
1452 }
Paul Bakker9255e832013-06-06 14:58:28 +02001453 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001454 {
1455 pem_free( &pem );
1456
Paul Bakker64171862013-06-06 15:01:18 +02001457 /*
1458 * PEM header and footer were found
1459 */
1460 buflen -= use_len;
1461 buf += use_len;
1462
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001463 if( first_error == 0 )
1464 first_error = ret;
1465
1466 continue;
1467 }
1468 else
1469 break;
1470
1471 ret = x509parse_crt_der( crt, pem.buf, pem.buflen );
1472
1473 pem_free( &pem );
1474
1475 if( ret != 0 )
1476 {
1477 /*
Paul Bakker69e095c2011-12-10 21:55:01 +00001478 * quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001479 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001480 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001481 {
1482 if( prev )
1483 prev->next = NULL;
1484
1485 if( crt != chain )
1486 free( crt );
1487
1488 return( ret );
1489 }
1490
1491 if( first_error == 0 )
1492 first_error = ret;
Paul Bakker69e095c2011-12-10 21:55:01 +00001493
1494 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001495
1496 memset( crt, 0, sizeof( x509_cert ) );
1497 continue;
1498 }
1499
1500 success = 1;
1501
1502 /*
1503 * Add new certificate to the list
1504 */
1505 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1506
1507 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001508 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001509
1510 prev = crt;
1511 crt = crt->next;
1512 memset( crt, 0, sizeof( x509_cert ) );
1513 }
1514 }
1515#endif
1516
1517 if( crt->version == 0 )
1518 {
1519 if( prev )
1520 prev->next = NULL;
1521
1522 if( crt != chain )
1523 free( crt );
1524 }
1525
1526 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001527 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001528 else if( first_error )
1529 return( first_error );
1530 else
1531 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001532}
1533
1534/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001535 * Parse one or more CRLs and add them to the chained list
1536 */
Paul Bakker23986e52011-04-24 08:57:21 +00001537int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001538{
Paul Bakker23986e52011-04-24 08:57:21 +00001539 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001540 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001541 unsigned char *p, *end;
1542 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001543#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001544 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001545 pem_context pem;
1546#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547
1548 crl = chain;
1549
1550 /*
1551 * Check for valid input
1552 */
1553 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001554 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001555
1556 while( crl->version != 0 && crl->next != NULL )
1557 crl = crl->next;
1558
1559 /*
1560 * Add new CRL on the end of the chain if needed.
1561 */
1562 if ( crl->version != 0 && crl->next == NULL)
1563 {
1564 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1565
Paul Bakker7d06ad22009-05-02 15:53:56 +00001566 if( crl->next == NULL )
1567 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001568 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001569 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001570 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001571
Paul Bakker7d06ad22009-05-02 15:53:56 +00001572 crl = crl->next;
1573 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001574 }
1575
Paul Bakker96743fc2011-02-12 14:30:57 +00001576#if defined(POLARSSL_PEM_C)
1577 pem_init( &pem );
1578 ret = pem_read_buffer( &pem,
1579 "-----BEGIN X509 CRL-----",
1580 "-----END X509 CRL-----",
1581 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001582
Paul Bakker96743fc2011-02-12 14:30:57 +00001583 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001584 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001585 /*
1586 * Was PEM encoded
1587 */
1588 buflen -= use_len;
1589 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001590
1591 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001592 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001593 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001594 p = pem.buf;
1595 pem.buf = NULL;
1596 len = pem.buflen;
1597 pem_free( &pem );
1598 }
Paul Bakker9255e832013-06-06 14:58:28 +02001599 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001600 {
1601 pem_free( &pem );
1602 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001603 }
1604 else
1605 {
1606 /*
1607 * nope, copy the raw DER data
1608 */
1609 p = (unsigned char *) malloc( len = buflen );
1610
1611 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001612 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001613
1614 memcpy( p, buf, buflen );
1615
1616 buflen = 0;
1617 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001618#else
1619 p = (unsigned char *) malloc( len = buflen );
1620
1621 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001622 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001623
1624 memcpy( p, buf, buflen );
1625
1626 buflen = 0;
1627#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001628
1629 crl->raw.p = p;
1630 crl->raw.len = len;
1631 end = p + len;
1632
1633 /*
1634 * CertificateList ::= SEQUENCE {
1635 * tbsCertList TBSCertList,
1636 * signatureAlgorithm AlgorithmIdentifier,
1637 * signatureValue BIT STRING }
1638 */
1639 if( ( ret = asn1_get_tag( &p, end, &len,
1640 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1641 {
1642 x509_crl_free( crl );
1643 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1644 }
1645
Paul Bakker23986e52011-04-24 08:57:21 +00001646 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001647 {
1648 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001649 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001650 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1651 }
1652
1653 /*
1654 * TBSCertList ::= SEQUENCE {
1655 */
1656 crl->tbs.p = p;
1657
1658 if( ( ret = asn1_get_tag( &p, end, &len,
1659 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1660 {
1661 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001662 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001663 }
1664
1665 end = p + len;
1666 crl->tbs.len = end - crl->tbs.p;
1667
1668 /*
1669 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1670 * -- if present, MUST be v2
1671 *
1672 * signature AlgorithmIdentifier
1673 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001674 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001675 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1676 {
1677 x509_crl_free( crl );
1678 return( ret );
1679 }
1680
1681 crl->version++;
1682
1683 if( crl->version > 2 )
1684 {
1685 x509_crl_free( crl );
1686 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1687 }
1688
Paul Bakker27d66162010-03-17 06:56:01 +00001689 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001690 {
1691 x509_crl_free( crl );
1692 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1693 }
1694
1695 /*
1696 * issuer Name
1697 */
1698 crl->issuer_raw.p = p;
1699
1700 if( ( ret = asn1_get_tag( &p, end, &len,
1701 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1702 {
1703 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001704 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001705 }
1706
1707 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1708 {
1709 x509_crl_free( crl );
1710 return( ret );
1711 }
1712
1713 crl->issuer_raw.len = p - crl->issuer_raw.p;
1714
1715 /*
1716 * thisUpdate Time
1717 * nextUpdate Time OPTIONAL
1718 */
Paul Bakker91200182010-02-18 21:26:15 +00001719 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001720 {
1721 x509_crl_free( crl );
1722 return( ret );
1723 }
1724
Paul Bakker91200182010-02-18 21:26:15 +00001725 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001726 {
Paul Bakker9d781402011-05-09 16:17:09 +00001727 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001728 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001729 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001730 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001731 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001732 x509_crl_free( crl );
1733 return( ret );
1734 }
1735 }
1736
1737 /*
1738 * revokedCertificates SEQUENCE OF SEQUENCE {
1739 * userCertificate CertificateSerialNumber,
1740 * revocationDate Time,
1741 * crlEntryExtensions Extensions OPTIONAL
1742 * -- if present, MUST be v2
1743 * } OPTIONAL
1744 */
1745 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1746 {
1747 x509_crl_free( crl );
1748 return( ret );
1749 }
1750
1751 /*
1752 * crlExtensions EXPLICIT Extensions OPTIONAL
1753 * -- if present, MUST be v2
1754 */
1755 if( crl->version == 2 )
1756 {
1757 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1758
1759 if( ret != 0 )
1760 {
1761 x509_crl_free( crl );
1762 return( ret );
1763 }
1764 }
1765
1766 if( p != end )
1767 {
1768 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001769 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001770 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1771 }
1772
1773 end = crl->raw.p + crl->raw.len;
1774
1775 /*
1776 * signatureAlgorithm AlgorithmIdentifier,
1777 * signatureValue BIT STRING
1778 */
1779 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1780 {
1781 x509_crl_free( crl );
1782 return( ret );
1783 }
1784
Paul Bakker535e97d2012-08-23 10:49:55 +00001785 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1786 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001787 {
1788 x509_crl_free( crl );
1789 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1790 }
1791
1792 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1793 {
1794 x509_crl_free( crl );
1795 return( ret );
1796 }
1797
1798 if( p != end )
1799 {
1800 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001801 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001802 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1803 }
1804
1805 if( buflen > 0 )
1806 {
1807 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1808
Paul Bakker7d06ad22009-05-02 15:53:56 +00001809 if( crl->next == NULL )
1810 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001811 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001812 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001813 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001814
Paul Bakker7d06ad22009-05-02 15:53:56 +00001815 crl = crl->next;
1816 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817
1818 return( x509parse_crl( crl, buf, buflen ) );
1819 }
1820
1821 return( 0 );
1822}
1823
Paul Bakker335db3f2011-04-25 15:28:35 +00001824#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001825/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001826 * Load all data from a file into a given buffer.
1827 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001828int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001829{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001830 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001831
Paul Bakkerd98030e2009-05-02 15:13:40 +00001832 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001833 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001834
Paul Bakkerd98030e2009-05-02 15:13:40 +00001835 fseek( f, 0, SEEK_END );
1836 *n = (size_t) ftell( f );
1837 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001838
Paul Bakkerd98030e2009-05-02 15:13:40 +00001839 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001840 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001841
Paul Bakkerd98030e2009-05-02 15:13:40 +00001842 if( fread( *buf, 1, *n, f ) != *n )
1843 {
1844 fclose( f );
1845 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001846 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001847 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001848
Paul Bakkerd98030e2009-05-02 15:13:40 +00001849 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001850
Paul Bakkerd98030e2009-05-02 15:13:40 +00001851 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001852
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001854}
1855
1856/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001857 * Load one or more certificates and add them to the chained list
1858 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001859int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001860{
1861 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001862 size_t n;
1863 unsigned char *buf;
1864
Paul Bakker69e095c2011-12-10 21:55:01 +00001865 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1866 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001867
Paul Bakker69e095c2011-12-10 21:55:01 +00001868 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001869
1870 memset( buf, 0, n + 1 );
1871 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001872
1873 return( ret );
1874}
1875
Paul Bakker8d914582012-06-04 12:46:42 +00001876int x509parse_crtpath( x509_cert *chain, const char *path )
1877{
1878 int ret = 0;
1879#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001880 int w_ret;
1881 WCHAR szDir[MAX_PATH];
1882 char filename[MAX_PATH];
1883 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001884 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001885
Paul Bakker97872ac2012-11-02 12:53:26 +00001886 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001887 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001888
1889 if( len > MAX_PATH - 3 )
1890 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001891
Paul Bakker3338b792012-10-01 21:13:10 +00001892 memset( szDir, 0, sizeof(szDir) );
1893 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001894 memcpy( filename, path, len );
1895 filename[len++] = '\\';
1896 p = filename + len;
1897 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001898
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001899 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001900
Paul Bakker97872ac2012-11-02 12:53:26 +00001901 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001902 if (hFind == INVALID_HANDLE_VALUE)
1903 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1904
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001905 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001906 do
1907 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001908 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001909
Paul Bakkere4791f32012-06-04 21:29:15 +00001910 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001911 continue;
1912
Paul Bakker3338b792012-10-01 21:13:10 +00001913 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1914 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001915 p, len - 1,
1916 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001917
Paul Bakker3338b792012-10-01 21:13:10 +00001918 w_ret = x509parse_crtfile( chain, filename );
1919 if( w_ret < 0 )
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001920 {
1921 ret = w_ret;
1922 goto cleanup;
1923 }
Paul Bakker3338b792012-10-01 21:13:10 +00001924
1925 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001926 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001927 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001928
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001929 if (GetLastError() != ERROR_NO_MORE_FILES)
1930 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001931
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001932cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001933 FindClose( hFind );
1934#else
1935 int t_ret;
1936 struct dirent *entry;
1937 char entry_name[255];
1938 DIR *dir = opendir( path );
1939
1940 if( dir == NULL)
1941 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1942
1943 while( ( entry = readdir( dir ) ) != NULL )
1944 {
1945 if( entry->d_type != DT_REG )
1946 continue;
1947
1948 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry->d_name );
1949 t_ret = x509parse_crtfile( chain, entry_name );
1950 if( t_ret < 0 )
Paul Bakker97872ac2012-11-02 12:53:26 +00001951 {
1952 ret = t_ret;
1953 break;
1954 }
Paul Bakker8d914582012-06-04 12:46:42 +00001955
1956 ret += t_ret;
1957 }
1958 closedir( dir );
1959#endif
1960
1961 return( ret );
1962}
1963
Paul Bakkerd98030e2009-05-02 15:13:40 +00001964/*
1965 * Load one or more CRLs and add them to the chained list
1966 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001967int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001968{
1969 int ret;
1970 size_t n;
1971 unsigned char *buf;
1972
Paul Bakker69e095c2011-12-10 21:55:01 +00001973 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1974 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001975
Paul Bakker27fdf462011-06-09 13:55:13 +00001976 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001977
1978 memset( buf, 0, n + 1 );
1979 free( buf );
1980
1981 return( ret );
1982}
1983
Paul Bakker5121ce52009-01-03 21:22:43 +00001984/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001985 * Load and parse a private RSA key
1986 */
1987int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1988{
1989 int ret;
1990 size_t n;
1991 unsigned char *buf;
1992
Paul Bakker69e095c2011-12-10 21:55:01 +00001993 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1994 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001995
1996 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001997 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001998 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001999 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002000 (unsigned char *) pwd, strlen( pwd ) );
2001
2002 memset( buf, 0, n + 1 );
2003 free( buf );
2004
2005 return( ret );
2006}
2007
2008/*
2009 * Load and parse a public RSA key
2010 */
2011int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2012{
2013 int ret;
2014 size_t n;
2015 unsigned char *buf;
2016
Paul Bakker69e095c2011-12-10 21:55:01 +00002017 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2018 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002019
Paul Bakker27fdf462011-06-09 13:55:13 +00002020 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002021
2022 memset( buf, 0, n + 1 );
2023 free( buf );
2024
2025 return( ret );
2026}
2027#endif /* POLARSSL_FS_IO */
2028
2029/*
Paul Bakker65a19092013-06-06 21:14:58 +02002030 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002031 */
Paul Bakker65a19092013-06-06 21:14:58 +02002032static int x509parse_key_pkcs1_der( rsa_context *rsa,
2033 const unsigned char *key,
2034 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002035{
Paul Bakker23986e52011-04-24 08:57:21 +00002036 int ret;
2037 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002039
Paul Bakker96743fc2011-02-12 14:30:57 +00002040 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002041 end = p + keylen;
2042
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002044 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002045 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002046 * RSAPrivateKey ::= SEQUENCE {
2047 * version Version,
2048 * modulus INTEGER, -- n
2049 * publicExponent INTEGER, -- e
2050 * privateExponent INTEGER, -- d
2051 * prime1 INTEGER, -- p
2052 * prime2 INTEGER, -- q
2053 * exponent1 INTEGER, -- d mod (p-1)
2054 * exponent2 INTEGER, -- d mod (q-1)
2055 * coefficient INTEGER, -- (inverse of q) mod p
2056 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2057 * }
2058 */
2059 if( ( ret = asn1_get_tag( &p, end, &len,
2060 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2061 {
Paul Bakker9d781402011-05-09 16:17:09 +00002062 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002063 }
2064
2065 end = p + len;
2066
2067 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2068 {
Paul Bakker9d781402011-05-09 16:17:09 +00002069 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002070 }
2071
2072 if( rsa->ver != 0 )
2073 {
Paul Bakker9d781402011-05-09 16:17:09 +00002074 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 }
2076
2077 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2078 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2079 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2080 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2081 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2082 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2083 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2084 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2085 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002086 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002087 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002088 }
2089
2090 rsa->len = mpi_size( &rsa->N );
2091
2092 if( p != end )
2093 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002094 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002095 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002096 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002097 }
2098
2099 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2100 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002101 rsa_free( rsa );
2102 return( ret );
2103 }
2104
Paul Bakker65a19092013-06-06 21:14:58 +02002105 return( 0 );
2106}
2107
2108/*
2109 * Parse an unencrypted PKCS#8 encoded private RSA key
2110 */
2111static int x509parse_key_pkcs8_unencrypted_der(
2112 rsa_context *rsa,
2113 const unsigned char *key,
2114 size_t keylen )
2115{
2116 int ret;
2117 size_t len;
2118 unsigned char *p, *end;
2119 x509_buf pk_alg_oid;
2120
2121 p = (unsigned char *) key;
2122 end = p + keylen;
2123
2124 /*
2125 * This function parses the PrivatKeyInfo object (PKCS#8)
2126 *
2127 * PrivateKeyInfo ::= SEQUENCE {
2128 * version Version,
2129 * algorithm AlgorithmIdentifier,
2130 * PrivateKey BIT STRING
2131 * }
2132 *
2133 * AlgorithmIdentifier ::= SEQUENCE {
2134 * algorithm OBJECT IDENTIFIER,
2135 * parameters ANY DEFINED BY algorithm OPTIONAL
2136 * }
2137 *
2138 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2139 */
2140 if( ( ret = asn1_get_tag( &p, end, &len,
2141 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2142 {
2143 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2144 }
2145
2146 end = p + len;
2147
2148 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2149 {
2150 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2151 }
2152
2153 if( rsa->ver != 0 )
2154 {
2155 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2156 }
2157
2158 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2159 {
2160 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2161 }
2162
2163 /*
2164 * only RSA keys handled at this time
2165 */
2166 if( pk_alg_oid.len != 9 ||
2167 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2168 {
2169 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2170 }
2171
2172 /*
2173 * Get the OCTET STRING and parse the PKCS#1 format inside
2174 */
2175 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2176 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2177
2178 if( ( end - p ) < 1 )
2179 {
2180 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2181 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2182 }
2183
2184 end = p + len;
2185
2186 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2187 return( ret );
2188
2189 return( 0 );
2190}
2191
2192/*
2193 * Parse a private RSA key
2194 */
2195int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2196 const unsigned char *pwd, size_t pwdlen )
2197{
2198 int ret;
2199
Paul Bakker96743fc2011-02-12 14:30:57 +00002200#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002201 size_t len;
2202 pem_context pem;
2203
2204 pem_init( &pem );
2205 ret = pem_read_buffer( &pem,
2206 "-----BEGIN RSA PRIVATE KEY-----",
2207 "-----END RSA PRIVATE KEY-----",
2208 key, pwd, pwdlen, &len );
2209 if( ret == 0 )
2210 {
2211 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2212 {
2213 rsa_free( rsa );
2214 }
2215
2216 pem_free( &pem );
2217 return( ret );
2218 }
2219 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2220 {
2221 pem_free( &pem );
2222 return( ret );
2223 }
2224
2225 ret = pem_read_buffer( &pem,
2226 "-----BEGIN PRIVATE KEY-----",
2227 "-----END PRIVATE KEY-----",
2228 key, NULL, 0, &len );
2229 if( ret == 0 )
2230 {
2231 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2232 pem.buf, pem.buflen ) ) != 0 )
2233 {
2234 rsa_free( rsa );
2235 }
2236
2237 pem_free( &pem );
2238 return( ret );
2239 }
2240 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2241 {
2242 pem_free( &pem );
2243 return( ret );
2244 }
2245
Paul Bakker96743fc2011-02-12 14:30:57 +00002246 pem_free( &pem );
Paul Bakker65a19092013-06-06 21:14:58 +02002247#else
2248 ((void) pwd);
2249 ((void) pwdlen);
2250#endif /* POLARSSL_PEM_C */
2251
2252 // At this point we only know it's not a PEM formatted key. Could be any
2253 // of the known DER encoded private key formats
2254 //
2255 // We try the different DER format parsers to see if one passes without
2256 // error
2257 //
2258 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) != 0 )
2259 {
2260 rsa_free( rsa );
2261
2262 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) != 0 )
2263 {
2264 rsa_free( rsa );
2265 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2266 }
2267 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002268
2269 return( 0 );
2270}
2271
2272/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002273 * Parse a public RSA key
2274 */
Paul Bakker23986e52011-04-24 08:57:21 +00002275int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002276{
Paul Bakker23986e52011-04-24 08:57:21 +00002277 int ret;
2278 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002279 unsigned char *p, *end;
2280 x509_buf alg_oid;
2281#if defined(POLARSSL_PEM_C)
2282 pem_context pem;
2283
2284 pem_init( &pem );
2285 ret = pem_read_buffer( &pem,
2286 "-----BEGIN PUBLIC KEY-----",
2287 "-----END PUBLIC KEY-----",
2288 key, NULL, 0, &len );
2289
2290 if( ret == 0 )
2291 {
2292 /*
2293 * Was PEM encoded
2294 */
2295 keylen = pem.buflen;
2296 }
Paul Bakker9255e832013-06-06 14:58:28 +02002297 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002298 {
2299 pem_free( &pem );
2300 return( ret );
2301 }
2302
2303 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2304#else
2305 p = (unsigned char *) key;
2306#endif
2307 end = p + keylen;
2308
2309 /*
2310 * PublicKeyInfo ::= SEQUENCE {
2311 * algorithm AlgorithmIdentifier,
2312 * PublicKey BIT STRING
2313 * }
2314 *
2315 * AlgorithmIdentifier ::= SEQUENCE {
2316 * algorithm OBJECT IDENTIFIER,
2317 * parameters ANY DEFINED BY algorithm OPTIONAL
2318 * }
2319 *
2320 * RSAPublicKey ::= SEQUENCE {
2321 * modulus INTEGER, -- n
2322 * publicExponent INTEGER -- e
2323 * }
2324 */
2325
2326 if( ( ret = asn1_get_tag( &p, end, &len,
2327 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2328 {
2329#if defined(POLARSSL_PEM_C)
2330 pem_free( &pem );
2331#endif
2332 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002333 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002334 }
2335
2336 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2337 {
2338#if defined(POLARSSL_PEM_C)
2339 pem_free( &pem );
2340#endif
2341 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002342 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002343 }
2344
2345 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2346 {
2347#if defined(POLARSSL_PEM_C)
2348 pem_free( &pem );
2349#endif
2350 rsa_free( rsa );
2351 return( ret );
2352 }
2353
2354 rsa->len = mpi_size( &rsa->N );
2355
2356#if defined(POLARSSL_PEM_C)
2357 pem_free( &pem );
2358#endif
2359
2360 return( 0 );
2361}
2362
Paul Bakkereaa89f82011-04-04 21:36:15 +00002363#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002364/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002365 * Parse DHM parameters
2366 */
Paul Bakker23986e52011-04-24 08:57:21 +00002367int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002368{
Paul Bakker23986e52011-04-24 08:57:21 +00002369 int ret;
2370 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002371 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002372#if defined(POLARSSL_PEM_C)
2373 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002374
Paul Bakker96743fc2011-02-12 14:30:57 +00002375 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002376
Paul Bakker96743fc2011-02-12 14:30:57 +00002377 ret = pem_read_buffer( &pem,
2378 "-----BEGIN DH PARAMETERS-----",
2379 "-----END DH PARAMETERS-----",
2380 dhmin, NULL, 0, &dhminlen );
2381
2382 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002383 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002384 /*
2385 * Was PEM encoded
2386 */
2387 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002388 }
Paul Bakker9255e832013-06-06 14:58:28 +02002389 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002390 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002391 pem_free( &pem );
2392 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002393 }
2394
Paul Bakker96743fc2011-02-12 14:30:57 +00002395 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2396#else
2397 p = (unsigned char *) dhmin;
2398#endif
2399 end = p + dhminlen;
2400
Paul Bakker1b57b062011-01-06 15:48:19 +00002401 memset( dhm, 0, sizeof( dhm_context ) );
2402
Paul Bakker1b57b062011-01-06 15:48:19 +00002403 /*
2404 * DHParams ::= SEQUENCE {
2405 * prime INTEGER, -- P
2406 * generator INTEGER, -- g
2407 * }
2408 */
2409 if( ( ret = asn1_get_tag( &p, end, &len,
2410 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2411 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002412#if defined(POLARSSL_PEM_C)
2413 pem_free( &pem );
2414#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002415 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002416 }
2417
2418 end = p + len;
2419
2420 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2421 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2422 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002423#if defined(POLARSSL_PEM_C)
2424 pem_free( &pem );
2425#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002426 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002427 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002428 }
2429
2430 if( p != end )
2431 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002432#if defined(POLARSSL_PEM_C)
2433 pem_free( &pem );
2434#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002435 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002436 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002437 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2438 }
2439
Paul Bakker96743fc2011-02-12 14:30:57 +00002440#if defined(POLARSSL_PEM_C)
2441 pem_free( &pem );
2442#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002443
2444 return( 0 );
2445}
2446
Paul Bakker335db3f2011-04-25 15:28:35 +00002447#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002448/*
2449 * Load and parse a private RSA key
2450 */
2451int x509parse_dhmfile( dhm_context *dhm, const char *path )
2452{
2453 int ret;
2454 size_t n;
2455 unsigned char *buf;
2456
Paul Bakker69e095c2011-12-10 21:55:01 +00002457 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2458 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002459
Paul Bakker27fdf462011-06-09 13:55:13 +00002460 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002461
2462 memset( buf, 0, n + 1 );
2463 free( buf );
2464
2465 return( ret );
2466}
Paul Bakker335db3f2011-04-25 15:28:35 +00002467#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002468#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002469
Paul Bakker5121ce52009-01-03 21:22:43 +00002470#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002471#include <stdarg.h>
2472
2473#if !defined vsnprintf
2474#define vsnprintf _vsnprintf
2475#endif // vsnprintf
2476
2477/*
2478 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2479 * Result value is not size of buffer needed, but -1 if no fit is possible.
2480 *
2481 * This fuction tries to 'fix' this by at least suggesting enlarging the
2482 * size by 20.
2483 */
2484int compat_snprintf(char *str, size_t size, const char *format, ...)
2485{
2486 va_list ap;
2487 int res = -1;
2488
2489 va_start( ap, format );
2490
2491 res = vsnprintf( str, size, format, ap );
2492
2493 va_end( ap );
2494
2495 // No quick fix possible
2496 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002497 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002498
2499 return res;
2500}
2501
2502#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002503#endif
2504
Paul Bakkerd98030e2009-05-02 15:13:40 +00002505#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2506
2507#define SAFE_SNPRINTF() \
2508{ \
2509 if( ret == -1 ) \
2510 return( -1 ); \
2511 \
Paul Bakker23986e52011-04-24 08:57:21 +00002512 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002513 p[n - 1] = '\0'; \
2514 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2515 } \
2516 \
Paul Bakker23986e52011-04-24 08:57:21 +00002517 n -= (unsigned int) ret; \
2518 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002519}
2520
Paul Bakker5121ce52009-01-03 21:22:43 +00002521/*
2522 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002523 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002524 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002525int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002526{
Paul Bakker23986e52011-04-24 08:57:21 +00002527 int ret;
2528 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002529 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002530 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002531 char s[128], *p;
2532
2533 memset( s, 0, sizeof( s ) );
2534
2535 name = dn;
2536 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002537 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002538
2539 while( name != NULL )
2540 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002541 if( !name->oid.p )
2542 {
2543 name = name->next;
2544 continue;
2545 }
2546
Paul Bakker74111d32011-01-15 16:57:55 +00002547 if( name != dn )
2548 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002549 ret = snprintf( p, n, ", " );
2550 SAFE_SNPRINTF();
2551 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002552
Paul Bakker535e97d2012-08-23 10:49:55 +00002553 if( name->oid.len == 3 &&
2554 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002555 {
2556 switch( name->oid.p[2] )
2557 {
2558 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002559 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002560
2561 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002562 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002563
2564 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002565 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002566
2567 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002568 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002569
2570 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002571 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002572
2573 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002574 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002575
2576 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002577 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002578 name->oid.p[2] );
2579 break;
2580 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002581 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002582 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002583 else if( name->oid.len == 9 &&
2584 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002585 {
2586 switch( name->oid.p[8] )
2587 {
2588 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002589 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002590
2591 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002592 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002593 name->oid.p[8] );
2594 break;
2595 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002596 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002597 }
2598 else
Paul Bakker74111d32011-01-15 16:57:55 +00002599 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002600 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002601 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002602 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002603
2604 for( i = 0; i < name->val.len; i++ )
2605 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002606 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002607 break;
2608
2609 c = name->val.p[i];
2610 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2611 s[i] = '?';
2612 else s[i] = c;
2613 }
2614 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002615 ret = snprintf( p, n, "%s", s );
2616 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002617 name = name->next;
2618 }
2619
Paul Bakker23986e52011-04-24 08:57:21 +00002620 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002621}
2622
2623/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002624 * Store the serial in printable form into buf; no more
2625 * than size characters will be written
2626 */
2627int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2628{
Paul Bakker23986e52011-04-24 08:57:21 +00002629 int ret;
2630 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002631 char *p;
2632
2633 p = buf;
2634 n = size;
2635
2636 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002637 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002638
2639 for( i = 0; i < nr; i++ )
2640 {
Paul Bakker93048802011-12-05 14:38:06 +00002641 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002642 continue;
2643
Paul Bakkerdd476992011-01-16 21:34:59 +00002644 ret = snprintf( p, n, "%02X%s",
2645 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2646 SAFE_SNPRINTF();
2647 }
2648
Paul Bakker03c7c252011-11-25 12:37:37 +00002649 if( nr != serial->len )
2650 {
2651 ret = snprintf( p, n, "...." );
2652 SAFE_SNPRINTF();
2653 }
2654
Paul Bakker23986e52011-04-24 08:57:21 +00002655 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002656}
2657
2658/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002659 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002660 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002661int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2662 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002663{
Paul Bakker23986e52011-04-24 08:57:21 +00002664 int ret;
2665 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002666 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002667
2668 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002669 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002670
Paul Bakkerd98030e2009-05-02 15:13:40 +00002671 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002672 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002673 SAFE_SNPRINTF();
2674 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002675 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002676 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002677
Paul Bakkerdd476992011-01-16 21:34:59 +00002678 ret = x509parse_serial_gets( p, n, &crt->serial);
2679 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002680
Paul Bakkerd98030e2009-05-02 15:13:40 +00002681 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2682 SAFE_SNPRINTF();
2683 ret = x509parse_dn_gets( p, n, &crt->issuer );
2684 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002685
Paul Bakkerd98030e2009-05-02 15:13:40 +00002686 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2687 SAFE_SNPRINTF();
2688 ret = x509parse_dn_gets( p, n, &crt->subject );
2689 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002690
Paul Bakkerd98030e2009-05-02 15:13:40 +00002691 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002692 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2693 crt->valid_from.year, crt->valid_from.mon,
2694 crt->valid_from.day, crt->valid_from.hour,
2695 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002696 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002697
Paul Bakkerd98030e2009-05-02 15:13:40 +00002698 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002699 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2700 crt->valid_to.year, crt->valid_to.mon,
2701 crt->valid_to.day, crt->valid_to.hour,
2702 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002703 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002704
Paul Bakkerd98030e2009-05-02 15:13:40 +00002705 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2706 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002707
Paul Bakker27d66162010-03-17 06:56:01 +00002708 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002709 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002710 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2711 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2712 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2713 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2714 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2715 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2716 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2717 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2718 default: ret = snprintf( p, n, "???" ); break;
2719 }
2720 SAFE_SNPRINTF();
2721
2722 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002723 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002724 SAFE_SNPRINTF();
2725
Paul Bakker23986e52011-04-24 08:57:21 +00002726 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002727}
2728
Paul Bakker74111d32011-01-15 16:57:55 +00002729/* Compare a given OID string with an OID x509_buf * */
2730#define OID_CMP(oid_str, oid_buf) \
2731 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2732 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2733
2734/*
2735 * Return an informational string describing the given OID
2736 */
2737const char *x509_oid_get_description( x509_buf *oid )
2738{
2739 if ( oid == NULL )
2740 return ( NULL );
2741
2742 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2743 return( STRING_SERVER_AUTH );
2744
2745 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2746 return( STRING_CLIENT_AUTH );
2747
2748 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2749 return( STRING_CODE_SIGNING );
2750
2751 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2752 return( STRING_EMAIL_PROTECTION );
2753
2754 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2755 return( STRING_TIME_STAMPING );
2756
2757 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2758 return( STRING_OCSP_SIGNING );
2759
2760 return( NULL );
2761}
2762
2763/* Return the x.y.z.... style numeric string for the given OID */
2764int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2765{
Paul Bakker23986e52011-04-24 08:57:21 +00002766 int ret;
2767 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002768 unsigned int value;
2769 char *p;
2770
2771 p = buf;
2772 n = size;
2773
2774 /* First byte contains first two dots */
2775 if( oid->len > 0 )
2776 {
2777 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2778 SAFE_SNPRINTF();
2779 }
2780
2781 /* TODO: value can overflow in value. */
2782 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002783 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002784 {
2785 value <<= 7;
2786 value += oid->p[i] & 0x7F;
2787
2788 if( !( oid->p[i] & 0x80 ) )
2789 {
2790 /* Last byte */
2791 ret = snprintf( p, n, ".%d", value );
2792 SAFE_SNPRINTF();
2793 value = 0;
2794 }
2795 }
2796
Paul Bakker23986e52011-04-24 08:57:21 +00002797 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002798}
2799
Paul Bakkerd98030e2009-05-02 15:13:40 +00002800/*
2801 * Return an informational string about the CRL.
2802 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002803int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2804 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002805{
Paul Bakker23986e52011-04-24 08:57:21 +00002806 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002807 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002808 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002809 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002810
2811 p = buf;
2812 n = size;
2813
2814 ret = snprintf( p, n, "%sCRL version : %d",
2815 prefix, crl->version );
2816 SAFE_SNPRINTF();
2817
2818 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2819 SAFE_SNPRINTF();
2820 ret = x509parse_dn_gets( p, n, &crl->issuer );
2821 SAFE_SNPRINTF();
2822
2823 ret = snprintf( p, n, "\n%sthis update : " \
2824 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2825 crl->this_update.year, crl->this_update.mon,
2826 crl->this_update.day, crl->this_update.hour,
2827 crl->this_update.min, crl->this_update.sec );
2828 SAFE_SNPRINTF();
2829
2830 ret = snprintf( p, n, "\n%snext update : " \
2831 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2832 crl->next_update.year, crl->next_update.mon,
2833 crl->next_update.day, crl->next_update.hour,
2834 crl->next_update.min, crl->next_update.sec );
2835 SAFE_SNPRINTF();
2836
2837 entry = &crl->entry;
2838
2839 ret = snprintf( p, n, "\n%sRevoked certificates:",
2840 prefix );
2841 SAFE_SNPRINTF();
2842
Paul Bakker9be19372009-07-27 20:21:53 +00002843 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002844 {
2845 ret = snprintf( p, n, "\n%sserial number: ",
2846 prefix );
2847 SAFE_SNPRINTF();
2848
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002849 ret = x509parse_serial_gets( p, n, &entry->serial);
2850 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002851
Paul Bakkerd98030e2009-05-02 15:13:40 +00002852 ret = snprintf( p, n, " revocation date: " \
2853 "%04d-%02d-%02d %02d:%02d:%02d",
2854 entry->revocation_date.year, entry->revocation_date.mon,
2855 entry->revocation_date.day, entry->revocation_date.hour,
2856 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002857 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002858
2859 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002860 }
2861
Paul Bakkerd98030e2009-05-02 15:13:40 +00002862 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2863 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002864
Paul Bakker27d66162010-03-17 06:56:01 +00002865 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002866 {
2867 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2868 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2869 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2870 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2871 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2872 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2873 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2874 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2875 default: ret = snprintf( p, n, "???" ); break;
2876 }
2877 SAFE_SNPRINTF();
2878
Paul Bakker1e27bb22009-07-19 20:25:25 +00002879 ret = snprintf( p, n, "\n" );
2880 SAFE_SNPRINTF();
2881
Paul Bakker23986e52011-04-24 08:57:21 +00002882 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002883}
2884
2885/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002886 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002887 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002888int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002889{
Paul Bakkercce9d772011-11-18 14:26:47 +00002890 int year, mon, day;
2891 int hour, min, sec;
2892
2893#if defined(_WIN32)
2894 SYSTEMTIME st;
2895
2896 GetLocalTime(&st);
2897
2898 year = st.wYear;
2899 mon = st.wMonth;
2900 day = st.wDay;
2901 hour = st.wHour;
2902 min = st.wMinute;
2903 sec = st.wSecond;
2904#else
Paul Bakker5121ce52009-01-03 21:22:43 +00002905 struct tm *lt;
2906 time_t tt;
2907
2908 tt = time( NULL );
2909 lt = localtime( &tt );
2910
Paul Bakkercce9d772011-11-18 14:26:47 +00002911 year = lt->tm_year + 1900;
2912 mon = lt->tm_mon + 1;
2913 day = lt->tm_mday;
2914 hour = lt->tm_hour;
2915 min = lt->tm_min;
2916 sec = lt->tm_sec;
2917#endif
2918
2919 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002920 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002921
Paul Bakkercce9d772011-11-18 14:26:47 +00002922 if( year == to->year &&
2923 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002924 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002925
Paul Bakkercce9d772011-11-18 14:26:47 +00002926 if( year == to->year &&
2927 mon == to->mon &&
2928 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002929 return( 1 );
2930
Paul Bakkercce9d772011-11-18 14:26:47 +00002931 if( year == to->year &&
2932 mon == to->mon &&
2933 day == to->day &&
2934 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00002935 return( 1 );
2936
Paul Bakkercce9d772011-11-18 14:26:47 +00002937 if( year == to->year &&
2938 mon == to->mon &&
2939 day == to->day &&
2940 hour == to->hour &&
2941 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00002942 return( 1 );
2943
Paul Bakkercce9d772011-11-18 14:26:47 +00002944 if( year == to->year &&
2945 mon == to->mon &&
2946 day == to->day &&
2947 hour == to->hour &&
2948 min == to->min &&
2949 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00002950 return( 1 );
2951
Paul Bakker40ea7de2009-05-03 10:18:48 +00002952 return( 0 );
2953}
2954
2955/*
2956 * Return 1 if the certificate is revoked, or 0 otherwise.
2957 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002958int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002959{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002960 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002961
2962 while( cur != NULL && cur->serial.len != 0 )
2963 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002964 if( crt->serial.len == cur->serial.len &&
2965 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002966 {
2967 if( x509parse_time_expired( &cur->revocation_date ) )
2968 return( 1 );
2969 }
2970
2971 cur = cur->next;
2972 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002973
2974 return( 0 );
2975}
2976
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002977/*
2978 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002979 */
Paul Bakker23986e52011-04-24 08:57:21 +00002980static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002981 unsigned char *out )
2982{
2983 switch( alg )
2984 {
Paul Bakker40e46942009-01-03 21:51:57 +00002985#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002986 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002987#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002988#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002989 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002990#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002991#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002992 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002993#endif
2994#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002995 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002996#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002997#if defined(POLARSSL_SHA2_C)
2998 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2999 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3000#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003001#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003002 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3003 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3004#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003005 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003006 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003007 break;
3008 }
3009}
3010
3011/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003012 * Check that the given certificate is valid accoring to the CRL.
3013 */
3014static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3015 x509_crl *crl_list)
3016{
3017 int flags = 0;
3018 int hash_id;
3019 unsigned char hash[64];
3020
Paul Bakker915275b2012-09-28 07:10:55 +00003021 if( ca == NULL )
3022 return( flags );
3023
Paul Bakker76fd75a2011-01-16 21:12:10 +00003024 /*
3025 * TODO: What happens if no CRL is present?
3026 * Suggestion: Revocation state should be unknown if no CRL is present.
3027 * For backwards compatibility this is not yet implemented.
3028 */
3029
Paul Bakker915275b2012-09-28 07:10:55 +00003030 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003031 {
Paul Bakker915275b2012-09-28 07:10:55 +00003032 if( crl_list->version == 0 ||
3033 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003034 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3035 crl_list->issuer_raw.len ) != 0 )
3036 {
3037 crl_list = crl_list->next;
3038 continue;
3039 }
3040
3041 /*
3042 * Check if CRL is correctly signed by the trusted CA
3043 */
3044 hash_id = crl_list->sig_alg;
3045
3046 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3047
3048 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
3049 0, hash, crl_list->sig.p ) == 0 )
3050 {
3051 /*
3052 * CRL is not trusted
3053 */
3054 flags |= BADCRL_NOT_TRUSTED;
3055 break;
3056 }
3057
3058 /*
3059 * Check for validity of CRL (Do not drop out)
3060 */
3061 if( x509parse_time_expired( &crl_list->next_update ) )
3062 flags |= BADCRL_EXPIRED;
3063
3064 /*
3065 * Check if certificate is revoked
3066 */
3067 if( x509parse_revoked(crt, crl_list) )
3068 {
3069 flags |= BADCERT_REVOKED;
3070 break;
3071 }
3072
3073 crl_list = crl_list->next;
3074 }
3075 return flags;
3076}
3077
Paul Bakker57b12982012-02-11 17:38:38 +00003078int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003079{
3080 size_t i;
3081 size_t cn_idx = 0;
3082
Paul Bakker57b12982012-02-11 17:38:38 +00003083 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003084 return( 0 );
3085
3086 for( i = 0; i < strlen( cn ); ++i )
3087 {
3088 if( cn[i] == '.' )
3089 {
3090 cn_idx = i;
3091 break;
3092 }
3093 }
3094
3095 if( cn_idx == 0 )
3096 return( 0 );
3097
Paul Bakker535e97d2012-08-23 10:49:55 +00003098 if( strlen( cn ) - cn_idx == name->len - 1 &&
3099 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003100 {
3101 return( 1 );
3102 }
3103
3104 return( 0 );
3105}
3106
Paul Bakker915275b2012-09-28 07:10:55 +00003107static int x509parse_verify_top(
3108 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003109 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003110 int (*f_vrfy)(void *, x509_cert *, int, int *),
3111 void *p_vrfy )
3112{
3113 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003114 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003115 unsigned char hash[64];
3116
3117 if( x509parse_time_expired( &child->valid_to ) )
3118 *flags |= BADCERT_EXPIRED;
3119
3120 /*
3121 * Child is the top of the chain. Check against the trust_ca list.
3122 */
3123 *flags |= BADCERT_NOT_TRUSTED;
3124
3125 while( trust_ca != NULL )
3126 {
3127 if( trust_ca->version == 0 ||
3128 child->issuer_raw.len != trust_ca->subject_raw.len ||
3129 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3130 child->issuer_raw.len ) != 0 )
3131 {
3132 trust_ca = trust_ca->next;
3133 continue;
3134 }
3135
Paul Bakker9a736322012-11-14 12:39:52 +00003136 /*
3137 * Reduce path_len to check against if top of the chain is
3138 * the same as the trusted CA
3139 */
3140 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3141 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3142 child->issuer_raw.len ) == 0 )
3143 {
3144 check_path_cnt--;
3145 }
3146
Paul Bakker915275b2012-09-28 07:10:55 +00003147 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003148 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003149 {
3150 trust_ca = trust_ca->next;
3151 continue;
3152 }
3153
3154 hash_id = child->sig_alg;
3155
3156 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3157
3158 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3159 0, hash, child->sig.p ) != 0 )
3160 {
3161 trust_ca = trust_ca->next;
3162 continue;
3163 }
3164
3165 /*
3166 * Top of chain is signed by a trusted CA
3167 */
3168 *flags &= ~BADCERT_NOT_TRUSTED;
3169 break;
3170 }
3171
Paul Bakker9a736322012-11-14 12:39:52 +00003172 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003173 * If top of chain is not the same as the trusted CA send a verify request
3174 * to the callback for any issues with validity and CRL presence for the
3175 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003176 */
3177 if( trust_ca != NULL &&
3178 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3179 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3180 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003181 {
3182 /* Check trusted CA's CRL for then chain's top crt */
3183 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3184
3185 if( x509parse_time_expired( &trust_ca->valid_to ) )
3186 ca_flags |= BADCERT_EXPIRED;
3187
Paul Bakker915275b2012-09-28 07:10:55 +00003188 if( NULL != f_vrfy )
3189 {
Paul Bakker9a736322012-11-14 12:39:52 +00003190 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003191 return( ret );
3192 }
3193 }
3194
3195 /* Call callback on top cert */
3196 if( NULL != f_vrfy )
3197 {
Paul Bakker9a736322012-11-14 12:39:52 +00003198 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003199 return( ret );
3200 }
3201
Paul Bakker915275b2012-09-28 07:10:55 +00003202 *flags |= ca_flags;
3203
3204 return( 0 );
3205}
3206
3207static int x509parse_verify_child(
3208 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003209 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003210 int (*f_vrfy)(void *, x509_cert *, int, int *),
3211 void *p_vrfy )
3212{
3213 int hash_id, ret;
3214 int parent_flags = 0;
3215 unsigned char hash[64];
3216 x509_cert *grandparent;
3217
3218 if( x509parse_time_expired( &child->valid_to ) )
3219 *flags |= BADCERT_EXPIRED;
3220
3221 hash_id = child->sig_alg;
3222
3223 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3224
3225 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3226 child->sig.p ) != 0 )
3227 *flags |= BADCERT_NOT_TRUSTED;
3228
3229 /* Check trusted CA's CRL for the given crt */
3230 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3231
3232 grandparent = parent->next;
3233
3234 while( grandparent != NULL )
3235 {
3236 if( grandparent->version == 0 ||
3237 grandparent->ca_istrue == 0 ||
3238 parent->issuer_raw.len != grandparent->subject_raw.len ||
3239 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3240 parent->issuer_raw.len ) != 0 )
3241 {
3242 grandparent = grandparent->next;
3243 continue;
3244 }
3245 break;
3246 }
3247
Paul Bakker915275b2012-09-28 07:10:55 +00003248 if( grandparent != NULL )
3249 {
3250 /*
3251 * Part of the chain
3252 */
Paul Bakker9a736322012-11-14 12:39:52 +00003253 ret = x509parse_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003254 if( ret != 0 )
3255 return( ret );
3256 }
3257 else
3258 {
Paul Bakker9a736322012-11-14 12:39:52 +00003259 ret = x509parse_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003260 if( ret != 0 )
3261 return( ret );
3262 }
3263
3264 /* child is verified to be a child of the parent, call verify callback */
3265 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003266 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003267 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003268
3269 *flags |= parent_flags;
3270
3271 return( 0 );
3272}
3273
Paul Bakker76fd75a2011-01-16 21:12:10 +00003274/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003275 * Verify the certificate validity
3276 */
3277int x509parse_verify( x509_cert *crt,
3278 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003279 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003280 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003281 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003282 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003283{
Paul Bakker23986e52011-04-24 08:57:21 +00003284 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003285 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003286 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003287 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003288 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003289 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003290
Paul Bakker40ea7de2009-05-03 10:18:48 +00003291 *flags = 0;
3292
Paul Bakker5121ce52009-01-03 21:22:43 +00003293 if( cn != NULL )
3294 {
3295 name = &crt->subject;
3296 cn_len = strlen( cn );
3297
Paul Bakker4d2c1242012-05-10 14:12:46 +00003298 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003299 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003300 cur = &crt->subject_alt_names;
3301
3302 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003303 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003304 if( cur->buf.len == cn_len &&
3305 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003306 break;
3307
Paul Bakker535e97d2012-08-23 10:49:55 +00003308 if( cur->buf.len > 2 &&
3309 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003310 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003311 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003312
Paul Bakker4d2c1242012-05-10 14:12:46 +00003313 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003314 }
3315
3316 if( cur == NULL )
3317 *flags |= BADCERT_CN_MISMATCH;
3318 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003319 else
3320 {
3321 while( name != NULL )
3322 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003323 if( name->oid.len == 3 &&
3324 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003325 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003326 if( name->val.len == cn_len &&
3327 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003328 break;
3329
Paul Bakker535e97d2012-08-23 10:49:55 +00003330 if( name->val.len > 2 &&
3331 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003332 x509_wildcard_verify( cn, &name->val ) )
3333 break;
3334 }
3335
3336 name = name->next;
3337 }
3338
3339 if( name == NULL )
3340 *flags |= BADCERT_CN_MISMATCH;
3341 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003342 }
3343
Paul Bakker5121ce52009-01-03 21:22:43 +00003344 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003345 * Iterate upwards in the given cert chain, to find our crt parent.
3346 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003347 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003348 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003349
Paul Bakker76fd75a2011-01-16 21:12:10 +00003350 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003351 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003352 if( parent->ca_istrue == 0 ||
3353 crt->issuer_raw.len != parent->subject_raw.len ||
3354 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003355 crt->issuer_raw.len ) != 0 )
3356 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003357 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003358 continue;
3359 }
Paul Bakker915275b2012-09-28 07:10:55 +00003360 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003361 }
3362
Paul Bakker915275b2012-09-28 07:10:55 +00003363 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003364 {
Paul Bakker915275b2012-09-28 07:10:55 +00003365 /*
3366 * Part of the chain
3367 */
Paul Bakker9a736322012-11-14 12:39:52 +00003368 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003369 if( ret != 0 )
3370 return( ret );
3371 }
3372 else
Paul Bakker74111d32011-01-15 16:57:55 +00003373 {
Paul Bakker9a736322012-11-14 12:39:52 +00003374 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003375 if( ret != 0 )
3376 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003377 }
Paul Bakker915275b2012-09-28 07:10:55 +00003378
3379 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003380 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003381
Paul Bakker5121ce52009-01-03 21:22:43 +00003382 return( 0 );
3383}
3384
3385/*
3386 * Unallocate all certificate data
3387 */
3388void x509_free( x509_cert *crt )
3389{
3390 x509_cert *cert_cur = crt;
3391 x509_cert *cert_prv;
3392 x509_name *name_cur;
3393 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003394 x509_sequence *seq_cur;
3395 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003396
3397 if( crt == NULL )
3398 return;
3399
3400 do
3401 {
3402 rsa_free( &cert_cur->rsa );
3403
3404 name_cur = cert_cur->issuer.next;
3405 while( name_cur != NULL )
3406 {
3407 name_prv = name_cur;
3408 name_cur = name_cur->next;
3409 memset( name_prv, 0, sizeof( x509_name ) );
3410 free( name_prv );
3411 }
3412
3413 name_cur = cert_cur->subject.next;
3414 while( name_cur != NULL )
3415 {
3416 name_prv = name_cur;
3417 name_cur = name_cur->next;
3418 memset( name_prv, 0, sizeof( x509_name ) );
3419 free( name_prv );
3420 }
3421
Paul Bakker74111d32011-01-15 16:57:55 +00003422 seq_cur = cert_cur->ext_key_usage.next;
3423 while( seq_cur != NULL )
3424 {
3425 seq_prv = seq_cur;
3426 seq_cur = seq_cur->next;
3427 memset( seq_prv, 0, sizeof( x509_sequence ) );
3428 free( seq_prv );
3429 }
3430
Paul Bakker8afa70d2012-02-11 18:42:45 +00003431 seq_cur = cert_cur->subject_alt_names.next;
3432 while( seq_cur != NULL )
3433 {
3434 seq_prv = seq_cur;
3435 seq_cur = seq_cur->next;
3436 memset( seq_prv, 0, sizeof( x509_sequence ) );
3437 free( seq_prv );
3438 }
3439
Paul Bakker5121ce52009-01-03 21:22:43 +00003440 if( cert_cur->raw.p != NULL )
3441 {
3442 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3443 free( cert_cur->raw.p );
3444 }
3445
3446 cert_cur = cert_cur->next;
3447 }
3448 while( cert_cur != NULL );
3449
3450 cert_cur = crt;
3451 do
3452 {
3453 cert_prv = cert_cur;
3454 cert_cur = cert_cur->next;
3455
3456 memset( cert_prv, 0, sizeof( x509_cert ) );
3457 if( cert_prv != crt )
3458 free( cert_prv );
3459 }
3460 while( cert_cur != NULL );
3461}
3462
Paul Bakkerd98030e2009-05-02 15:13:40 +00003463/*
3464 * Unallocate all CRL data
3465 */
3466void x509_crl_free( x509_crl *crl )
3467{
3468 x509_crl *crl_cur = crl;
3469 x509_crl *crl_prv;
3470 x509_name *name_cur;
3471 x509_name *name_prv;
3472 x509_crl_entry *entry_cur;
3473 x509_crl_entry *entry_prv;
3474
3475 if( crl == NULL )
3476 return;
3477
3478 do
3479 {
3480 name_cur = crl_cur->issuer.next;
3481 while( name_cur != NULL )
3482 {
3483 name_prv = name_cur;
3484 name_cur = name_cur->next;
3485 memset( name_prv, 0, sizeof( x509_name ) );
3486 free( name_prv );
3487 }
3488
3489 entry_cur = crl_cur->entry.next;
3490 while( entry_cur != NULL )
3491 {
3492 entry_prv = entry_cur;
3493 entry_cur = entry_cur->next;
3494 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3495 free( entry_prv );
3496 }
3497
3498 if( crl_cur->raw.p != NULL )
3499 {
3500 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3501 free( crl_cur->raw.p );
3502 }
3503
3504 crl_cur = crl_cur->next;
3505 }
3506 while( crl_cur != NULL );
3507
3508 crl_cur = crl;
3509 do
3510 {
3511 crl_prv = crl_cur;
3512 crl_cur = crl_cur->next;
3513
3514 memset( crl_prv, 0, sizeof( x509_crl ) );
3515 if( crl_prv != crl )
3516 free( crl_prv );
3517 }
3518 while( crl_cur != NULL );
3519}
3520
Paul Bakker40e46942009-01-03 21:51:57 +00003521#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003522
Paul Bakker40e46942009-01-03 21:51:57 +00003523#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003524
3525/*
3526 * Checkup routine
3527 */
3528int x509_self_test( int verbose )
3529{
Paul Bakker5690efc2011-05-26 13:16:06 +00003530#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003531 int ret;
3532 int flags;
3533 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003534 x509_cert cacert;
3535 x509_cert clicert;
3536 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003537#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003538 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003539#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003540
3541 if( verbose != 0 )
3542 printf( " X.509 certificate load: " );
3543
3544 memset( &clicert, 0, sizeof( x509_cert ) );
3545
Paul Bakkereae09db2013-06-06 12:35:54 +02003546 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003547 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003548 if( ret != 0 )
3549 {
3550 if( verbose != 0 )
3551 printf( "failed\n" );
3552
3553 return( ret );
3554 }
3555
3556 memset( &cacert, 0, sizeof( x509_cert ) );
3557
Paul Bakkereae09db2013-06-06 12:35:54 +02003558 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003559 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003560 if( ret != 0 )
3561 {
3562 if( verbose != 0 )
3563 printf( "failed\n" );
3564
3565 return( ret );
3566 }
3567
3568 if( verbose != 0 )
3569 printf( "passed\n X.509 private key load: " );
3570
3571 i = strlen( test_ca_key );
3572 j = strlen( test_ca_pwd );
3573
Paul Bakker66b78b22011-03-25 14:22:50 +00003574 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3575
Paul Bakker5121ce52009-01-03 21:22:43 +00003576 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003577 (const unsigned char *) test_ca_key, i,
3578 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003579 {
3580 if( verbose != 0 )
3581 printf( "failed\n" );
3582
3583 return( ret );
3584 }
3585
3586 if( verbose != 0 )
3587 printf( "passed\n X.509 signature verify: ");
3588
Paul Bakker23986e52011-04-24 08:57:21 +00003589 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003590 if( ret != 0 )
3591 {
Paul Bakker23986e52011-04-24 08:57:21 +00003592 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003593 if( verbose != 0 )
3594 printf( "failed\n" );
3595
3596 return( ret );
3597 }
3598
Paul Bakker5690efc2011-05-26 13:16:06 +00003599#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003600 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003601 printf( "passed\n X.509 DHM parameter load: " );
3602
3603 i = strlen( test_dhm_params );
3604 j = strlen( test_ca_pwd );
3605
Paul Bakkereae09db2013-06-06 12:35:54 +02003606 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003607 {
3608 if( verbose != 0 )
3609 printf( "failed\n" );
3610
3611 return( ret );
3612 }
3613
3614 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003615 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003616#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003617
3618 x509_free( &cacert );
3619 x509_free( &clicert );
3620 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003621#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003622 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003623#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003624
3625 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003626#else
3627 ((void) verbose);
3628 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3629#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003630}
3631
3632#endif
3633
3634#endif