blob: 80390ae738670d53bb02ef5b73f1879f0cba19bc [file] [log] [blame]
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001/*
2 * X.509 certificate and private key decoding
3 *
4 * Copyright (C) 2006-2013, Brainspark B.V.
5 *
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
37#include "polarssl/config.h"
38
39#if defined(POLARSSL_X509_USE_C)
40
41#include "polarssl/x509.h"
42#include "polarssl/asn1.h"
43#include "polarssl/oid.h"
44#if defined(POLARSSL_PEM_PARSE_C)
45#include "polarssl/pem.h"
46#endif
47
48#if defined(POLARSSL_MEMORY_C)
49#include "polarssl/memory.h"
50#else
51#define polarssl_malloc malloc
52#define polarssl_free free
53#endif
54
55#include <string.h>
56#include <stdlib.h>
Paul Bakkerfa6a6202013-10-28 18:48:30 +010057#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020058#include <windows.h>
59#else
60#include <time.h>
61#endif
62
Paul Bakkerfa6a6202013-10-28 18:48:30 +010063#if defined(EFIX64) || defined(EFI32)
64#include <stdio.h>
65#endif
66
Paul Bakker7c6b2c32013-09-16 13:49:26 +020067#if defined(POLARSSL_FS_IO)
68#include <stdio.h>
69#if !defined(_WIN32)
70#include <sys/types.h>
71#include <sys/stat.h>
72#include <dirent.h>
73#endif
74#endif
75
76/*
77 * CertificateSerialNumber ::= INTEGER
78 */
79int x509_get_serial( unsigned char **p, const unsigned char *end,
80 x509_buf *serial )
81{
82 int ret;
83
84 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +020085 return( POLARSSL_ERR_X509_INVALID_SERIAL +
Paul Bakker7c6b2c32013-09-16 13:49:26 +020086 POLARSSL_ERR_ASN1_OUT_OF_DATA );
87
88 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
89 **p != ASN1_INTEGER )
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_UNEXPECTED_TAG );
92
93 serial->tag = *(*p)++;
94
95 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +020096 return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +020097
98 serial->p = *p;
99 *p += serial->len;
100
101 return( 0 );
102}
103
104/* Get an algorithm identifier without parameters (eg for signatures)
105 *
106 * AlgorithmIdentifier ::= SEQUENCE {
107 * algorithm OBJECT IDENTIFIER,
108 * parameters ANY DEFINED BY algorithm OPTIONAL }
109 */
110int x509_get_alg_null( unsigned char **p, const unsigned char *end,
111 x509_buf *alg )
112{
113 int ret;
114
115 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200116 return( POLARSSL_ERR_X509_INVALID_ALG + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200117
118 return( 0 );
119}
120
121/*
Manuel Pégourié-Gonnardb1d4eb12014-01-22 10:12:57 +0100122 * Parse an algorithm identifier with (optional) paramaters
123 */
124int x509_get_alg( unsigned char **p, const unsigned char *end,
125 x509_buf *alg, x509_buf *params )
126{
127 int ret;
128
129 if( ( ret = asn1_get_alg( p, end, alg, params ) ) != 0 )
130 return( POLARSSL_ERR_X509_INVALID_ALG + ret );
131
132 return( 0 );
133}
134
135/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200136 * AttributeTypeAndValue ::= SEQUENCE {
137 * type AttributeType,
138 * value AttributeValue }
139 *
140 * AttributeType ::= OBJECT IDENTIFIER
141 *
142 * AttributeValue ::= ANY DEFINED BY AttributeType
143 */
144static int x509_get_attr_type_value( unsigned char **p,
145 const unsigned char *end,
146 x509_name *cur )
147{
148 int ret;
149 size_t len;
150 x509_buf *oid;
151 x509_buf *val;
152
153 if( ( ret = asn1_get_tag( p, end, &len,
154 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200155 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200156
157 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200158 return( POLARSSL_ERR_X509_INVALID_NAME +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200159 POLARSSL_ERR_ASN1_OUT_OF_DATA );
160
161 oid = &cur->oid;
162 oid->tag = **p;
163
164 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200165 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200166
167 oid->p = *p;
168 *p += oid->len;
169
170 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200171 return( POLARSSL_ERR_X509_INVALID_NAME +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200172 POLARSSL_ERR_ASN1_OUT_OF_DATA );
173
174 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
175 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
176 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker51876562013-09-17 14:36:05 +0200177 return( POLARSSL_ERR_X509_INVALID_NAME +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200178 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
179
180 val = &cur->val;
181 val->tag = *(*p)++;
182
183 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200184 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200185
186 val->p = *p;
187 *p += val->len;
188
189 cur->next = NULL;
190
191 return( 0 );
192}
193
194/*
195 * RelativeDistinguishedName ::=
196 * SET OF AttributeTypeAndValue
197 *
198 * AttributeTypeAndValue ::= SEQUENCE {
199 * type AttributeType,
200 * value AttributeValue }
201 *
202 * AttributeType ::= OBJECT IDENTIFIER
203 *
204 * AttributeValue ::= ANY DEFINED BY AttributeType
205 */
206int x509_get_name( unsigned char **p, const unsigned char *end,
207 x509_name *cur )
208{
209 int ret;
210 size_t len;
211 const unsigned char *end2;
212 x509_name *use;
213
214 if( ( ret = asn1_get_tag( p, end, &len,
215 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200216 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200217
218 end2 = end;
219 end = *p + len;
220 use = cur;
221
222 do
223 {
224 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
225 return( ret );
226
227 if( *p != end )
228 {
229 use->next = (x509_name *) polarssl_malloc(
230 sizeof( x509_name ) );
231
232 if( use->next == NULL )
233 return( POLARSSL_ERR_X509_MALLOC_FAILED );
234
235 memset( use->next, 0, sizeof( x509_name ) );
236
237 use = use->next;
238 }
239 }
240 while( *p != end );
241
242 /*
243 * recurse until end of SEQUENCE is reached
244 */
245 if( *p == end2 )
246 return( 0 );
247
248 cur->next = (x509_name *) polarssl_malloc(
249 sizeof( x509_name ) );
250
251 if( cur->next == NULL )
252 return( POLARSSL_ERR_X509_MALLOC_FAILED );
253
254 memset( cur->next, 0, sizeof( x509_name ) );
255
256 return( x509_get_name( p, end2, cur->next ) );
257}
258
259/*
260 * Time ::= CHOICE {
261 * utcTime UTCTime,
262 * generalTime GeneralizedTime }
263 */
264int x509_get_time( unsigned char **p, const unsigned char *end,
265 x509_time *time )
266{
267 int ret;
268 size_t len;
269 char date[64];
270 unsigned char tag;
271
272 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200273 return( POLARSSL_ERR_X509_INVALID_DATE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200274 POLARSSL_ERR_ASN1_OUT_OF_DATA );
275
276 tag = **p;
277
278 if ( tag == ASN1_UTC_TIME )
279 {
280 (*p)++;
281 ret = asn1_get_len( p, end, &len );
Paul Bakker51876562013-09-17 14:36:05 +0200282
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200283 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200284 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200285
286 memset( date, 0, sizeof( date ) );
287 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
288 len : sizeof( date ) - 1 );
289
290 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
291 &time->year, &time->mon, &time->day,
292 &time->hour, &time->min, &time->sec ) < 5 )
Paul Bakker51876562013-09-17 14:36:05 +0200293 return( POLARSSL_ERR_X509_INVALID_DATE );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200294
295 time->year += 100 * ( time->year < 50 );
296 time->year += 1900;
297
298 *p += len;
299
300 return( 0 );
301 }
302 else if ( tag == ASN1_GENERALIZED_TIME )
303 {
304 (*p)++;
305 ret = asn1_get_len( p, end, &len );
Paul Bakker51876562013-09-17 14:36:05 +0200306
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200307 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200308 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200309
310 memset( date, 0, sizeof( date ) );
311 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
312 len : sizeof( date ) - 1 );
313
314 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
315 &time->year, &time->mon, &time->day,
316 &time->hour, &time->min, &time->sec ) < 5 )
Paul Bakker51876562013-09-17 14:36:05 +0200317 return( POLARSSL_ERR_X509_INVALID_DATE );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200318
319 *p += len;
320
321 return( 0 );
322 }
323 else
Paul Bakker51876562013-09-17 14:36:05 +0200324 return( POLARSSL_ERR_X509_INVALID_DATE +
325 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200326}
327
328int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
329{
330 int ret;
331 size_t len;
332
333 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200334 return( POLARSSL_ERR_X509_INVALID_SIGNATURE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200335 POLARSSL_ERR_ASN1_OUT_OF_DATA );
336
337 sig->tag = **p;
338
339 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200340 return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200341
342 sig->len = len;
343 sig->p = *p;
344
345 *p += len;
346
347 return( 0 );
348}
349
350int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
351 pk_type_t *pk_alg )
352{
353 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
354
355 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200356 return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200357
358 return( 0 );
359}
360
361/*
362 * X.509 Extensions (No parsing of extensions, pointer should
363 * be either manually updated or extensions should be parsed!
364 */
365int x509_get_ext( unsigned char **p, const unsigned char *end,
366 x509_buf *ext, int tag )
367{
368 int ret;
369 size_t len;
370
371 if( *p == end )
372 return( 0 );
373
374 ext->tag = **p;
375
376 if( ( ret = asn1_get_tag( p, end, &ext->len,
377 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
378 return( ret );
379
380 ext->p = *p;
381 end = *p + ext->len;
382
383 /*
384 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
385 *
386 * Extension ::= SEQUENCE {
387 * extnID OBJECT IDENTIFIER,
388 * critical BOOLEAN DEFAULT FALSE,
389 * extnValue OCTET STRING }
390 */
391 if( ( ret = asn1_get_tag( p, end, &len,
392 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200393 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200394
395 if( end != *p + len )
Paul Bakker51876562013-09-17 14:36:05 +0200396 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200397 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
398
399 return( 0 );
400}
401
402#if defined(POLARSSL_FS_IO)
403/*
404 * Load all data from a file into a given buffer.
405 */
406int x509_load_file( const char *path, unsigned char **buf, size_t *n )
407{
408 FILE *f;
409 long size;
410
411 if( ( f = fopen( path, "rb" ) ) == NULL )
412 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
413
414 fseek( f, 0, SEEK_END );
415 if( ( size = ftell( f ) ) == -1 )
416 {
417 fclose( f );
418 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
419 }
420 fseek( f, 0, SEEK_SET );
421
422 *n = (size_t) size;
423
424 if( *n + 1 == 0 ||
425 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
426 {
427 fclose( f );
428 return( POLARSSL_ERR_X509_MALLOC_FAILED );
429 }
430
431 if( fread( *buf, 1, *n, f ) != *n )
432 {
433 fclose( f );
434 polarssl_free( *buf );
435 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
436 }
437
438 fclose( f );
439
440 (*buf)[*n] = '\0';
441
442 return( 0 );
443}
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200444#endif /* POLARSSL_FS_IO */
445
Paul Bakker6edcd412013-10-29 15:22:54 +0100446#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
447 !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200448#include <stdarg.h>
449
450#if !defined vsnprintf
451#define vsnprintf _vsnprintf
452#endif // vsnprintf
453
454/*
455 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
456 * Result value is not size of buffer needed, but -1 if no fit is possible.
457 *
458 * This fuction tries to 'fix' this by at least suggesting enlarging the
459 * size by 20.
460 */
461static int compat_snprintf(char *str, size_t size, const char *format, ...)
462{
463 va_list ap;
464 int res = -1;
465
466 va_start( ap, format );
467
468 res = vsnprintf( str, size, format, ap );
469
470 va_end( ap );
471
472 // No quick fix possible
473 if ( res < 0 )
474 return( (int) size + 20 );
475
476 return res;
477}
478
479#define snprintf compat_snprintf
480#endif
481
482#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
483
484#define SAFE_SNPRINTF() \
485{ \
486 if( ret == -1 ) \
487 return( -1 ); \
488 \
489 if ( (unsigned int) ret > n ) { \
490 p[n - 1] = '\0'; \
491 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
492 } \
493 \
494 n -= (unsigned int) ret; \
495 p += (unsigned int) ret; \
496}
497
498/*
499 * Store the name in printable form into buf; no more
500 * than size characters will be written
501 */
Paul Bakker86d0c192013-09-18 11:11:02 +0200502int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200503{
504 int ret;
505 size_t i, n;
506 unsigned char c;
507 const x509_name *name;
508 const char *short_name = NULL;
509 char s[128], *p;
510
511 memset( s, 0, sizeof( s ) );
512
513 name = dn;
514 p = buf;
515 n = size;
516
517 while( name != NULL )
518 {
519 if( !name->oid.p )
520 {
521 name = name->next;
522 continue;
523 }
524
525 if( name != dn )
526 {
527 ret = snprintf( p, n, ", " );
528 SAFE_SNPRINTF();
529 }
530
531 ret = oid_get_attr_short_name( &name->oid, &short_name );
532
533 if( ret == 0 )
534 ret = snprintf( p, n, "%s=", short_name );
535 else
536 ret = snprintf( p, n, "\?\?=" );
537 SAFE_SNPRINTF();
538
539 for( i = 0; i < name->val.len; i++ )
540 {
541 if( i >= sizeof( s ) - 1 )
542 break;
543
544 c = name->val.p[i];
545 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
546 s[i] = '?';
547 else s[i] = c;
548 }
549 s[i] = '\0';
550 ret = snprintf( p, n, "%s", s );
551 SAFE_SNPRINTF();
552 name = name->next;
553 }
554
555 return( (int) ( size - n ) );
556}
557
558/*
559 * Store the serial in printable form into buf; no more
560 * than size characters will be written
561 */
Paul Bakker86d0c192013-09-18 11:11:02 +0200562int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200563{
564 int ret;
565 size_t i, n, nr;
566 char *p;
567
568 p = buf;
569 n = size;
570
571 nr = ( serial->len <= 32 )
572 ? serial->len : 28;
573
574 for( i = 0; i < nr; i++ )
575 {
576 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
577 continue;
578
579 ret = snprintf( p, n, "%02X%s",
580 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
581 SAFE_SNPRINTF();
582 }
583
584 if( nr != serial->len )
585 {
586 ret = snprintf( p, n, "...." );
587 SAFE_SNPRINTF();
588 }
589
590 return( (int) ( size - n ) );
591}
592
593/*
594 * Helper for writing "RSA key size", "EC key size", etc
595 */
596int x509_key_size_helper( char *buf, size_t size, const char *name )
597{
598 char *p = buf;
599 size_t n = size;
600 int ret;
601
602 if( strlen( name ) + sizeof( " key size" ) > size )
603 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;
604
605 ret = snprintf( p, n, "%s key size", name );
606 SAFE_SNPRINTF();
607
608 return( 0 );
609}
610
611/*
612 * Return an informational string describing the given OID
613 */
614const char *x509_oid_get_description( x509_buf *oid )
615{
616 const char *desc = NULL;
617 int ret;
618
619 ret = oid_get_extended_key_usage( oid, &desc );
620
621 if( ret != 0 )
622 return( NULL );
623
624 return( desc );
625}
626
627/* Return the x.y.z.... style numeric string for the given OID */
628int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
629{
630 return oid_get_numeric_string( buf, size, oid );
631}
632
633/*
634 * Return 0 if the x509_time is still valid, or 1 otherwise.
635 */
636#if defined(POLARSSL_HAVE_TIME)
Paul Bakker86d0c192013-09-18 11:11:02 +0200637int x509_time_expired( const x509_time *to )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200638{
639 int year, mon, day;
640 int hour, min, sec;
641
Paul Bakkerfa6a6202013-10-28 18:48:30 +0100642#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200643 SYSTEMTIME st;
644
645 GetLocalTime(&st);
646
647 year = st.wYear;
648 mon = st.wMonth;
649 day = st.wDay;
650 hour = st.wHour;
651 min = st.wMinute;
652 sec = st.wSecond;
653#else
654 struct tm *lt;
655 time_t tt;
656
657 tt = time( NULL );
658 lt = localtime( &tt );
659
660 year = lt->tm_year + 1900;
661 mon = lt->tm_mon + 1;
662 day = lt->tm_mday;
663 hour = lt->tm_hour;
664 min = lt->tm_min;
665 sec = lt->tm_sec;
666#endif
667
668 if( year > to->year )
669 return( 1 );
670
671 if( year == to->year &&
672 mon > to->mon )
673 return( 1 );
674
675 if( year == to->year &&
676 mon == to->mon &&
677 day > to->day )
678 return( 1 );
679
680 if( year == to->year &&
681 mon == to->mon &&
682 day == to->day &&
683 hour > to->hour )
684 return( 1 );
685
686 if( year == to->year &&
687 mon == to->mon &&
688 day == to->day &&
689 hour == to->hour &&
690 min > to->min )
691 return( 1 );
692
693 if( year == to->year &&
694 mon == to->mon &&
695 day == to->day &&
696 hour == to->hour &&
697 min == to->min &&
698 sec > to->sec )
699 return( 1 );
700
701 return( 0 );
702}
703#else /* POLARSSL_HAVE_TIME */
Paul Bakker86d0c192013-09-18 11:11:02 +0200704int x509_time_expired( const x509_time *to )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200705{
706 ((void) to);
707 return( 0 );
708}
709#endif /* POLARSSL_HAVE_TIME */
710
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200711#if defined(POLARSSL_SELF_TEST)
712
713#include "polarssl/x509_crt.h"
714#include "polarssl/certs.h"
715
716/*
717 * Checkup routine
718 */
719int x509_self_test( int verbose )
720{
721#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
722 int ret;
723 int flags;
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200724 x509_crt cacert;
725 x509_crt clicert;
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200726
727 if( verbose != 0 )
728 printf( " X.509 certificate load: " );
729
Paul Bakkerb6b09562013-09-18 14:17:41 +0200730 x509_crt_init( &clicert );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200731
Paul Bakkerddf26b42013-09-18 13:46:23 +0200732 ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
733 strlen( test_cli_crt ) );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200734 if( ret != 0 )
735 {
736 if( verbose != 0 )
737 printf( "failed\n" );
738
739 return( ret );
740 }
741
Paul Bakkerb6b09562013-09-18 14:17:41 +0200742 x509_crt_init( &cacert );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200743
Paul Bakkerddf26b42013-09-18 13:46:23 +0200744 ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
745 strlen( test_ca_crt ) );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200746 if( ret != 0 )
747 {
748 if( verbose != 0 )
749 printf( "failed\n" );
750
751 return( ret );
752 }
753
754 if( verbose != 0 )
755 printf( "passed\n X.509 signature verify: ");
756
Paul Bakkerddf26b42013-09-18 13:46:23 +0200757 ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200758 if( ret != 0 )
759 {
760 if( verbose != 0 )
761 printf( "failed\n" );
762
763 printf("ret = %d, &flags = %04x\n", ret, flags);
764
765 return( ret );
766 }
767
768 if( verbose != 0 )
769 printf( "passed\n\n");
770
771 x509_crt_free( &cacert );
772 x509_crt_free( &clicert );
773
774 return( 0 );
775#else
776 ((void) verbose);
777 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
778#endif
779}
780
781#endif
782
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200783#endif /* POLARSSL_X509_USE_C */