blob: 1b06e21c66017cb593b33bbe51d52018b1cff73d [file] [log] [blame]
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, Brainspark B.V.
Paul Bakker7c6b2c32013-09-16 13:49:26 +02005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * 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/*
26 * The ITU-T X.509 standard defines a certificate format for PKI.
27 *
28 * http://www.ietf.org/rfc/rfc3279.txt
29 * http://www.ietf.org/rfc/rfc3280.txt
30 *
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
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020037#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020038#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020039#else
40#include POLARSSL_CONFIG_FILE
41#endif
Paul Bakker7c6b2c32013-09-16 13:49:26 +020042
43#if defined(POLARSSL_X509_USE_C)
44
45#include "polarssl/x509.h"
46#include "polarssl/asn1.h"
47#include "polarssl/oid.h"
48#if defined(POLARSSL_PEM_PARSE_C)
49#include "polarssl/pem.h"
50#endif
51
Paul Bakker7dc4c442014-02-01 22:50:26 +010052#if defined(POLARSSL_PLATFORM_C)
53#include "polarssl/platform.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020054#else
Paul Bakker7dc4c442014-02-01 22:50:26 +010055#define polarssl_printf printf
Paul Bakker7c6b2c32013-09-16 13:49:26 +020056#define polarssl_malloc malloc
57#define polarssl_free free
58#endif
59
60#include <string.h>
61#include <stdlib.h>
Paul Bakkerfa6a6202013-10-28 18:48:30 +010062#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020063#include <windows.h>
64#else
65#include <time.h>
66#endif
67
Paul Bakkerfa6a6202013-10-28 18:48:30 +010068#if defined(EFIX64) || defined(EFI32)
69#include <stdio.h>
70#endif
71
Paul Bakker7c6b2c32013-09-16 13:49:26 +020072#if defined(POLARSSL_FS_IO)
73#include <stdio.h>
74#if !defined(_WIN32)
75#include <sys/types.h>
76#include <sys/stat.h>
77#include <dirent.h>
78#endif
79#endif
80
81/*
82 * CertificateSerialNumber ::= INTEGER
83 */
84int x509_get_serial( unsigned char **p, const unsigned char *end,
85 x509_buf *serial )
86{
87 int ret;
88
89 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +020090 return( POLARSSL_ERR_X509_INVALID_SERIAL +
Paul Bakker7c6b2c32013-09-16 13:49:26 +020091 POLARSSL_ERR_ASN1_OUT_OF_DATA );
92
93 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
94 **p != ASN1_INTEGER )
Paul Bakker51876562013-09-17 14:36:05 +020095 return( POLARSSL_ERR_X509_INVALID_SERIAL +
Paul Bakker7c6b2c32013-09-16 13:49:26 +020096 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
97
98 serial->tag = *(*p)++;
99
100 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200101 return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200102
103 serial->p = *p;
104 *p += serial->len;
105
106 return( 0 );
107}
108
109/* Get an algorithm identifier without parameters (eg for signatures)
110 *
111 * AlgorithmIdentifier ::= SEQUENCE {
112 * algorithm OBJECT IDENTIFIER,
113 * parameters ANY DEFINED BY algorithm OPTIONAL }
114 */
115int x509_get_alg_null( unsigned char **p, const unsigned char *end,
116 x509_buf *alg )
117{
118 int ret;
119
120 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200121 return( POLARSSL_ERR_X509_INVALID_ALG + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200122
123 return( 0 );
124}
125
126/*
127 * AttributeTypeAndValue ::= SEQUENCE {
128 * type AttributeType,
129 * value AttributeValue }
130 *
131 * AttributeType ::= OBJECT IDENTIFIER
132 *
133 * AttributeValue ::= ANY DEFINED BY AttributeType
134 */
135static int x509_get_attr_type_value( unsigned char **p,
136 const unsigned char *end,
137 x509_name *cur )
138{
139 int ret;
140 size_t len;
141 x509_buf *oid;
142 x509_buf *val;
143
144 if( ( ret = asn1_get_tag( p, end, &len,
145 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200146 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200147
148 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200149 return( POLARSSL_ERR_X509_INVALID_NAME +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200150 POLARSSL_ERR_ASN1_OUT_OF_DATA );
151
152 oid = &cur->oid;
153 oid->tag = **p;
154
155 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200156 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200157
158 oid->p = *p;
159 *p += oid->len;
160
161 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200162 return( POLARSSL_ERR_X509_INVALID_NAME +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200163 POLARSSL_ERR_ASN1_OUT_OF_DATA );
164
165 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
166 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
167 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker51876562013-09-17 14:36:05 +0200168 return( POLARSSL_ERR_X509_INVALID_NAME +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200169 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
170
171 val = &cur->val;
172 val->tag = *(*p)++;
173
174 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200175 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200176
177 val->p = *p;
178 *p += val->len;
179
180 cur->next = NULL;
181
182 return( 0 );
183}
184
185/*
186 * RelativeDistinguishedName ::=
187 * SET OF AttributeTypeAndValue
188 *
189 * AttributeTypeAndValue ::= SEQUENCE {
190 * type AttributeType,
191 * value AttributeValue }
192 *
193 * AttributeType ::= OBJECT IDENTIFIER
194 *
195 * AttributeValue ::= ANY DEFINED BY AttributeType
196 */
197int x509_get_name( unsigned char **p, const unsigned char *end,
198 x509_name *cur )
199{
200 int ret;
201 size_t len;
202 const unsigned char *end2;
203 x509_name *use;
204
205 if( ( ret = asn1_get_tag( p, end, &len,
206 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200207 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200208
209 end2 = end;
210 end = *p + len;
211 use = cur;
212
213 do
214 {
215 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
216 return( ret );
217
218 if( *p != end )
219 {
220 use->next = (x509_name *) polarssl_malloc(
221 sizeof( x509_name ) );
222
223 if( use->next == NULL )
224 return( POLARSSL_ERR_X509_MALLOC_FAILED );
225
226 memset( use->next, 0, sizeof( x509_name ) );
227
228 use = use->next;
229 }
230 }
231 while( *p != end );
232
233 /*
234 * recurse until end of SEQUENCE is reached
235 */
236 if( *p == end2 )
237 return( 0 );
238
239 cur->next = (x509_name *) polarssl_malloc(
240 sizeof( x509_name ) );
241
242 if( cur->next == NULL )
243 return( POLARSSL_ERR_X509_MALLOC_FAILED );
244
245 memset( cur->next, 0, sizeof( x509_name ) );
246
247 return( x509_get_name( p, end2, cur->next ) );
248}
249
250/*
251 * Time ::= CHOICE {
252 * utcTime UTCTime,
253 * generalTime GeneralizedTime }
254 */
255int x509_get_time( unsigned char **p, const unsigned char *end,
256 x509_time *time )
257{
258 int ret;
259 size_t len;
260 char date[64];
261 unsigned char tag;
262
263 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200264 return( POLARSSL_ERR_X509_INVALID_DATE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200265 POLARSSL_ERR_ASN1_OUT_OF_DATA );
266
267 tag = **p;
268
269 if ( tag == ASN1_UTC_TIME )
270 {
271 (*p)++;
272 ret = asn1_get_len( p, end, &len );
Paul Bakker51876562013-09-17 14:36:05 +0200273
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200274 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200275 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200276
277 memset( date, 0, sizeof( date ) );
278 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
279 len : sizeof( date ) - 1 );
280
Manuel Pégourié-Gonnard9655e452014-04-11 12:29:49 +0200281 if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ",
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200282 &time->year, &time->mon, &time->day,
283 &time->hour, &time->min, &time->sec ) < 5 )
Paul Bakker51876562013-09-17 14:36:05 +0200284 return( POLARSSL_ERR_X509_INVALID_DATE );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200285
286 time->year += 100 * ( time->year < 50 );
287 time->year += 1900;
288
289 *p += len;
290
291 return( 0 );
292 }
293 else if ( tag == ASN1_GENERALIZED_TIME )
294 {
295 (*p)++;
296 ret = asn1_get_len( p, end, &len );
Paul Bakker51876562013-09-17 14:36:05 +0200297
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200298 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200299 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200300
301 memset( date, 0, sizeof( date ) );
302 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
303 len : sizeof( date ) - 1 );
304
Manuel Pégourié-Gonnard9655e452014-04-11 12:29:49 +0200305 if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ",
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200306 &time->year, &time->mon, &time->day,
307 &time->hour, &time->min, &time->sec ) < 5 )
Paul Bakker51876562013-09-17 14:36:05 +0200308 return( POLARSSL_ERR_X509_INVALID_DATE );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200309
310 *p += len;
311
312 return( 0 );
313 }
314 else
Paul Bakker51876562013-09-17 14:36:05 +0200315 return( POLARSSL_ERR_X509_INVALID_DATE +
316 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200317}
318
319int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
320{
321 int ret;
322 size_t len;
323
324 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200325 return( POLARSSL_ERR_X509_INVALID_SIGNATURE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200326 POLARSSL_ERR_ASN1_OUT_OF_DATA );
327
328 sig->tag = **p;
329
330 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200331 return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200332
333 sig->len = len;
334 sig->p = *p;
335
336 *p += len;
337
338 return( 0 );
339}
340
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100341int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
342 pk_type_t *pk_alg )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200343{
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100344 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200345
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100346 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200347 return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200348
349 return( 0 );
350}
351
352/*
353 * X.509 Extensions (No parsing of extensions, pointer should
354 * be either manually updated or extensions should be parsed!
355 */
356int x509_get_ext( unsigned char **p, const unsigned char *end,
357 x509_buf *ext, int tag )
358{
359 int ret;
360 size_t len;
361
362 if( *p == end )
363 return( 0 );
364
365 ext->tag = **p;
366
367 if( ( ret = asn1_get_tag( p, end, &ext->len,
368 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
369 return( ret );
370
371 ext->p = *p;
372 end = *p + ext->len;
373
374 /*
375 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
376 *
377 * Extension ::= SEQUENCE {
378 * extnID OBJECT IDENTIFIER,
379 * critical BOOLEAN DEFAULT FALSE,
380 * extnValue OCTET STRING }
381 */
382 if( ( ret = asn1_get_tag( p, end, &len,
383 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200384 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200385
386 if( end != *p + len )
Paul Bakker51876562013-09-17 14:36:05 +0200387 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200388 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
389
390 return( 0 );
391}
392
393#if defined(POLARSSL_FS_IO)
394/*
395 * Load all data from a file into a given buffer.
396 */
397int x509_load_file( const char *path, unsigned char **buf, size_t *n )
398{
399 FILE *f;
400 long size;
401
402 if( ( f = fopen( path, "rb" ) ) == NULL )
403 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
404
405 fseek( f, 0, SEEK_END );
406 if( ( size = ftell( f ) ) == -1 )
407 {
408 fclose( f );
409 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
410 }
411 fseek( f, 0, SEEK_SET );
412
413 *n = (size_t) size;
414
415 if( *n + 1 == 0 ||
416 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
417 {
418 fclose( f );
419 return( POLARSSL_ERR_X509_MALLOC_FAILED );
420 }
421
422 if( fread( *buf, 1, *n, f ) != *n )
423 {
424 fclose( f );
425 polarssl_free( *buf );
426 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
427 }
428
429 fclose( f );
430
431 (*buf)[*n] = '\0';
432
433 return( 0 );
434}
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200435#endif /* POLARSSL_FS_IO */
436
Paul Bakker6edcd412013-10-29 15:22:54 +0100437#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
438 !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200439#include <stdarg.h>
440
441#if !defined vsnprintf
442#define vsnprintf _vsnprintf
443#endif // vsnprintf
444
445/*
446 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
447 * Result value is not size of buffer needed, but -1 if no fit is possible.
448 *
449 * This fuction tries to 'fix' this by at least suggesting enlarging the
450 * size by 20.
451 */
452static int compat_snprintf(char *str, size_t size, const char *format, ...)
453{
454 va_list ap;
455 int res = -1;
456
457 va_start( ap, format );
458
459 res = vsnprintf( str, size, format, ap );
460
461 va_end( ap );
462
463 // No quick fix possible
464 if ( res < 0 )
465 return( (int) size + 20 );
466
467 return res;
468}
469
470#define snprintf compat_snprintf
471#endif
472
473#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
474
475#define SAFE_SNPRINTF() \
476{ \
477 if( ret == -1 ) \
478 return( -1 ); \
479 \
480 if ( (unsigned int) ret > n ) { \
481 p[n - 1] = '\0'; \
482 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
483 } \
484 \
485 n -= (unsigned int) ret; \
486 p += (unsigned int) ret; \
487}
488
489/*
490 * Store the name in printable form into buf; no more
491 * than size characters will be written
492 */
Paul Bakker86d0c192013-09-18 11:11:02 +0200493int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200494{
495 int ret;
496 size_t i, n;
497 unsigned char c;
498 const x509_name *name;
499 const char *short_name = NULL;
500 char s[128], *p;
501
502 memset( s, 0, sizeof( s ) );
503
504 name = dn;
505 p = buf;
506 n = size;
507
508 while( name != NULL )
509 {
510 if( !name->oid.p )
511 {
512 name = name->next;
513 continue;
514 }
515
516 if( name != dn )
517 {
518 ret = snprintf( p, n, ", " );
519 SAFE_SNPRINTF();
520 }
521
522 ret = oid_get_attr_short_name( &name->oid, &short_name );
523
524 if( ret == 0 )
525 ret = snprintf( p, n, "%s=", short_name );
526 else
527 ret = snprintf( p, n, "\?\?=" );
528 SAFE_SNPRINTF();
529
530 for( i = 0; i < name->val.len; i++ )
531 {
532 if( i >= sizeof( s ) - 1 )
533 break;
534
535 c = name->val.p[i];
536 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
537 s[i] = '?';
538 else s[i] = c;
539 }
540 s[i] = '\0';
541 ret = snprintf( p, n, "%s", s );
542 SAFE_SNPRINTF();
543 name = name->next;
544 }
545
546 return( (int) ( size - n ) );
547}
548
549/*
550 * Store the serial in printable form into buf; no more
551 * than size characters will be written
552 */
Paul Bakker86d0c192013-09-18 11:11:02 +0200553int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200554{
555 int ret;
556 size_t i, n, nr;
557 char *p;
558
559 p = buf;
560 n = size;
561
562 nr = ( serial->len <= 32 )
563 ? serial->len : 28;
564
565 for( i = 0; i < nr; i++ )
566 {
567 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
568 continue;
569
570 ret = snprintf( p, n, "%02X%s",
571 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
572 SAFE_SNPRINTF();
573 }
574
575 if( nr != serial->len )
576 {
577 ret = snprintf( p, n, "...." );
578 SAFE_SNPRINTF();
579 }
580
581 return( (int) ( size - n ) );
582}
583
584/*
585 * Helper for writing "RSA key size", "EC key size", etc
586 */
587int x509_key_size_helper( char *buf, size_t size, const char *name )
588{
589 char *p = buf;
590 size_t n = size;
591 int ret;
592
593 if( strlen( name ) + sizeof( " key size" ) > size )
594 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;
595
596 ret = snprintf( p, n, "%s key size", name );
597 SAFE_SNPRINTF();
598
599 return( 0 );
600}
601
602/*
603 * Return an informational string describing the given OID
604 */
605const char *x509_oid_get_description( x509_buf *oid )
606{
607 const char *desc = NULL;
608 int ret;
609
610 ret = oid_get_extended_key_usage( oid, &desc );
611
612 if( ret != 0 )
613 return( NULL );
614
615 return( desc );
616}
617
618/* Return the x.y.z.... style numeric string for the given OID */
619int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
620{
621 return oid_get_numeric_string( buf, size, oid );
622}
623
624/*
625 * Return 0 if the x509_time is still valid, or 1 otherwise.
626 */
627#if defined(POLARSSL_HAVE_TIME)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200628
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100629static void x509_get_current_time( x509_time *now )
630{
Paul Bakkerfa6a6202013-10-28 18:48:30 +0100631#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200632 SYSTEMTIME st;
633
Manuel Pégourié-Gonnard0776a432014-04-11 12:25:45 +0200634 GetSystemTime(&st);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200635
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100636 now->year = st.wYear;
637 now->mon = st.wMonth;
638 now->day = st.wDay;
639 now->hour = st.wHour;
640 now->min = st.wMinute;
641 now->sec = st.wSecond;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200642#else
Paul Bakker5fff23b2014-03-26 15:34:54 +0100643 struct tm lt;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200644 time_t tt;
645
646 tt = time( NULL );
Manuel Pégourié-Gonnard0776a432014-04-11 12:25:45 +0200647 gmtime_r( &tt, &lt );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200648
Paul Bakker5fff23b2014-03-26 15:34:54 +0100649 now->year = lt.tm_year + 1900;
650 now->mon = lt.tm_mon + 1;
651 now->day = lt.tm_mday;
652 now->hour = lt.tm_hour;
653 now->min = lt.tm_min;
654 now->sec = lt.tm_sec;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200655#endif
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100656}
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200657
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100658/*
659 * Return 0 if before <= after, 1 otherwise
660 */
661static int x509_check_time( const x509_time *before, const x509_time *after )
662{
663 if( before->year > after->year )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200664 return( 1 );
665
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100666 if( before->year == after->year &&
667 before->mon > after->mon )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200668 return( 1 );
669
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100670 if( before->year == after->year &&
671 before->mon == after->mon &&
672 before->day > after->day )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200673 return( 1 );
674
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100675 if( before->year == after->year &&
676 before->mon == after->mon &&
677 before->day == after->day &&
678 before->hour > after->hour )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200679 return( 1 );
680
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100681 if( before->year == after->year &&
682 before->mon == after->mon &&
683 before->day == after->day &&
684 before->hour == after->hour &&
685 before->min > after->min )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200686 return( 1 );
687
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100688 if( before->year == after->year &&
689 before->mon == after->mon &&
690 before->day == after->day &&
691 before->hour == after->hour &&
692 before->min == after->min &&
693 before->sec > after->sec )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200694 return( 1 );
695
696 return( 0 );
697}
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100698
699int x509_time_expired( const x509_time *to )
700{
701 x509_time now;
702
703 x509_get_current_time( &now );
704
705 return( x509_check_time( &now, to ) );
706}
707
708int x509_time_future( const x509_time *from )
709{
710 x509_time now;
711
712 x509_get_current_time( &now );
713
714 return( x509_check_time( from, &now ) );
715}
716
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200717#else /* POLARSSL_HAVE_TIME */
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100718
Paul Bakker86d0c192013-09-18 11:11:02 +0200719int x509_time_expired( const x509_time *to )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200720{
721 ((void) to);
722 return( 0 );
723}
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100724
725int x509_time_future( const x509_time *from )
726{
727 ((void) from);
728 return( 0 );
729}
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200730#endif /* POLARSSL_HAVE_TIME */
731
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200732#if defined(POLARSSL_SELF_TEST)
733
734#include "polarssl/x509_crt.h"
735#include "polarssl/certs.h"
736
737/*
738 * Checkup routine
739 */
740int x509_self_test( int verbose )
741{
742#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
743 int ret;
744 int flags;
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200745 x509_crt cacert;
746 x509_crt clicert;
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200747
748 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100749 polarssl_printf( " X.509 certificate load: " );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200750
Paul Bakkerb6b09562013-09-18 14:17:41 +0200751 x509_crt_init( &clicert );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200752
Paul Bakkerddf26b42013-09-18 13:46:23 +0200753 ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
754 strlen( test_cli_crt ) );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200755 if( ret != 0 )
756 {
757 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100758 polarssl_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200759
760 return( ret );
761 }
762
Paul Bakkerb6b09562013-09-18 14:17:41 +0200763 x509_crt_init( &cacert );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200764
Paul Bakkerddf26b42013-09-18 13:46:23 +0200765 ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
766 strlen( test_ca_crt ) );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200767 if( ret != 0 )
768 {
769 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100770 polarssl_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200771
772 return( ret );
773 }
774
775 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100776 polarssl_printf( "passed\n X.509 signature verify: ");
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200777
Paul Bakkerddf26b42013-09-18 13:46:23 +0200778 ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200779 if( ret != 0 )
780 {
781 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100782 polarssl_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200783
Paul Bakker7dc4c442014-02-01 22:50:26 +0100784 polarssl_printf("ret = %d, &flags = %04x\n", ret, flags);
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200785
786 return( ret );
787 }
788
789 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100790 polarssl_printf( "passed\n\n");
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200791
792 x509_crt_free( &cacert );
793 x509_crt_free( &clicert );
794
795 return( 0 );
796#else
797 ((void) verbose);
798 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
799#endif
800}
801
802#endif
803
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200804#endif /* POLARSSL_X509_USE_C */