blob: 331c8a0667af6a12ab3d3ef4022c56f006d9b091 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02004 * Copyright (C) 2006-2013, 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 Bakkerc70b9822013-04-07 22:00:46 +020043#include "polarssl/oid.h"
Paul Bakkercff68422013-09-15 20:43:33 +020044#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker96743fc2011-02-12 14:30:57 +000045#include "polarssl/pem.h"
Paul Bakkercff68422013-09-15 20:43:33 +020046#endif
Paul Bakker28144de2013-06-24 19:28:55 +020047#if defined(POLARSSL_PKCS5_C)
48#include "polarssl/pkcs5.h"
49#endif
Paul Bakker38b50d72013-06-24 19:33:27 +020050#if defined(POLARSSL_PKCS12_C)
51#include "polarssl/pkcs12.h"
52#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000053
Paul Bakker6e339b52013-07-03 13:37:05 +020054#if defined(POLARSSL_MEMORY_C)
55#include "polarssl/memory.h"
56#else
57#define polarssl_malloc malloc
58#define polarssl_free free
59#endif
60
Paul Bakker5121ce52009-01-03 21:22:43 +000061#include <string.h>
62#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000063#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000064#include <windows.h>
65#else
Paul Bakker5121ce52009-01-03 21:22:43 +000066#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000067#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000068
Paul Bakker335db3f2011-04-25 15:28:35 +000069#if defined(POLARSSL_FS_IO)
70#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000071#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000072#include <sys/types.h>
Paul Bakker2c8cdd22013-06-24 19:22:42 +020073#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000074#include <dirent.h>
75#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000076#endif
77
Paul Bakker5121ce52009-01-03 21:22:43 +000078/*
Paul Bakker5121ce52009-01-03 21:22:43 +000079 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
80 */
81static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000082 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000083 int *ver )
84{
Paul Bakker23986e52011-04-24 08:57:21 +000085 int ret;
86 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000087
88 if( ( ret = asn1_get_tag( p, end, &len,
89 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
90 {
Paul Bakker40e46942009-01-03 21:51:57 +000091 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +000092 {
93 *ver = 0;
94 return( 0 );
95 }
Paul Bakker5121ce52009-01-03 21:22:43 +000096
97 return( ret );
98 }
99
100 end = *p + len;
101
102 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000103 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000104
105 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000106 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000107 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000108
109 return( 0 );
110}
111
112/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000113 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000114 */
115static int x509_crl_get_version( unsigned char **p,
116 const unsigned char *end,
117 int *ver )
118{
119 int ret;
120
121 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
122 {
123 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000124 {
125 *ver = 0;
126 return( 0 );
127 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000128
129 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
130 }
131
132 return( 0 );
133}
134
135/*
Paul Bakkerf9f377e2013-09-09 15:35:10 +0200136 * Version ::= INTEGER { v1(0) }
137 */
138static int x509_csr_get_version( unsigned char **p,
139 const unsigned char *end,
140 int *ver )
141{
142 int ret;
143
144 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
145 {
146 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
147 {
148 *ver = 0;
149 return( 0 );
150 }
151
152 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
153 }
154
155 return( 0 );
156}
157
158/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000159 * CertificateSerialNumber ::= INTEGER
160 */
161static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000162 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000163 x509_buf *serial )
164{
165 int ret;
166
167 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000168 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000169 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
171 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
172 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000173 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000174 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000175
176 serial->tag = *(*p)++;
177
178 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000179 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000180
181 serial->p = *p;
182 *p += serial->len;
183
184 return( 0 );
185}
186
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +0200187/* Get an algorithm identifier without parameters (eg for signatures)
188 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000189 * AlgorithmIdentifier ::= SEQUENCE {
190 * algorithm OBJECT IDENTIFIER,
191 * parameters ANY DEFINED BY algorithm OPTIONAL }
192 */
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +0200193static int x509_get_alg_null( unsigned char **p, const unsigned char *end,
194 x509_buf *alg )
Paul Bakker5121ce52009-01-03 21:22:43 +0000195{
Paul Bakker23986e52011-04-24 08:57:21 +0000196 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +0200198 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 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
Paul Bakker5121ce52009-01-03 21:22:43 +0000201 return( 0 );
202}
203
204/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000205 * AttributeTypeAndValue ::= SEQUENCE {
206 * type AttributeType,
207 * value AttributeValue }
208 *
209 * AttributeType ::= OBJECT IDENTIFIER
210 *
211 * AttributeValue ::= ANY DEFINED BY AttributeType
212 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000213static int x509_get_attr_type_value( unsigned char **p,
214 const unsigned char *end,
215 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000216{
Paul Bakker23986e52011-04-24 08:57:21 +0000217 int ret;
218 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000219 x509_buf *oid;
220 x509_buf *val;
221
222 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000223 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000224 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000225
Manuel Pégourié-Gonnard686bfae2013-08-15 13:40:10 +0200226 if( ( end - *p ) < 1 )
227 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
228 POLARSSL_ERR_ASN1_OUT_OF_DATA );
229
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 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200299 use->next = (x509_name *) polarssl_malloc(
Paul Bakker400ff6f2011-02-20 10:40:16 +0000300 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
Paul Bakker6e339b52013-07-03 13:37:05 +0200318 cur->next = (x509_name *) polarssl_malloc(
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 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
Paul Bakker5121ce52009-01-03 21:22:43 +0000431static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000432 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000433 x509_buf *sig )
434{
Paul Bakker23986e52011-04-24 08:57:21 +0000435 int ret;
436 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
Paul Bakker8afa70d2012-02-11 18:42:45 +0000438 if( ( end - *p ) < 1 )
439 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
440 POLARSSL_ERR_ASN1_OUT_OF_DATA );
441
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 sig->tag = **p;
443
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200444 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000445 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
Paul Bakker5121ce52009-01-03 21:22:43 +0000447 sig->len = len;
448 sig->p = *p;
449
450 *p += len;
451
452 return( 0 );
453}
454
455/*
456 * X.509 v2/v3 unique identifier (not parsed)
457 */
458static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000459 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000460 x509_buf *uid, int n )
461{
462 int ret;
463
464 if( *p == end )
465 return( 0 );
466
467 uid->tag = **p;
468
469 if( ( ret = asn1_get_tag( p, end, &uid->len,
470 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
471 {
Paul Bakker40e46942009-01-03 21:51:57 +0000472 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000473 return( 0 );
474
475 return( ret );
476 }
477
478 uid->p = *p;
479 *p += uid->len;
480
481 return( 0 );
482}
483
484/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000485 * X.509 Extensions (No parsing of extensions, pointer should
486 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000487 */
488static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000489 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000490 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000491{
Paul Bakker23986e52011-04-24 08:57:21 +0000492 int ret;
493 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 if( *p == end )
496 return( 0 );
497
498 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000499
Paul Bakker5121ce52009-01-03 21:22:43 +0000500 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000501 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000502 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000503
504 ext->p = *p;
505 end = *p + ext->len;
506
507 /*
508 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
509 *
510 * Extension ::= SEQUENCE {
511 * extnID OBJECT IDENTIFIER,
512 * critical BOOLEAN DEFAULT FALSE,
513 * extnValue OCTET STRING }
514 */
515 if( ( ret = asn1_get_tag( p, end, &len,
516 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000517 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
519 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000520 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000521 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000522
Paul Bakkerd98030e2009-05-02 15:13:40 +0000523 return( 0 );
524}
525
526/*
527 * X.509 CRL v2 extensions (no extensions parsed yet.)
528 */
529static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000530 const unsigned char *end,
531 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000532{
Paul Bakker23986e52011-04-24 08:57:21 +0000533 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000534 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000535
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000536 /* Get explicit tag */
537 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000538 {
539 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
540 return( 0 );
541
542 return( ret );
543 }
544
545 while( *p < end )
546 {
547 if( ( ret = asn1_get_tag( p, end, &len,
548 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000549 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000550
551 *p += len;
552 }
553
554 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000555 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000556 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
557
558 return( 0 );
559}
560
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000561/*
562 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
563 */
564static int x509_get_crl_entry_ext( unsigned char **p,
565 const unsigned char *end,
566 x509_buf *ext )
567{
568 int ret;
569 size_t len = 0;
570
571 /* OPTIONAL */
572 if (end <= *p)
573 return( 0 );
574
575 ext->tag = **p;
576 ext->p = *p;
577
578 /*
579 * Get CRL-entry extension sequence header
580 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
581 */
582 if( ( ret = asn1_get_tag( p, end, &ext->len,
583 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
584 {
585 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
586 {
587 ext->p = NULL;
588 return( 0 );
589 }
590 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
591 }
592
593 end = *p + ext->len;
594
595 if( end != *p + ext->len )
596 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
597 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
598
599 while( *p < end )
600 {
601 if( ( ret = asn1_get_tag( p, end, &len,
602 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
603 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
604
605 *p += len;
606 }
607
608 if( *p != end )
609 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
610 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
611
612 return( 0 );
613}
614
Paul Bakker74111d32011-01-15 16:57:55 +0000615static int x509_get_basic_constraints( unsigned char **p,
616 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000617 int *ca_istrue,
618 int *max_pathlen )
619{
Paul Bakker23986e52011-04-24 08:57:21 +0000620 int ret;
621 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000622
623 /*
624 * BasicConstraints ::= SEQUENCE {
625 * cA BOOLEAN DEFAULT FALSE,
626 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
627 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000628 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000629 *max_pathlen = 0; /* endless */
630
631 if( ( ret = asn1_get_tag( p, end, &len,
632 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000633 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000634
635 if( *p == end )
636 return 0;
637
Paul Bakker3cccddb2011-01-16 21:46:31 +0000638 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000639 {
640 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000641 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000642
643 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000644 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000645
Paul Bakker3cccddb2011-01-16 21:46:31 +0000646 if( *ca_istrue != 0 )
647 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000648 }
649
650 if( *p == end )
651 return 0;
652
653 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000654 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000655
656 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000657 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000658 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
659
660 (*max_pathlen)++;
661
Paul Bakker74111d32011-01-15 16:57:55 +0000662 return 0;
663}
664
665static int x509_get_ns_cert_type( unsigned char **p,
666 const unsigned char *end,
667 unsigned char *ns_cert_type)
668{
669 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000670 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000671
672 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000673 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000674
675 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000676 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000677 POLARSSL_ERR_ASN1_INVALID_LENGTH );
678
679 /* Get actual bitstring */
680 *ns_cert_type = *bs.p;
681 return 0;
682}
683
684static int x509_get_key_usage( unsigned char **p,
685 const unsigned char *end,
686 unsigned char *key_usage)
687{
688 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000689 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000690
691 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000692 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000693
Paul Bakker94a67962012-08-23 13:03:52 +0000694 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000695 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000696 POLARSSL_ERR_ASN1_INVALID_LENGTH );
697
698 /* Get actual bitstring */
699 *key_usage = *bs.p;
700 return 0;
701}
702
Paul Bakkerd98030e2009-05-02 15:13:40 +0000703/*
Paul Bakker74111d32011-01-15 16:57:55 +0000704 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
705 *
706 * KeyPurposeId ::= OBJECT IDENTIFIER
707 */
708static int x509_get_ext_key_usage( unsigned char **p,
709 const unsigned char *end,
710 x509_sequence *ext_key_usage)
711{
712 int ret;
713
714 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000715 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000716
717 /* Sequence length must be >= 1 */
718 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000719 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000720 POLARSSL_ERR_ASN1_INVALID_LENGTH );
721
722 return 0;
723}
724
725/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000726 * SubjectAltName ::= GeneralNames
727 *
728 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
729 *
730 * GeneralName ::= CHOICE {
731 * otherName [0] OtherName,
732 * rfc822Name [1] IA5String,
733 * dNSName [2] IA5String,
734 * x400Address [3] ORAddress,
735 * directoryName [4] Name,
736 * ediPartyName [5] EDIPartyName,
737 * uniformResourceIdentifier [6] IA5String,
738 * iPAddress [7] OCTET STRING,
739 * registeredID [8] OBJECT IDENTIFIER }
740 *
741 * OtherName ::= SEQUENCE {
742 * type-id OBJECT IDENTIFIER,
743 * value [0] EXPLICIT ANY DEFINED BY type-id }
744 *
745 * EDIPartyName ::= SEQUENCE {
746 * nameAssigner [0] DirectoryString OPTIONAL,
747 * partyName [1] DirectoryString }
748 *
749 * NOTE: PolarSSL only parses and uses dNSName at this point.
750 */
751static int x509_get_subject_alt_name( unsigned char **p,
752 const unsigned char *end,
753 x509_sequence *subject_alt_name )
754{
755 int ret;
756 size_t len, tag_len;
757 asn1_buf *buf;
758 unsigned char tag;
759 asn1_sequence *cur = subject_alt_name;
760
761 /* Get main sequence tag */
762 if( ( ret = asn1_get_tag( p, end, &len,
763 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
764 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
765
766 if( *p + len != end )
767 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
768 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
769
770 while( *p < end )
771 {
772 if( ( end - *p ) < 1 )
773 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
774 POLARSSL_ERR_ASN1_OUT_OF_DATA );
775
776 tag = **p;
777 (*p)++;
778 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
779 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
780
781 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
782 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
783 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
784
785 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
786 {
787 *p += tag_len;
788 continue;
789 }
790
791 buf = &(cur->buf);
792 buf->tag = tag;
793 buf->p = *p;
794 buf->len = tag_len;
795 *p += buf->len;
796
797 /* Allocate and assign next pointer */
798 if (*p < end)
799 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200800 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkera8cd2392012-02-11 16:09:32 +0000801 sizeof( asn1_sequence ) );
802
803 if( cur->next == NULL )
804 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
805 POLARSSL_ERR_ASN1_MALLOC_FAILED );
806
Paul Bakker535e97d2012-08-23 10:49:55 +0000807 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000808 cur = cur->next;
809 }
810 }
811
812 /* Set final sequence entry's next pointer to NULL */
813 cur->next = NULL;
814
815 if( *p != end )
816 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
817 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
818
819 return( 0 );
820}
821
822/*
Paul Bakker74111d32011-01-15 16:57:55 +0000823 * X.509 v3 extensions
824 *
825 * TODO: Perform all of the basic constraints tests required by the RFC
826 * TODO: Set values for undetected extensions to a sane default?
827 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000828 */
829static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000830 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000831 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000832{
Paul Bakker23986e52011-04-24 08:57:21 +0000833 int ret;
834 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000835 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000836
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000837 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000838 {
839 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
840 return( 0 );
841
842 return( ret );
843 }
844
Paul Bakker5121ce52009-01-03 21:22:43 +0000845 while( *p < end )
846 {
Paul Bakker74111d32011-01-15 16:57:55 +0000847 /*
848 * Extension ::= SEQUENCE {
849 * extnID OBJECT IDENTIFIER,
850 * critical BOOLEAN DEFAULT FALSE,
851 * extnValue OCTET STRING }
852 */
853 x509_buf extn_oid = {0, 0, NULL};
854 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200855 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +0000856
Paul Bakker5121ce52009-01-03 21:22:43 +0000857 if( ( ret = asn1_get_tag( p, end, &len,
858 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000859 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000860
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000861 end_ext_data = *p + len;
862
Paul Bakker74111d32011-01-15 16:57:55 +0000863 /* Get extension ID */
864 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000865
Paul Bakker74111d32011-01-15 16:57:55 +0000866 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000867 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000868
Paul Bakker74111d32011-01-15 16:57:55 +0000869 extn_oid.p = *p;
870 *p += extn_oid.len;
871
872 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000873 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000874 POLARSSL_ERR_ASN1_OUT_OF_DATA );
875
876 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000877 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000878 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000879 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000880
Paul Bakker74111d32011-01-15 16:57:55 +0000881 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000882 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000883 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000884 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000885
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000886 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000887
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000888 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000889 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000890 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000891
Paul Bakker74111d32011-01-15 16:57:55 +0000892 /*
893 * Detect supported extensions
894 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200895 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
896
897 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000898 {
899 /* No parser found, skip extension */
900 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000901
Paul Bakker5c721f92011-07-27 16:51:09 +0000902#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +0000903 if( is_critical )
904 {
905 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +0000906 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000907 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
908 }
Paul Bakker5c721f92011-07-27 16:51:09 +0000909#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +0200910 continue;
911 }
912
913 crt->ext_types |= ext_type;
914
915 switch( ext_type )
916 {
917 case EXT_BASIC_CONSTRAINTS:
918 /* Parse basic constraints */
919 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
920 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
921 return ( ret );
922 break;
923
924 case EXT_KEY_USAGE:
925 /* Parse key usage */
926 if( ( ret = x509_get_key_usage( p, end_ext_octet,
927 &crt->key_usage ) ) != 0 )
928 return ( ret );
929 break;
930
931 case EXT_EXTENDED_KEY_USAGE:
932 /* Parse extended key usage */
933 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
934 &crt->ext_key_usage ) ) != 0 )
935 return ( ret );
936 break;
937
938 case EXT_SUBJECT_ALT_NAME:
939 /* Parse subject alt name */
940 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
941 &crt->subject_alt_names ) ) != 0 )
942 return ( ret );
943 break;
944
945 case EXT_NS_CERT_TYPE:
946 /* Parse netscape certificate type */
947 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
948 &crt->ns_cert_type ) ) != 0 )
949 return ( ret );
950 break;
951
952 default:
953 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +0000954 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000955 }
956
957 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000958 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000959 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000960
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 return( 0 );
962}
963
964/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000965 * X.509 CRL Entries
966 */
967static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000968 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000969 x509_crl_entry *entry )
970{
Paul Bakker23986e52011-04-24 08:57:21 +0000971 int ret;
972 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000973 x509_crl_entry *cur_entry = entry;
974
975 if( *p == end )
976 return( 0 );
977
Paul Bakker9be19372009-07-27 20:21:53 +0000978 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000979 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
980 {
981 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
982 return( 0 );
983
984 return( ret );
985 }
986
Paul Bakker9be19372009-07-27 20:21:53 +0000987 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000988
989 while( *p < end )
990 {
Paul Bakker23986e52011-04-24 08:57:21 +0000991 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000992 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000993
994 if( ( ret = asn1_get_tag( p, end, &len2,
995 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
996 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000997 return( ret );
998 }
999
Paul Bakker9be19372009-07-27 20:21:53 +00001000 cur_entry->raw.tag = **p;
1001 cur_entry->raw.p = *p;
1002 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001003 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001004
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001005 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001006 return( ret );
1007
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001008 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001009 return( ret );
1010
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001011 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001012 return( ret );
1013
Paul Bakker74111d32011-01-15 16:57:55 +00001014 if ( *p < end )
1015 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001016 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001017
1018 if( cur_entry->next == NULL )
1019 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1020
Paul Bakkerd98030e2009-05-02 15:13:40 +00001021 cur_entry = cur_entry->next;
1022 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1023 }
1024 }
1025
1026 return( 0 );
1027}
1028
Paul Bakkerc70b9822013-04-07 22:00:46 +02001029static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1030 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001031{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001032 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001033
Paul Bakkerc70b9822013-04-07 22:00:46 +02001034 if( ret != 0 )
1035 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001036
Paul Bakkerc70b9822013-04-07 22:00:46 +02001037 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001038}
1039
Paul Bakkerd98030e2009-05-02 15:13:40 +00001040/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001041 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001042 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001043static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1044 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001045{
Paul Bakker23986e52011-04-24 08:57:21 +00001046 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001047 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001048 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001049
Paul Bakker320a4b52009-03-28 18:52:39 +00001050 /*
1051 * Check for valid input
1052 */
1053 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001054 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001055
Paul Bakker6e339b52013-07-03 13:37:05 +02001056 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001057
1058 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001059 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001060
1061 memcpy( p, buf, buflen );
1062
1063 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001064
1065 crt->raw.p = p;
1066 crt->raw.len = len;
1067 end = p + len;
1068
1069 /*
1070 * Certificate ::= SEQUENCE {
1071 * tbsCertificate TBSCertificate,
1072 * signatureAlgorithm AlgorithmIdentifier,
1073 * signatureValue BIT STRING }
1074 */
1075 if( ( ret = asn1_get_tag( &p, end, &len,
1076 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1077 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001078 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001079 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001080 }
1081
Paul Bakkerb00ca422012-09-25 12:10:00 +00001082 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001083 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001084 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001085 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001086 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001087 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001088 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001089
Paul Bakker5121ce52009-01-03 21:22:43 +00001090 /*
1091 * TBSCertificate ::= SEQUENCE {
1092 */
1093 crt->tbs.p = p;
1094
1095 if( ( ret = asn1_get_tag( &p, end, &len,
1096 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1097 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001098 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001099 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001100 }
1101
1102 end = p + len;
1103 crt->tbs.len = end - crt->tbs.p;
1104
1105 /*
1106 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1107 *
1108 * CertificateSerialNumber ::= INTEGER
1109 *
1110 * signature AlgorithmIdentifier
1111 */
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02001112 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1113 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1114 ( ret = x509_get_alg_null( &p, end, &crt->sig_oid1 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001115 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001116 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001117 return( ret );
1118 }
1119
1120 crt->version++;
1121
1122 if( crt->version > 3 )
1123 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001124 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001125 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001126 }
1127
Paul Bakkerc70b9822013-04-07 22:00:46 +02001128 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1129 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001130 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001131 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001132 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001133 }
1134
1135 /*
1136 * issuer Name
1137 */
1138 crt->issuer_raw.p = p;
1139
1140 if( ( ret = asn1_get_tag( &p, end, &len,
1141 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1142 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001143 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001144 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001145 }
1146
1147 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1148 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001149 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001150 return( ret );
1151 }
1152
1153 crt->issuer_raw.len = p - crt->issuer_raw.p;
1154
1155 /*
1156 * Validity ::= SEQUENCE {
1157 * notBefore Time,
1158 * notAfter Time }
1159 *
1160 */
1161 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1162 &crt->valid_to ) ) != 0 )
1163 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001164 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001165 return( ret );
1166 }
1167
1168 /*
1169 * subject Name
1170 */
1171 crt->subject_raw.p = p;
1172
1173 if( ( ret = asn1_get_tag( &p, end, &len,
1174 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1175 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001176 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001177 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001178 }
1179
Paul Bakkercefb3962012-06-27 11:51:09 +00001180 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001181 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001182 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 return( ret );
1184 }
1185
1186 crt->subject_raw.len = p - crt->subject_raw.p;
1187
1188 /*
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +02001189 * SubjectPublicKeyInfo
Paul Bakker5121ce52009-01-03 21:22:43 +00001190 */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001191 if( ( ret = pk_parse_get_pubkey( &p, end, &crt->pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001192 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001193 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001194 return( ret );
1195 }
1196
Paul Bakker5121ce52009-01-03 21:22:43 +00001197 /*
1198 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1199 * -- If present, version shall be v2 or v3
1200 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1201 * -- If present, version shall be v2 or v3
1202 * extensions [3] EXPLICIT Extensions OPTIONAL
1203 * -- If present, version shall be v3
1204 */
1205 if( crt->version == 2 || crt->version == 3 )
1206 {
1207 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1208 if( ret != 0 )
1209 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001210 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 return( ret );
1212 }
1213 }
1214
1215 if( crt->version == 2 || crt->version == 3 )
1216 {
1217 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1218 if( ret != 0 )
1219 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001220 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001221 return( ret );
1222 }
1223 }
1224
1225 if( crt->version == 3 )
1226 {
Paul Bakker74111d32011-01-15 16:57:55 +00001227 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001228 if( ret != 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
1235 if( p != end )
1236 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001237 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001238 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001239 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001240 }
1241
Paul Bakkerb00ca422012-09-25 12:10:00 +00001242 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001243
1244 /*
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +02001245 * }
1246 * -- end of TBSCertificate
1247 *
Paul Bakker5121ce52009-01-03 21:22:43 +00001248 * signatureAlgorithm AlgorithmIdentifier,
1249 * signatureValue BIT STRING
1250 */
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02001251 if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001252 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001253 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001254 return( ret );
1255 }
1256
Paul Bakker535e97d2012-08-23 10:49:55 +00001257 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1258 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001260 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001261 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001262 }
1263
1264 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1265 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001266 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001267 return( ret );
1268 }
1269
1270 if( p != end )
1271 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001272 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001273 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001274 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 }
1276
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001277 return( 0 );
1278}
1279
1280/*
Paul Bakker42c65812013-06-24 19:21:59 +02001281 * Parse one X.509 certificate in DER format from a buffer and add them to a
1282 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001283 */
Paul Bakker42c65812013-06-24 19:21:59 +02001284int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001285{
Paul Bakker42c65812013-06-24 19:21:59 +02001286 int ret;
1287 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001288
1289 /*
1290 * Check for valid input
1291 */
1292 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001293 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001294
1295 while( crt->version != 0 && crt->next != NULL )
1296 {
1297 prev = crt;
1298 crt = crt->next;
1299 }
1300
1301 /*
1302 * Add new certificate on the end of the chain if needed.
1303 */
1304 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001305 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001306 crt->next = (x509_cert *) polarssl_malloc( sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001307
Paul Bakker7d06ad22009-05-02 15:53:56 +00001308 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001309 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001310
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001311 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001312 crt = crt->next;
1313 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001314 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001315
Paul Bakker42c65812013-06-24 19:21:59 +02001316 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1317 {
1318 if( prev )
1319 prev->next = NULL;
1320
1321 if( crt != chain )
Paul Bakker6e339b52013-07-03 13:37:05 +02001322 polarssl_free( crt );
Paul Bakker42c65812013-06-24 19:21:59 +02001323
1324 return( ret );
1325 }
1326
1327 return( 0 );
1328}
1329
1330/*
1331 * Parse one or more PEM certificates from a buffer and add them to the chained list
1332 */
1333int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1334{
Paul Bakkerdce7fdc2013-09-15 17:15:26 +02001335 int success = 0, first_error = 0, total_failed = 0;
Paul Bakker42c65812013-06-24 19:21:59 +02001336 int buf_format = X509_FORMAT_DER;
1337
1338 /*
1339 * Check for valid input
1340 */
1341 if( chain == NULL || buf == NULL )
1342 return( POLARSSL_ERR_X509_INVALID_INPUT );
1343
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001344 /*
1345 * Determine buffer content. Buffer contains either one DER certificate or
1346 * one or more PEM certificates.
1347 */
Paul Bakkercff68422013-09-15 20:43:33 +02001348#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001349 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001350 buf_format = X509_FORMAT_PEM;
1351#endif
1352
1353 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001354 return x509parse_crt_der( chain, buf, buflen );
1355
Paul Bakkercff68422013-09-15 20:43:33 +02001356#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001357 if( buf_format == X509_FORMAT_PEM )
1358 {
Paul Bakkerdce7fdc2013-09-15 17:15:26 +02001359 int ret;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001360 pem_context pem;
1361
1362 while( buflen > 0 )
1363 {
1364 size_t use_len;
1365 pem_init( &pem );
1366
1367 ret = pem_read_buffer( &pem,
1368 "-----BEGIN CERTIFICATE-----",
1369 "-----END CERTIFICATE-----",
1370 buf, NULL, 0, &use_len );
1371
1372 if( ret == 0 )
1373 {
1374 /*
1375 * Was PEM encoded
1376 */
1377 buflen -= use_len;
1378 buf += use_len;
1379 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001380 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1381 {
1382 return( ret );
1383 }
Paul Bakker00b28602013-06-24 13:02:41 +02001384 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001385 {
1386 pem_free( &pem );
1387
Paul Bakker5ed3b342013-06-24 19:05:46 +02001388 /*
1389 * PEM header and footer were found
1390 */
1391 buflen -= use_len;
1392 buf += use_len;
1393
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001394 if( first_error == 0 )
1395 first_error = ret;
1396
1397 continue;
1398 }
1399 else
1400 break;
1401
Paul Bakker42c65812013-06-24 19:21:59 +02001402 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001403
1404 pem_free( &pem );
1405
1406 if( ret != 0 )
1407 {
1408 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001409 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001410 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001411 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001412 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001413
1414 if( first_error == 0 )
1415 first_error = ret;
1416
Paul Bakker42c65812013-06-24 19:21:59 +02001417 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001418 continue;
1419 }
1420
1421 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001422 }
1423 }
1424#endif
1425
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001426 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001427 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001428 else if( first_error )
1429 return( first_error );
1430 else
1431 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001432}
1433
1434/*
Paul Bakkerf9f377e2013-09-09 15:35:10 +02001435 * Parse a CSR
1436 */
1437int x509parse_csr( x509_csr *csr, const unsigned char *buf, size_t buflen )
1438{
1439 int ret;
1440 size_t len;
1441 unsigned char *p, *end;
Paul Bakkercff68422013-09-15 20:43:33 +02001442#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakkerf9f377e2013-09-09 15:35:10 +02001443 size_t use_len;
1444 pem_context pem;
1445#endif
1446
1447 /*
1448 * Check for valid input
1449 */
1450 if( csr == NULL || buf == NULL )
1451 return( POLARSSL_ERR_X509_INVALID_INPUT );
1452
1453 memset( csr, 0, sizeof( x509_csr ) );
1454
Paul Bakkercff68422013-09-15 20:43:33 +02001455#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakkerf9f377e2013-09-09 15:35:10 +02001456 pem_init( &pem );
1457 ret = pem_read_buffer( &pem,
1458 "-----BEGIN CERTIFICATE REQUEST-----",
1459 "-----END CERTIFICATE REQUEST-----",
1460 buf, NULL, 0, &use_len );
1461
1462 if( ret == 0 )
1463 {
1464 /*
1465 * Was PEM encoded
1466 */
1467 buflen -= use_len;
1468 buf += use_len;
1469
1470 /*
1471 * Steal PEM buffer
1472 */
1473 p = pem.buf;
1474 pem.buf = NULL;
1475 len = pem.buflen;
1476 pem_free( &pem );
1477 }
1478 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1479 {
1480 pem_free( &pem );
1481 return( ret );
1482 }
1483 else
Manuel Pégourié-Gonnard85dfe082013-09-10 15:59:02 +02001484#endif
Paul Bakkerf9f377e2013-09-09 15:35:10 +02001485 {
1486 /*
1487 * nope, copy the raw DER data
1488 */
1489 p = (unsigned char *) polarssl_malloc( len = buflen );
1490
1491 if( p == NULL )
1492 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1493
1494 memcpy( p, buf, buflen );
1495
1496 buflen = 0;
1497 }
Paul Bakkerf9f377e2013-09-09 15:35:10 +02001498
1499 csr->raw.p = p;
1500 csr->raw.len = len;
1501 end = p + len;
1502
1503 /*
1504 * CertificationRequest ::= SEQUENCE {
1505 * certificationRequestInfo CertificationRequestInfo,
1506 * signatureAlgorithm AlgorithmIdentifier,
1507 * signature BIT STRING
1508 * }
1509 */
1510 if( ( ret = asn1_get_tag( &p, end, &len,
1511 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1512 {
1513 x509_csr_free( csr );
1514 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1515 }
1516
1517 if( len != (size_t) ( end - p ) )
1518 {
1519 x509_csr_free( csr );
1520 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
1521 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1522 }
1523
1524 /*
1525 * CertificationRequestInfo ::= SEQUENCE {
1526 */
1527 csr->cri.p = p;
1528
1529 if( ( ret = asn1_get_tag( &p, end, &len,
1530 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1531 {
1532 x509_csr_free( csr );
1533 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
1534 }
1535
1536 end = p + len;
1537 csr->cri.len = end - csr->cri.p;
1538
1539 /*
1540 * Version ::= INTEGER { v1(0) }
1541 */
1542 if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
1543 {
1544 x509_csr_free( csr );
1545 return( ret );
1546 }
1547
1548 csr->version++;
1549
1550 if( csr->version != 1 )
1551 {
1552 x509_csr_free( csr );
1553 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1554 }
1555
1556 /*
1557 * subject Name
1558 */
1559 csr->subject_raw.p = p;
1560
1561 if( ( ret = asn1_get_tag( &p, end, &len,
1562 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1563 {
1564 x509_csr_free( csr );
1565 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
1566 }
1567
1568 if( ( ret = x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
1569 {
1570 x509_csr_free( csr );
1571 return( ret );
1572 }
1573
1574 csr->subject_raw.len = p - csr->subject_raw.p;
1575
1576 /*
1577 * subjectPKInfo SubjectPublicKeyInfo
1578 */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001579 if( ( ret = pk_parse_get_pubkey( &p, end, &csr->pk ) ) != 0 )
Paul Bakkerf9f377e2013-09-09 15:35:10 +02001580 {
1581 x509_csr_free( csr );
1582 return( ret );
1583 }
1584
1585 /*
1586 * attributes [0] Attributes
1587 */
1588 if( ( ret = asn1_get_tag( &p, end, &len,
1589 ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ) != 0 )
1590 {
1591 x509_csr_free( csr );
1592 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
1593 }
1594 // TODO Parse Attributes / extension requests
1595
1596 p += len;
1597
1598 end = csr->raw.p + csr->raw.len;
1599
1600 /*
1601 * signatureAlgorithm AlgorithmIdentifier,
1602 * signature BIT STRING
1603 */
1604 if( ( ret = x509_get_alg_null( &p, end, &csr->sig_oid ) ) != 0 )
1605 {
1606 x509_csr_free( csr );
1607 return( ret );
1608 }
1609
1610 if( ( ret = x509_get_sig_alg( &csr->sig_oid, &csr->sig_md,
1611 &csr->sig_pk ) ) != 0 )
1612 {
1613 x509_csr_free( csr );
1614 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1615 }
1616
1617 if( ( ret = x509_get_sig( &p, end, &csr->sig ) ) != 0 )
1618 {
1619 x509_csr_free( csr );
1620 return( ret );
1621 }
1622
1623 if( p != end )
1624 {
1625 x509_csr_free( csr );
1626 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
1627 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1628 }
1629
1630 return( 0 );
1631}
1632
1633/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001634 * Parse one or more CRLs and add them to the chained list
1635 */
Paul Bakker23986e52011-04-24 08:57:21 +00001636int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001637{
Paul Bakker23986e52011-04-24 08:57:21 +00001638 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001639 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001640 unsigned char *p, *end;
1641 x509_crl *crl;
Paul Bakkercff68422013-09-15 20:43:33 +02001642#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001643 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001644 pem_context pem;
1645#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001646
1647 crl = chain;
1648
1649 /*
1650 * Check for valid input
1651 */
1652 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001653 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001654
1655 while( crl->version != 0 && crl->next != NULL )
1656 crl = crl->next;
1657
1658 /*
1659 * Add new CRL on the end of the chain if needed.
1660 */
1661 if ( crl->version != 0 && crl->next == NULL)
1662 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001663 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001664
Paul Bakker7d06ad22009-05-02 15:53:56 +00001665 if( crl->next == NULL )
1666 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001667 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001668 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001669 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001670
Paul Bakker7d06ad22009-05-02 15:53:56 +00001671 crl = crl->next;
1672 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001673 }
1674
Paul Bakkercff68422013-09-15 20:43:33 +02001675#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker96743fc2011-02-12 14:30:57 +00001676 pem_init( &pem );
1677 ret = pem_read_buffer( &pem,
1678 "-----BEGIN X509 CRL-----",
1679 "-----END X509 CRL-----",
1680 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001681
Paul Bakker96743fc2011-02-12 14:30:57 +00001682 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001683 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001684 /*
1685 * Was PEM encoded
1686 */
1687 buflen -= use_len;
1688 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001689
1690 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001691 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001692 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001693 p = pem.buf;
1694 pem.buf = NULL;
1695 len = pem.buflen;
1696 pem_free( &pem );
1697 }
Paul Bakker00b28602013-06-24 13:02:41 +02001698 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001699 {
1700 pem_free( &pem );
1701 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001702 }
1703 else
Manuel Pégourié-Gonnard85dfe082013-09-10 15:59:02 +02001704#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001705 {
1706 /*
1707 * nope, copy the raw DER data
1708 */
Paul Bakker6e339b52013-07-03 13:37:05 +02001709 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001710
1711 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001712 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001713
1714 memcpy( p, buf, buflen );
1715
1716 buflen = 0;
1717 }
1718
1719 crl->raw.p = p;
1720 crl->raw.len = len;
1721 end = p + len;
1722
1723 /*
1724 * CertificateList ::= SEQUENCE {
1725 * tbsCertList TBSCertList,
1726 * signatureAlgorithm AlgorithmIdentifier,
1727 * signatureValue BIT STRING }
1728 */
1729 if( ( ret = asn1_get_tag( &p, end, &len,
1730 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1731 {
1732 x509_crl_free( crl );
1733 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1734 }
1735
Paul Bakker23986e52011-04-24 08:57:21 +00001736 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001737 {
1738 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001739 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001740 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1741 }
1742
1743 /*
1744 * TBSCertList ::= SEQUENCE {
1745 */
1746 crl->tbs.p = p;
1747
1748 if( ( ret = asn1_get_tag( &p, end, &len,
1749 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1750 {
1751 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001752 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001753 }
1754
1755 end = p + len;
1756 crl->tbs.len = end - crl->tbs.p;
1757
1758 /*
1759 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1760 * -- if present, MUST be v2
1761 *
1762 * signature AlgorithmIdentifier
1763 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001764 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02001765 ( ret = x509_get_alg_null( &p, end, &crl->sig_oid1 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001766 {
1767 x509_crl_free( crl );
1768 return( ret );
1769 }
1770
1771 crl->version++;
1772
1773 if( crl->version > 2 )
1774 {
1775 x509_crl_free( crl );
1776 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1777 }
1778
Paul Bakkerc70b9822013-04-07 22:00:46 +02001779 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1780 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001781 {
1782 x509_crl_free( crl );
1783 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1784 }
1785
1786 /*
1787 * issuer Name
1788 */
1789 crl->issuer_raw.p = p;
1790
1791 if( ( ret = asn1_get_tag( &p, end, &len,
1792 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1793 {
1794 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001795 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001796 }
1797
1798 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1799 {
1800 x509_crl_free( crl );
1801 return( ret );
1802 }
1803
1804 crl->issuer_raw.len = p - crl->issuer_raw.p;
1805
1806 /*
1807 * thisUpdate Time
1808 * nextUpdate Time OPTIONAL
1809 */
Paul Bakker91200182010-02-18 21:26:15 +00001810 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001811 {
1812 x509_crl_free( crl );
1813 return( ret );
1814 }
1815
Paul Bakker91200182010-02-18 21:26:15 +00001816 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817 {
Paul Bakker9d781402011-05-09 16:17:09 +00001818 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001819 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001820 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001821 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001822 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001823 x509_crl_free( crl );
1824 return( ret );
1825 }
1826 }
1827
1828 /*
1829 * revokedCertificates SEQUENCE OF SEQUENCE {
1830 * userCertificate CertificateSerialNumber,
1831 * revocationDate Time,
1832 * crlEntryExtensions Extensions OPTIONAL
1833 * -- if present, MUST be v2
1834 * } OPTIONAL
1835 */
1836 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1837 {
1838 x509_crl_free( crl );
1839 return( ret );
1840 }
1841
1842 /*
1843 * crlExtensions EXPLICIT Extensions OPTIONAL
1844 * -- if present, MUST be v2
1845 */
1846 if( crl->version == 2 )
1847 {
1848 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1849
1850 if( ret != 0 )
1851 {
1852 x509_crl_free( crl );
1853 return( ret );
1854 }
1855 }
1856
1857 if( p != end )
1858 {
1859 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001860 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001861 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1862 }
1863
1864 end = crl->raw.p + crl->raw.len;
1865
1866 /*
1867 * signatureAlgorithm AlgorithmIdentifier,
1868 * signatureValue BIT STRING
1869 */
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02001870 if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001871 {
1872 x509_crl_free( crl );
1873 return( ret );
1874 }
1875
Paul Bakker535e97d2012-08-23 10:49:55 +00001876 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1877 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001878 {
1879 x509_crl_free( crl );
1880 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1881 }
1882
1883 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1884 {
1885 x509_crl_free( crl );
1886 return( ret );
1887 }
1888
1889 if( p != end )
1890 {
1891 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001892 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001893 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1894 }
1895
1896 if( buflen > 0 )
1897 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001898 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001899
Paul Bakker7d06ad22009-05-02 15:53:56 +00001900 if( crl->next == NULL )
1901 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001902 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001903 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001904 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001905
Paul Bakker7d06ad22009-05-02 15:53:56 +00001906 crl = crl->next;
1907 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001908
1909 return( x509parse_crl( crl, buf, buflen ) );
1910 }
1911
1912 return( 0 );
1913}
1914
Paul Bakker335db3f2011-04-25 15:28:35 +00001915#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001916/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001917 * Load all data from a file into a given buffer.
1918 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001919static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001920{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001921 FILE *f;
Paul Bakker42c3ccf2013-08-19 14:29:31 +02001922 long size;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001923
Paul Bakkerd98030e2009-05-02 15:13:40 +00001924 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001925 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001926
Paul Bakkerd98030e2009-05-02 15:13:40 +00001927 fseek( f, 0, SEEK_END );
Paul Bakker42c3ccf2013-08-19 14:29:31 +02001928 if( ( size = ftell( f ) ) == -1 )
1929 {
1930 fclose( f );
1931 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1932 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001933 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001934
Paul Bakker42c3ccf2013-08-19 14:29:31 +02001935 *n = (size_t) size;
1936
Paul Bakker694d3ae2013-08-19 14:23:38 +02001937 if( *n + 1 == 0 ||
1938 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001939 {
1940 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001941 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001942 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001943
Paul Bakkerd98030e2009-05-02 15:13:40 +00001944 if( fread( *buf, 1, *n, f ) != *n )
1945 {
1946 fclose( f );
Paul Bakker6e339b52013-07-03 13:37:05 +02001947 polarssl_free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001948 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001949 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001950
Paul Bakkerd98030e2009-05-02 15:13:40 +00001951 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001952
Paul Bakkerd98030e2009-05-02 15:13:40 +00001953 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001954
Paul Bakkerd98030e2009-05-02 15:13:40 +00001955 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001956}
1957
1958/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 * Load one or more certificates and add them to the chained list
1960 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001961int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001962{
1963 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001964 size_t n;
1965 unsigned char *buf;
1966
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02001967 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00001968 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001969
Paul Bakker69e095c2011-12-10 21:55:01 +00001970 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001971
1972 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02001973 polarssl_free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001974
1975 return( ret );
1976}
1977
Paul Bakker8d914582012-06-04 12:46:42 +00001978int x509parse_crtpath( x509_cert *chain, const char *path )
1979{
1980 int ret = 0;
1981#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001982 int w_ret;
1983 WCHAR szDir[MAX_PATH];
1984 char filename[MAX_PATH];
1985 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001986 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001987
Paul Bakker97872ac2012-11-02 12:53:26 +00001988 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001989 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001990
1991 if( len > MAX_PATH - 3 )
1992 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001993
Paul Bakker3338b792012-10-01 21:13:10 +00001994 memset( szDir, 0, sizeof(szDir) );
1995 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001996 memcpy( filename, path, len );
1997 filename[len++] = '\\';
1998 p = filename + len;
1999 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00002000
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002001 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00002002
Paul Bakker97872ac2012-11-02 12:53:26 +00002003 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00002004 if (hFind == INVALID_HANDLE_VALUE)
2005 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2006
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002007 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00002008 do
2009 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002010 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00002011
Paul Bakkere4791f32012-06-04 21:29:15 +00002012 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00002013 continue;
2014
Paul Bakker3338b792012-10-01 21:13:10 +00002015 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
2016 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002017 p, len - 1,
2018 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00002019
Paul Bakker3338b792012-10-01 21:13:10 +00002020 w_ret = x509parse_crtfile( chain, filename );
2021 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002022 ret++;
2023 else
2024 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002025 }
Paul Bakker97872ac2012-11-02 12:53:26 +00002026 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00002027
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002028 if (GetLastError() != ERROR_NO_MORE_FILES)
2029 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00002030
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002031cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00002032 FindClose( hFind );
2033#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002034 int t_ret, i;
2035 struct stat sb;
2036 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00002037 char entry_name[255];
2038 DIR *dir = opendir( path );
2039
2040 if( dir == NULL)
2041 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2042
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002043 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00002044 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002045 if( result == NULL )
2046 break;
2047
2048 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
2049
2050 i = stat( entry_name, &sb );
2051
2052 if( i == -1 )
Paul Bakker003dbad2013-09-09 17:26:14 +02002053 {
2054 closedir( dir );
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002055 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker003dbad2013-09-09 17:26:14 +02002056 }
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002057
2058 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00002059 continue;
2060
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002061 // Ignore parse errors
2062 //
Paul Bakker8d914582012-06-04 12:46:42 +00002063 t_ret = x509parse_crtfile( chain, entry_name );
2064 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002065 ret++;
2066 else
2067 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002068 }
2069 closedir( dir );
2070#endif
2071
2072 return( ret );
2073}
2074
Paul Bakkerd98030e2009-05-02 15:13:40 +00002075/*
Paul Bakkerf9f377e2013-09-09 15:35:10 +02002076 * Load a CSR into the structure
2077 */
2078int x509parse_csrfile( x509_csr *csr, const char *path )
2079{
2080 int ret;
2081 size_t n;
2082 unsigned char *buf;
2083
2084 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2085 return( ret );
2086
2087 ret = x509parse_csr( csr, buf, n );
2088
2089 memset( buf, 0, n + 1 );
2090 polarssl_free( buf );
2091
2092 return( ret );
2093}
2094
2095/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002096 * Load one or more CRLs and add them to the chained list
2097 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002098int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002099{
2100 int ret;
2101 size_t n;
2102 unsigned char *buf;
2103
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002104 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002105 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002106
Paul Bakker27fdf462011-06-09 13:55:13 +00002107 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002108
2109 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002110 polarssl_free( buf );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002111
2112 return( ret );
2113}
2114
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002115#if defined(POLARSSL_RSA_C)
2116/*
2117 * Load and parse a private RSA key
2118 */
2119int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd )
2120{
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002121 int ret;
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002122 pk_context pk;
2123
2124 pk_init( &pk );
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002125
Paul Bakker1a7550a2013-09-15 13:01:22 +02002126 ret = pk_parse_keyfile( &pk, path, pwd );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002127
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +02002128 if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) )
2129 ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
2130
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002131 if( ret == 0 )
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +02002132 rsa_copy( rsa, pk_rsa( pk ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002133 else
2134 rsa_free( rsa );
2135
2136 pk_free( &pk );
2137
2138 return( ret );
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002139}
2140
2141/*
2142 * Load and parse a public RSA key
2143 */
2144int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path )
2145{
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002146 int ret;
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002147 pk_context pk;
2148
2149 pk_init( &pk );
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002150
Paul Bakker1a7550a2013-09-15 13:01:22 +02002151 ret = pk_parse_public_keyfile( &pk, path );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002152
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +02002153 if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) )
2154 ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
2155
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002156 if( ret == 0 )
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +02002157 rsa_copy( rsa, pk_rsa( pk ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002158 else
2159 rsa_free( rsa );
2160
2161 pk_free( &pk );
2162
2163 return( ret );
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002164}
2165#endif /* POLARSSL_RSA_C */
Paul Bakker335db3f2011-04-25 15:28:35 +00002166#endif /* POLARSSL_FS_IO */
2167
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002168#if defined(POLARSSL_RSA_C)
Paul Bakker335db3f2011-04-25 15:28:35 +00002169/*
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002170 * Parse a private RSA key
2171 */
2172int x509parse_key_rsa( rsa_context *rsa,
2173 const unsigned char *key, size_t keylen,
2174 const unsigned char *pwd, size_t pwdlen )
2175{
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002176 int ret;
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002177 pk_context pk;
2178
2179 pk_init( &pk );
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002180
Paul Bakker1a7550a2013-09-15 13:01:22 +02002181 ret = pk_parse_key( &pk, key, keylen, pwd, pwdlen );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002182
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +02002183 if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) )
2184 ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
2185
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002186 if( ret == 0 )
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +02002187 rsa_copy( rsa, pk_rsa( pk ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002188 else
2189 rsa_free( rsa );
2190
2191 pk_free( &pk );
2192
2193 return( ret );
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002194}
2195
2196/*
2197 * Parse a public RSA key
2198 */
2199int x509parse_public_key_rsa( rsa_context *rsa,
2200 const unsigned char *key, size_t keylen )
2201{
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002202 int ret;
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002203 pk_context pk;
2204
2205 pk_init( &pk );
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002206
Paul Bakker1a7550a2013-09-15 13:01:22 +02002207 ret = pk_parse_public_key( &pk, key, keylen );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002208
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +02002209 if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) )
2210 ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
2211
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002212 if( ret == 0 )
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +02002213 rsa_copy( rsa, pk_rsa( pk ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002214 else
2215 rsa_free( rsa );
2216
2217 pk_free( &pk );
2218
2219 return( ret );
Manuel Pégourié-Gonnardab2d9832013-07-11 16:17:23 +02002220}
2221#endif /* POLARSSL_RSA_C */
2222
Paul Bakker5121ce52009-01-03 21:22:43 +00002223#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002224#include <stdarg.h>
2225
2226#if !defined vsnprintf
2227#define vsnprintf _vsnprintf
2228#endif // vsnprintf
2229
2230/*
2231 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2232 * Result value is not size of buffer needed, but -1 if no fit is possible.
2233 *
2234 * This fuction tries to 'fix' this by at least suggesting enlarging the
2235 * size by 20.
2236 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002237static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00002238{
2239 va_list ap;
2240 int res = -1;
2241
2242 va_start( ap, format );
2243
2244 res = vsnprintf( str, size, format, ap );
2245
2246 va_end( ap );
2247
2248 // No quick fix possible
2249 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002250 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002251
2252 return res;
2253}
2254
2255#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002256#endif
2257
Paul Bakkerd98030e2009-05-02 15:13:40 +00002258#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2259
2260#define SAFE_SNPRINTF() \
2261{ \
2262 if( ret == -1 ) \
2263 return( -1 ); \
2264 \
Paul Bakker23986e52011-04-24 08:57:21 +00002265 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002266 p[n - 1] = '\0'; \
2267 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2268 } \
2269 \
Paul Bakker23986e52011-04-24 08:57:21 +00002270 n -= (unsigned int) ret; \
2271 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002272}
2273
Paul Bakker5121ce52009-01-03 21:22:43 +00002274/*
2275 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002276 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002277 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002278int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002279{
Paul Bakker23986e52011-04-24 08:57:21 +00002280 int ret;
2281 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002282 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002283 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002284 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002285 char s[128], *p;
2286
2287 memset( s, 0, sizeof( s ) );
2288
2289 name = dn;
2290 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002291 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002292
2293 while( name != NULL )
2294 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002295 if( !name->oid.p )
2296 {
2297 name = name->next;
2298 continue;
2299 }
2300
Paul Bakker74111d32011-01-15 16:57:55 +00002301 if( name != dn )
2302 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002303 ret = snprintf( p, n, ", " );
2304 SAFE_SNPRINTF();
2305 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002306
Paul Bakkerc70b9822013-04-07 22:00:46 +02002307 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002308
Paul Bakkerc70b9822013-04-07 22:00:46 +02002309 if( ret == 0 )
2310 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002311 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00002312 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002313 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002314
2315 for( i = 0; i < name->val.len; i++ )
2316 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002317 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002318 break;
2319
2320 c = name->val.p[i];
2321 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2322 s[i] = '?';
2323 else s[i] = c;
2324 }
2325 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002326 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002327 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002328 name = name->next;
2329 }
2330
Paul Bakker23986e52011-04-24 08:57:21 +00002331 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002332}
2333
2334/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002335 * Store the serial in printable form into buf; no more
2336 * than size characters will be written
2337 */
2338int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2339{
Paul Bakker23986e52011-04-24 08:57:21 +00002340 int ret;
2341 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002342 char *p;
2343
2344 p = buf;
2345 n = size;
2346
2347 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002348 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002349
2350 for( i = 0; i < nr; i++ )
2351 {
Paul Bakker93048802011-12-05 14:38:06 +00002352 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002353 continue;
2354
Paul Bakkerdd476992011-01-16 21:34:59 +00002355 ret = snprintf( p, n, "%02X%s",
2356 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2357 SAFE_SNPRINTF();
2358 }
2359
Paul Bakker03c7c252011-11-25 12:37:37 +00002360 if( nr != serial->len )
2361 {
2362 ret = snprintf( p, n, "...." );
2363 SAFE_SNPRINTF();
2364 }
2365
Paul Bakker23986e52011-04-24 08:57:21 +00002366 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002367}
2368
2369/*
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +02002370 * Helper for writing "RSA key size", "EC key size", etc
2371 */
2372static int x509_key_size_helper( char *buf, size_t size, const char *name )
2373{
2374 char *p = buf;
2375 size_t n = size;
2376 int ret;
2377
2378 if( strlen( name ) + sizeof( " key size" ) > size )
2379 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;
2380
2381 ret = snprintf( p, n, "%s key size", name );
2382 SAFE_SNPRINTF();
2383
2384 return( 0 );
2385}
2386
2387/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002388 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002389 */
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +02002390#define BEFORE_COLON 14
2391#define BC "14"
Paul Bakkerff60ee62010-03-16 21:09:09 +00002392int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2393 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002394{
Paul Bakker23986e52011-04-24 08:57:21 +00002395 int ret;
2396 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002397 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002398 const char *desc = NULL;
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +02002399 char key_size_str[BEFORE_COLON];
Paul Bakker5121ce52009-01-03 21:22:43 +00002400
2401 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002402 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002403
Paul Bakkerd98030e2009-05-02 15:13:40 +00002404 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002405 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002406 SAFE_SNPRINTF();
2407 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002408 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002409 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002410
Paul Bakkerdd476992011-01-16 21:34:59 +00002411 ret = x509parse_serial_gets( p, n, &crt->serial);
2412 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002413
Paul Bakkerd98030e2009-05-02 15:13:40 +00002414 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2415 SAFE_SNPRINTF();
2416 ret = x509parse_dn_gets( p, n, &crt->issuer );
2417 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002418
Paul Bakkerd98030e2009-05-02 15:13:40 +00002419 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2420 SAFE_SNPRINTF();
2421 ret = x509parse_dn_gets( p, n, &crt->subject );
2422 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002423
Paul Bakkerd98030e2009-05-02 15:13:40 +00002424 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002425 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2426 crt->valid_from.year, crt->valid_from.mon,
2427 crt->valid_from.day, crt->valid_from.hour,
2428 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002429 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002430
Paul Bakkerd98030e2009-05-02 15:13:40 +00002431 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002432 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2433 crt->valid_to.year, crt->valid_to.mon,
2434 crt->valid_to.day, crt->valid_to.hour,
2435 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002436 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002437
Paul Bakkerc70b9822013-04-07 22:00:46 +02002438 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002439 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002440
Paul Bakkerc70b9822013-04-07 22:00:46 +02002441 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
2442 if( ret != 0 )
2443 ret = snprintf( p, n, "???" );
2444 else
Manuel Pégourié-Gonnard70f17682013-08-23 12:06:11 +02002445 ret = snprintf( p, n, "%s", desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002446 SAFE_SNPRINTF();
2447
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +02002448 if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +02002449 pk_get_name( &crt->pk ) ) ) != 0 )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +02002450 {
2451 return( ret );
2452 }
2453
2454 ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +02002455 (int) pk_get_size( &crt->pk ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002456 SAFE_SNPRINTF();
2457
Paul Bakker23986e52011-04-24 08:57:21 +00002458 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002459}
2460
Paul Bakker74111d32011-01-15 16:57:55 +00002461/*
2462 * Return an informational string describing the given OID
2463 */
2464const char *x509_oid_get_description( x509_buf *oid )
2465{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002466 const char *desc = NULL;
2467 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00002468
Paul Bakkerc70b9822013-04-07 22:00:46 +02002469 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002470
Paul Bakkerc70b9822013-04-07 22:00:46 +02002471 if( ret != 0 )
2472 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00002473
Paul Bakkerc70b9822013-04-07 22:00:46 +02002474 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002475}
2476
2477/* Return the x.y.z.... style numeric string for the given OID */
2478int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2479{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002480 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00002481}
2482
Paul Bakkerd98030e2009-05-02 15:13:40 +00002483/*
2484 * Return an informational string about the CRL.
2485 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002486int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2487 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002488{
Paul Bakker23986e52011-04-24 08:57:21 +00002489 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002490 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002491 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002492 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002493 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002494
2495 p = buf;
2496 n = size;
2497
2498 ret = snprintf( p, n, "%sCRL version : %d",
2499 prefix, crl->version );
2500 SAFE_SNPRINTF();
2501
2502 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2503 SAFE_SNPRINTF();
2504 ret = x509parse_dn_gets( p, n, &crl->issuer );
2505 SAFE_SNPRINTF();
2506
2507 ret = snprintf( p, n, "\n%sthis update : " \
2508 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2509 crl->this_update.year, crl->this_update.mon,
2510 crl->this_update.day, crl->this_update.hour,
2511 crl->this_update.min, crl->this_update.sec );
2512 SAFE_SNPRINTF();
2513
2514 ret = snprintf( p, n, "\n%snext update : " \
2515 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2516 crl->next_update.year, crl->next_update.mon,
2517 crl->next_update.day, crl->next_update.hour,
2518 crl->next_update.min, crl->next_update.sec );
2519 SAFE_SNPRINTF();
2520
2521 entry = &crl->entry;
2522
2523 ret = snprintf( p, n, "\n%sRevoked certificates:",
2524 prefix );
2525 SAFE_SNPRINTF();
2526
Paul Bakker9be19372009-07-27 20:21:53 +00002527 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002528 {
2529 ret = snprintf( p, n, "\n%sserial number: ",
2530 prefix );
2531 SAFE_SNPRINTF();
2532
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002533 ret = x509parse_serial_gets( p, n, &entry->serial);
2534 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002535
Paul Bakkerd98030e2009-05-02 15:13:40 +00002536 ret = snprintf( p, n, " revocation date: " \
2537 "%04d-%02d-%02d %02d:%02d:%02d",
2538 entry->revocation_date.year, entry->revocation_date.mon,
2539 entry->revocation_date.day, entry->revocation_date.hour,
2540 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002541 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002542
2543 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002544 }
2545
Paul Bakkerc70b9822013-04-07 22:00:46 +02002546 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002547 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002548
Paul Bakkerc70b9822013-04-07 22:00:46 +02002549 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
2550 if( ret != 0 )
2551 ret = snprintf( p, n, "???" );
2552 else
Manuel Pégourié-Gonnard70f17682013-08-23 12:06:11 +02002553 ret = snprintf( p, n, "%s", desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002554 SAFE_SNPRINTF();
2555
Paul Bakker1e27bb22009-07-19 20:25:25 +00002556 ret = snprintf( p, n, "\n" );
2557 SAFE_SNPRINTF();
2558
Paul Bakker23986e52011-04-24 08:57:21 +00002559 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002560}
2561
2562/*
Paul Bakkerf9f377e2013-09-09 15:35:10 +02002563 * Return an informational string about the CSR.
2564 */
2565int x509parse_csr_info( char *buf, size_t size, const char *prefix,
2566 const x509_csr *csr )
2567{
2568 int ret;
2569 size_t n;
2570 char *p;
2571 const char *desc;
2572 char key_size_str[BEFORE_COLON];
2573
2574 p = buf;
2575 n = size;
2576
2577 ret = snprintf( p, n, "%sCSR version : %d",
2578 prefix, csr->version );
2579 SAFE_SNPRINTF();
2580
2581 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2582 SAFE_SNPRINTF();
2583 ret = x509parse_dn_gets( p, n, &csr->subject );
2584 SAFE_SNPRINTF();
2585
2586 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
2587 SAFE_SNPRINTF();
2588
2589 ret = oid_get_sig_alg_desc( &csr->sig_oid, &desc );
2590 if( ret != 0 )
2591 ret = snprintf( p, n, "???" );
2592 else
2593 ret = snprintf( p, n, "%s", desc );
2594 SAFE_SNPRINTF();
2595
2596 if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
2597 pk_get_name( &csr->pk ) ) ) != 0 )
2598 {
2599 return( ret );
2600 }
2601
2602 ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
2603 (int) pk_get_size( &csr->pk ) );
2604 SAFE_SNPRINTF();
2605
2606 return( (int) ( size - n ) );
2607}
2608
2609/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002610 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002611 */
Paul Bakkerfa9b1002013-07-03 15:31:03 +02002612#if defined(POLARSSL_HAVE_TIME)
Paul Bakkerff60ee62010-03-16 21:09:09 +00002613int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002614{
Paul Bakkercce9d772011-11-18 14:26:47 +00002615 int year, mon, day;
2616 int hour, min, sec;
2617
2618#if defined(_WIN32)
2619 SYSTEMTIME st;
2620
2621 GetLocalTime(&st);
2622
2623 year = st.wYear;
2624 mon = st.wMonth;
2625 day = st.wDay;
2626 hour = st.wHour;
2627 min = st.wMinute;
2628 sec = st.wSecond;
2629#else
Paul Bakker5121ce52009-01-03 21:22:43 +00002630 struct tm *lt;
2631 time_t tt;
2632
2633 tt = time( NULL );
2634 lt = localtime( &tt );
2635
Paul Bakkercce9d772011-11-18 14:26:47 +00002636 year = lt->tm_year + 1900;
2637 mon = lt->tm_mon + 1;
2638 day = lt->tm_mday;
2639 hour = lt->tm_hour;
2640 min = lt->tm_min;
2641 sec = lt->tm_sec;
2642#endif
2643
2644 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002645 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002646
Paul Bakkercce9d772011-11-18 14:26:47 +00002647 if( year == to->year &&
2648 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002649 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002650
Paul Bakkercce9d772011-11-18 14:26:47 +00002651 if( year == to->year &&
2652 mon == to->mon &&
2653 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002654 return( 1 );
2655
Paul Bakkercce9d772011-11-18 14:26:47 +00002656 if( year == to->year &&
2657 mon == to->mon &&
2658 day == to->day &&
2659 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00002660 return( 1 );
2661
Paul Bakkercce9d772011-11-18 14:26:47 +00002662 if( year == to->year &&
2663 mon == to->mon &&
2664 day == to->day &&
2665 hour == to->hour &&
2666 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00002667 return( 1 );
2668
Paul Bakkercce9d772011-11-18 14:26:47 +00002669 if( year == to->year &&
2670 mon == to->mon &&
2671 day == to->day &&
2672 hour == to->hour &&
2673 min == to->min &&
2674 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00002675 return( 1 );
2676
Paul Bakker40ea7de2009-05-03 10:18:48 +00002677 return( 0 );
2678}
Paul Bakkerfa9b1002013-07-03 15:31:03 +02002679#else /* POLARSSL_HAVE_TIME */
2680int x509parse_time_expired( const x509_time *to )
2681{
2682 ((void) to);
2683 return( 0 );
2684}
2685#endif /* POLARSSL_HAVE_TIME */
Paul Bakker40ea7de2009-05-03 10:18:48 +00002686
2687/*
2688 * Return 1 if the certificate is revoked, or 0 otherwise.
2689 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002690int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002691{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002692 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002693
2694 while( cur != NULL && cur->serial.len != 0 )
2695 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002696 if( crt->serial.len == cur->serial.len &&
2697 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002698 {
2699 if( x509parse_time_expired( &cur->revocation_date ) )
2700 return( 1 );
2701 }
2702
2703 cur = cur->next;
2704 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002705
2706 return( 0 );
2707}
2708
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002709/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002710 * Check that the given certificate is valid accoring to the CRL.
2711 */
2712static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2713 x509_crl *crl_list)
2714{
2715 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002716 unsigned char hash[POLARSSL_MD_MAX_SIZE];
2717 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002718
Paul Bakker915275b2012-09-28 07:10:55 +00002719 if( ca == NULL )
2720 return( flags );
2721
Paul Bakker76fd75a2011-01-16 21:12:10 +00002722 /*
2723 * TODO: What happens if no CRL is present?
2724 * Suggestion: Revocation state should be unknown if no CRL is present.
2725 * For backwards compatibility this is not yet implemented.
2726 */
2727
Paul Bakker915275b2012-09-28 07:10:55 +00002728 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00002729 {
Paul Bakker915275b2012-09-28 07:10:55 +00002730 if( crl_list->version == 0 ||
2731 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00002732 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2733 crl_list->issuer_raw.len ) != 0 )
2734 {
2735 crl_list = crl_list->next;
2736 continue;
2737 }
2738
2739 /*
2740 * Check if CRL is correctly signed by the trusted CA
2741 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002742 md_info = md_info_from_type( crl_list->sig_md );
2743 if( md_info == NULL )
2744 {
2745 /*
2746 * Cannot check 'unknown' hash
2747 */
2748 flags |= BADCRL_NOT_TRUSTED;
2749 break;
2750 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002751
Paul Bakkerc70b9822013-04-07 22:00:46 +02002752 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002753
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +02002754 if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 ||
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +02002755 pk_verify( &ca->pk, crl_list->sig_md, hash, md_info->size,
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +02002756 crl_list->sig.p, crl_list->sig.len ) != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00002757 {
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +02002758 flags |= BADCRL_NOT_TRUSTED;
2759 break;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002760 }
2761
2762 /*
2763 * Check for validity of CRL (Do not drop out)
2764 */
2765 if( x509parse_time_expired( &crl_list->next_update ) )
2766 flags |= BADCRL_EXPIRED;
2767
2768 /*
2769 * Check if certificate is revoked
2770 */
2771 if( x509parse_revoked(crt, crl_list) )
2772 {
2773 flags |= BADCERT_REVOKED;
2774 break;
2775 }
2776
2777 crl_list = crl_list->next;
2778 }
2779 return flags;
2780}
2781
Paul Bakkera5943852013-09-09 17:21:45 +02002782// Equal == 0, inequal == 1
2783static int x509_name_cmp( const void *s1, const void *s2, size_t len )
2784{
2785 size_t i;
2786 unsigned char diff;
2787 const unsigned char *n1 = s1, *n2 = s2;
2788
2789 for( i = 0; i < len; i++ )
2790 {
2791 diff = n1[i] ^ n2[i];
2792
2793 if( ( n1[i] >= 'a' || n1[i] <= 'z' ) && ( diff == 0 || diff == 32 ) )
2794 continue;
2795
2796 if( ( n1[i] >= 'A' || n1[i] <= 'Z' ) && ( diff == 0 || diff == 32 ) )
2797 continue;
2798
2799 return( 1 );
2800 }
2801
2802 return( 0 );
2803}
2804
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02002805static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00002806{
2807 size_t i;
2808 size_t cn_idx = 0;
2809
Paul Bakker57b12982012-02-11 17:38:38 +00002810 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00002811 return( 0 );
2812
2813 for( i = 0; i < strlen( cn ); ++i )
2814 {
2815 if( cn[i] == '.' )
2816 {
2817 cn_idx = i;
2818 break;
2819 }
2820 }
2821
2822 if( cn_idx == 0 )
2823 return( 0 );
2824
Paul Bakker535e97d2012-08-23 10:49:55 +00002825 if( strlen( cn ) - cn_idx == name->len - 1 &&
Paul Bakkera5943852013-09-09 17:21:45 +02002826 x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00002827 {
2828 return( 1 );
2829 }
2830
2831 return( 0 );
2832}
2833
Paul Bakker915275b2012-09-28 07:10:55 +00002834static int x509parse_verify_top(
2835 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00002836 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00002837 int (*f_vrfy)(void *, x509_cert *, int, int *),
2838 void *p_vrfy )
2839{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002840 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00002841 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002842 unsigned char hash[POLARSSL_MD_MAX_SIZE];
2843 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00002844
2845 if( x509parse_time_expired( &child->valid_to ) )
2846 *flags |= BADCERT_EXPIRED;
2847
2848 /*
2849 * Child is the top of the chain. Check against the trust_ca list.
2850 */
2851 *flags |= BADCERT_NOT_TRUSTED;
2852
Manuel Pégourié-Gonnardcffe4a62013-08-23 16:47:30 +02002853 md_info = md_info_from_type( child->sig_md );
2854 if( md_info == NULL )
2855 {
2856 /*
2857 * Cannot check 'unknown', no need to try any CA
2858 */
2859 trust_ca = NULL;
2860 }
2861 else
2862 md( md_info, child->tbs.p, child->tbs.len, hash );
2863
Paul Bakker915275b2012-09-28 07:10:55 +00002864 while( trust_ca != NULL )
2865 {
2866 if( trust_ca->version == 0 ||
2867 child->issuer_raw.len != trust_ca->subject_raw.len ||
2868 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
2869 child->issuer_raw.len ) != 0 )
2870 {
2871 trust_ca = trust_ca->next;
2872 continue;
2873 }
2874
Paul Bakker9a736322012-11-14 12:39:52 +00002875 /*
2876 * Reduce path_len to check against if top of the chain is
2877 * the same as the trusted CA
2878 */
2879 if( child->subject_raw.len == trust_ca->subject_raw.len &&
2880 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +02002881 child->issuer_raw.len ) == 0 )
Paul Bakker9a736322012-11-14 12:39:52 +00002882 {
2883 check_path_cnt--;
2884 }
2885
Paul Bakker915275b2012-09-28 07:10:55 +00002886 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00002887 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00002888 {
2889 trust_ca = trust_ca->next;
2890 continue;
2891 }
2892
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +02002893 if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 ||
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +02002894 pk_verify( &trust_ca->pk, child->sig_md, hash, md_info->size,
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +02002895 child->sig.p, child->sig.len ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00002896 {
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +02002897 trust_ca = trust_ca->next;
2898 continue;
Paul Bakker915275b2012-09-28 07:10:55 +00002899 }
2900
2901 /*
2902 * Top of chain is signed by a trusted CA
2903 */
2904 *flags &= ~BADCERT_NOT_TRUSTED;
2905 break;
2906 }
2907
Paul Bakker9a736322012-11-14 12:39:52 +00002908 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01002909 * If top of chain is not the same as the trusted CA send a verify request
2910 * to the callback for any issues with validity and CRL presence for the
2911 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00002912 */
2913 if( trust_ca != NULL &&
2914 ( child->subject_raw.len != trust_ca->subject_raw.len ||
2915 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
2916 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00002917 {
Manuel Pégourié-Gonnardcffe4a62013-08-23 16:47:30 +02002918 /* Check trusted CA's CRL for the chain's top crt */
Paul Bakker915275b2012-09-28 07:10:55 +00002919 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
2920
2921 if( x509parse_time_expired( &trust_ca->valid_to ) )
2922 ca_flags |= BADCERT_EXPIRED;
2923
Paul Bakker915275b2012-09-28 07:10:55 +00002924 if( NULL != f_vrfy )
2925 {
Paul Bakker9a736322012-11-14 12:39:52 +00002926 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00002927 return( ret );
2928 }
2929 }
2930
2931 /* Call callback on top cert */
2932 if( NULL != f_vrfy )
2933 {
Paul Bakker9a736322012-11-14 12:39:52 +00002934 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00002935 return( ret );
2936 }
2937
Paul Bakker915275b2012-09-28 07:10:55 +00002938 *flags |= ca_flags;
2939
2940 return( 0 );
2941}
2942
2943static int x509parse_verify_child(
2944 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00002945 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00002946 int (*f_vrfy)(void *, x509_cert *, int, int *),
2947 void *p_vrfy )
2948{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002949 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00002950 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002951 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00002952 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002953 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00002954
2955 if( x509parse_time_expired( &child->valid_to ) )
2956 *flags |= BADCERT_EXPIRED;
2957
Paul Bakkerc70b9822013-04-07 22:00:46 +02002958 md_info = md_info_from_type( child->sig_md );
2959 if( md_info == NULL )
2960 {
2961 /*
2962 * Cannot check 'unknown' hash
2963 */
Paul Bakker915275b2012-09-28 07:10:55 +00002964 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002965 }
2966 else
2967 {
2968 md( md_info, child->tbs.p, child->tbs.len, hash );
2969
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +02002970 if( pk_can_do( &parent->pk, child->sig_pk ) == 0 ||
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +02002971 pk_verify( &parent->pk, child->sig_md, hash, md_info->size,
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +02002972 child->sig.p, child->sig.len ) != 0 )
Manuel Pégourié-Gonnardff56da32013-07-11 10:46:21 +02002973 {
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +02002974 *flags |= BADCERT_NOT_TRUSTED;
Manuel Pégourié-Gonnardff56da32013-07-11 10:46:21 +02002975 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002976 }
2977
Paul Bakker915275b2012-09-28 07:10:55 +00002978 /* Check trusted CA's CRL for the given crt */
2979 *flags |= x509parse_verifycrl(child, parent, ca_crl);
2980
2981 grandparent = parent->next;
2982
2983 while( grandparent != NULL )
2984 {
2985 if( grandparent->version == 0 ||
2986 grandparent->ca_istrue == 0 ||
2987 parent->issuer_raw.len != grandparent->subject_raw.len ||
2988 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
2989 parent->issuer_raw.len ) != 0 )
2990 {
2991 grandparent = grandparent->next;
2992 continue;
2993 }
2994 break;
2995 }
2996
Paul Bakker915275b2012-09-28 07:10:55 +00002997 if( grandparent != NULL )
2998 {
2999 /*
3000 * Part of the chain
3001 */
Paul Bakker9a736322012-11-14 12:39:52 +00003002 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 +00003003 if( ret != 0 )
3004 return( ret );
Paul Bakkera5943852013-09-09 17:21:45 +02003005 }
Paul Bakker915275b2012-09-28 07:10:55 +00003006 else
3007 {
Paul Bakker9a736322012-11-14 12:39:52 +00003008 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 +00003009 if( ret != 0 )
3010 return( ret );
3011 }
3012
3013 /* child is verified to be a child of the parent, call verify callback */
3014 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003015 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003016 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003017
3018 *flags |= parent_flags;
3019
3020 return( 0 );
3021}
3022
Paul Bakker76fd75a2011-01-16 21:12:10 +00003023/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003024 * Verify the certificate validity
3025 */
3026int x509parse_verify( x509_cert *crt,
3027 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003028 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003029 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003030 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003031 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003032{
Paul Bakker23986e52011-04-24 08:57:21 +00003033 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003034 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003035 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003036 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003037 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003038 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003039
Paul Bakker40ea7de2009-05-03 10:18:48 +00003040 *flags = 0;
3041
Paul Bakker5121ce52009-01-03 21:22:43 +00003042 if( cn != NULL )
3043 {
3044 name = &crt->subject;
3045 cn_len = strlen( cn );
3046
Paul Bakker4d2c1242012-05-10 14:12:46 +00003047 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003048 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003049 cur = &crt->subject_alt_names;
3050
3051 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003052 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003053 if( cur->buf.len == cn_len &&
Paul Bakkera5943852013-09-09 17:21:45 +02003054 x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003055 break;
3056
Paul Bakker535e97d2012-08-23 10:49:55 +00003057 if( cur->buf.len > 2 &&
3058 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003059 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003060 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003061
Paul Bakker4d2c1242012-05-10 14:12:46 +00003062 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003063 }
3064
3065 if( cur == NULL )
3066 *flags |= BADCERT_CN_MISMATCH;
3067 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003068 else
3069 {
3070 while( name != NULL )
3071 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003072 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003073 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003074 if( name->val.len == cn_len &&
Paul Bakkera5943852013-09-09 17:21:45 +02003075 x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003076 break;
3077
Paul Bakker535e97d2012-08-23 10:49:55 +00003078 if( name->val.len > 2 &&
3079 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003080 x509_wildcard_verify( cn, &name->val ) )
3081 break;
3082 }
3083
3084 name = name->next;
3085 }
3086
3087 if( name == NULL )
3088 *flags |= BADCERT_CN_MISMATCH;
3089 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003090 }
3091
Paul Bakker5121ce52009-01-03 21:22:43 +00003092 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003093 * Iterate upwards in the given cert chain, to find our crt parent.
3094 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003095 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003096 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003097
Paul Bakker76fd75a2011-01-16 21:12:10 +00003098 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003099 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003100 if( parent->ca_istrue == 0 ||
3101 crt->issuer_raw.len != parent->subject_raw.len ||
3102 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003103 crt->issuer_raw.len ) != 0 )
3104 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003105 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003106 continue;
3107 }
Paul Bakker915275b2012-09-28 07:10:55 +00003108 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003109 }
3110
Paul Bakker915275b2012-09-28 07:10:55 +00003111 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003112 {
Paul Bakker915275b2012-09-28 07:10:55 +00003113 /*
3114 * Part of the chain
3115 */
Paul Bakker9a736322012-11-14 12:39:52 +00003116 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003117 if( ret != 0 )
3118 return( ret );
3119 }
3120 else
Paul Bakker74111d32011-01-15 16:57:55 +00003121 {
Paul Bakker9a736322012-11-14 12:39:52 +00003122 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003123 if( ret != 0 )
3124 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003125 }
Paul Bakker915275b2012-09-28 07:10:55 +00003126
3127 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003128 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003129
Paul Bakker5121ce52009-01-03 21:22:43 +00003130 return( 0 );
3131}
3132
3133/*
3134 * Unallocate all certificate data
3135 */
3136void x509_free( x509_cert *crt )
3137{
3138 x509_cert *cert_cur = crt;
3139 x509_cert *cert_prv;
3140 x509_name *name_cur;
3141 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003142 x509_sequence *seq_cur;
3143 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003144
3145 if( crt == NULL )
3146 return;
3147
3148 do
3149 {
Manuel Pégourié-Gonnard674b2242013-07-10 14:32:58 +02003150 pk_free( &cert_cur->pk );
Paul Bakker5121ce52009-01-03 21:22:43 +00003151
3152 name_cur = cert_cur->issuer.next;
3153 while( name_cur != NULL )
3154 {
3155 name_prv = name_cur;
3156 name_cur = name_cur->next;
3157 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003158 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003159 }
3160
3161 name_cur = cert_cur->subject.next;
3162 while( name_cur != NULL )
3163 {
3164 name_prv = name_cur;
3165 name_cur = name_cur->next;
3166 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003167 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003168 }
3169
Paul Bakker74111d32011-01-15 16:57:55 +00003170 seq_cur = cert_cur->ext_key_usage.next;
3171 while( seq_cur != NULL )
3172 {
3173 seq_prv = seq_cur;
3174 seq_cur = seq_cur->next;
3175 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003176 polarssl_free( seq_prv );
Paul Bakker74111d32011-01-15 16:57:55 +00003177 }
3178
Paul Bakker8afa70d2012-02-11 18:42:45 +00003179 seq_cur = cert_cur->subject_alt_names.next;
3180 while( seq_cur != NULL )
3181 {
3182 seq_prv = seq_cur;
3183 seq_cur = seq_cur->next;
3184 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003185 polarssl_free( seq_prv );
Paul Bakker8afa70d2012-02-11 18:42:45 +00003186 }
3187
Paul Bakker5121ce52009-01-03 21:22:43 +00003188 if( cert_cur->raw.p != NULL )
3189 {
3190 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02003191 polarssl_free( cert_cur->raw.p );
Paul Bakker5121ce52009-01-03 21:22:43 +00003192 }
3193
3194 cert_cur = cert_cur->next;
3195 }
3196 while( cert_cur != NULL );
3197
3198 cert_cur = crt;
3199 do
3200 {
3201 cert_prv = cert_cur;
3202 cert_cur = cert_cur->next;
3203
3204 memset( cert_prv, 0, sizeof( x509_cert ) );
3205 if( cert_prv != crt )
Paul Bakker6e339b52013-07-03 13:37:05 +02003206 polarssl_free( cert_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003207 }
3208 while( cert_cur != NULL );
3209}
3210
Paul Bakkerd98030e2009-05-02 15:13:40 +00003211/*
3212 * Unallocate all CRL data
3213 */
3214void x509_crl_free( x509_crl *crl )
3215{
3216 x509_crl *crl_cur = crl;
3217 x509_crl *crl_prv;
3218 x509_name *name_cur;
3219 x509_name *name_prv;
3220 x509_crl_entry *entry_cur;
3221 x509_crl_entry *entry_prv;
3222
3223 if( crl == NULL )
3224 return;
3225
3226 do
3227 {
3228 name_cur = crl_cur->issuer.next;
3229 while( name_cur != NULL )
3230 {
3231 name_prv = name_cur;
3232 name_cur = name_cur->next;
3233 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003234 polarssl_free( name_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003235 }
3236
3237 entry_cur = crl_cur->entry.next;
3238 while( entry_cur != NULL )
3239 {
3240 entry_prv = entry_cur;
3241 entry_cur = entry_cur->next;
3242 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003243 polarssl_free( entry_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003244 }
3245
3246 if( crl_cur->raw.p != NULL )
3247 {
3248 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02003249 polarssl_free( crl_cur->raw.p );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003250 }
3251
3252 crl_cur = crl_cur->next;
3253 }
3254 while( crl_cur != NULL );
3255
3256 crl_cur = crl;
3257 do
3258 {
3259 crl_prv = crl_cur;
3260 crl_cur = crl_cur->next;
3261
3262 memset( crl_prv, 0, sizeof( x509_crl ) );
3263 if( crl_prv != crl )
Paul Bakker6e339b52013-07-03 13:37:05 +02003264 polarssl_free( crl_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003265 }
3266 while( crl_cur != NULL );
3267}
3268
Paul Bakkerf9f377e2013-09-09 15:35:10 +02003269/*
3270 * Unallocate all CSR data
3271 */
3272void x509_csr_free( x509_csr *csr )
3273{
3274 x509_name *name_cur;
3275 x509_name *name_prv;
3276
3277 if( csr == NULL )
3278 return;
3279
3280 pk_free( &csr->pk );
3281
3282 name_cur = csr->subject.next;
3283 while( name_cur != NULL )
3284 {
3285 name_prv = name_cur;
3286 name_cur = name_cur->next;
3287 memset( name_prv, 0, sizeof( x509_name ) );
3288 polarssl_free( name_prv );
3289 }
3290
3291 if( csr->raw.p != NULL )
3292 {
3293 memset( csr->raw.p, 0, csr->raw.len );
3294 polarssl_free( csr->raw.p );
3295 }
3296
3297 memset( csr, 0, sizeof( x509_csr ) );
3298}
3299
Paul Bakker40e46942009-01-03 21:51:57 +00003300#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003301
Paul Bakker40e46942009-01-03 21:51:57 +00003302#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003303
3304/*
3305 * Checkup routine
3306 */
3307int x509_self_test( int verbose )
3308{
Paul Bakker5690efc2011-05-26 13:16:06 +00003309#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003310 int ret;
3311 int flags;
Paul Bakker5121ce52009-01-03 21:22:43 +00003312 x509_cert cacert;
3313 x509_cert clicert;
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +02003314 pk_context pkey;
Paul Bakker5121ce52009-01-03 21:22:43 +00003315
3316 if( verbose != 0 )
3317 printf( " X.509 certificate load: " );
3318
3319 memset( &clicert, 0, sizeof( x509_cert ) );
3320
Paul Bakker3c2122f2013-06-24 19:03:14 +02003321 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003322 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003323 if( ret != 0 )
3324 {
3325 if( verbose != 0 )
3326 printf( "failed\n" );
3327
3328 return( ret );
3329 }
3330
3331 memset( &cacert, 0, sizeof( x509_cert ) );
3332
Paul Bakker3c2122f2013-06-24 19:03:14 +02003333 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003334 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003335 if( ret != 0 )
3336 {
3337 if( verbose != 0 )
3338 printf( "failed\n" );
3339
3340 return( ret );
3341 }
3342
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02003343#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
3344 defined(POLARSSL_DES_C) && defined(POLARSSL_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003345 if( verbose != 0 )
3346 printf( "passed\n X.509 private key load: " );
3347
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +02003348 pk_init( &pkey );
Paul Bakker66b78b22011-03-25 14:22:50 +00003349
Paul Bakker1a7550a2013-09-15 13:01:22 +02003350 if( ( ret = pk_parse_key( &pkey,
3351 (const unsigned char *) test_ca_key,
3352 strlen( test_ca_key ),
3353 (const unsigned char *) test_ca_pwd,
3354 strlen( test_ca_pwd ) ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003355 {
3356 if( verbose != 0 )
3357 printf( "failed\n" );
3358
3359 return( ret );
3360 }
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02003361#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003362
3363 if( verbose != 0 )
3364 printf( "passed\n X.509 signature verify: ");
3365
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +02003366 ret = x509parse_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003367 if( ret != 0 )
3368 {
3369 if( verbose != 0 )
3370 printf( "failed\n" );
3371
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +02003372 printf("ret = %d, &flags = %04x\n", ret, flags);
3373
Paul Bakker5121ce52009-01-03 21:22:43 +00003374 return( ret );
3375 }
3376
3377 if( verbose != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +02003378 printf( "passed\n\n");
Paul Bakker5121ce52009-01-03 21:22:43 +00003379
3380 x509_free( &cacert );
3381 x509_free( &clicert );
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +02003382 pk_free( &pkey );
Paul Bakker5121ce52009-01-03 21:22:43 +00003383
3384 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003385#else
3386 ((void) verbose);
3387 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3388#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003389}
3390
3391#endif
3392
3393#endif