blob: 9c3b0f4aa36613c671e5ad59a207f16410f3bb74 [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
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
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#if defined(POLARSSL_PLATFORM_C)
49#include "polarssl/platform.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020050#else
Paul Bakker7dc4c442014-02-01 22:50:26 +010051#define polarssl_printf printf
Paul Bakker7c6b2c32013-09-16 13:49:26 +020052#define polarssl_malloc malloc
53#define polarssl_free free
54#endif
55
56#include <string.h>
57#include <stdlib.h>
Paul Bakkerfa6a6202013-10-28 18:48:30 +010058#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020059#include <windows.h>
60#else
61#include <time.h>
62#endif
63
Paul Bakkerfa6a6202013-10-28 18:48:30 +010064#if defined(EFIX64) || defined(EFI32)
65#include <stdio.h>
66#endif
67
Paul Bakker7c6b2c32013-09-16 13:49:26 +020068#if defined(POLARSSL_FS_IO)
69#include <stdio.h>
70#if !defined(_WIN32)
71#include <sys/types.h>
72#include <sys/stat.h>
73#include <dirent.h>
74#endif
75#endif
76
77/*
78 * CertificateSerialNumber ::= INTEGER
79 */
80int x509_get_serial( unsigned char **p, const unsigned char *end,
81 x509_buf *serial )
82{
83 int ret;
84
85 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +020086 return( POLARSSL_ERR_X509_INVALID_SERIAL +
Paul Bakker7c6b2c32013-09-16 13:49:26 +020087 POLARSSL_ERR_ASN1_OUT_OF_DATA );
88
89 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
90 **p != ASN1_INTEGER )
Paul Bakker51876562013-09-17 14:36:05 +020091 return( POLARSSL_ERR_X509_INVALID_SERIAL +
Paul Bakker7c6b2c32013-09-16 13:49:26 +020092 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
93
94 serial->tag = *(*p)++;
95
96 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +020097 return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +020098
99 serial->p = *p;
100 *p += serial->len;
101
102 return( 0 );
103}
104
105/* Get an algorithm identifier without parameters (eg for signatures)
106 *
107 * AlgorithmIdentifier ::= SEQUENCE {
108 * algorithm OBJECT IDENTIFIER,
109 * parameters ANY DEFINED BY algorithm OPTIONAL }
110 */
111int x509_get_alg_null( unsigned char **p, const unsigned char *end,
112 x509_buf *alg )
113{
114 int ret;
115
116 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200117 return( POLARSSL_ERR_X509_INVALID_ALG + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200118
119 return( 0 );
120}
121
122/*
123 * AttributeTypeAndValue ::= SEQUENCE {
124 * type AttributeType,
125 * value AttributeValue }
126 *
127 * AttributeType ::= OBJECT IDENTIFIER
128 *
129 * AttributeValue ::= ANY DEFINED BY AttributeType
130 */
131static int x509_get_attr_type_value( unsigned char **p,
132 const unsigned char *end,
133 x509_name *cur )
134{
135 int ret;
136 size_t len;
137 x509_buf *oid;
138 x509_buf *val;
139
140 if( ( ret = asn1_get_tag( p, end, &len,
141 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200142 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200143
144 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200145 return( POLARSSL_ERR_X509_INVALID_NAME +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200146 POLARSSL_ERR_ASN1_OUT_OF_DATA );
147
148 oid = &cur->oid;
149 oid->tag = **p;
150
151 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200152 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200153
154 oid->p = *p;
155 *p += oid->len;
156
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 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
162 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
163 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker51876562013-09-17 14:36:05 +0200164 return( POLARSSL_ERR_X509_INVALID_NAME +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200165 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
166
167 val = &cur->val;
168 val->tag = *(*p)++;
169
170 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200171 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200172
173 val->p = *p;
174 *p += val->len;
175
176 cur->next = NULL;
177
178 return( 0 );
179}
180
181/*
182 * RelativeDistinguishedName ::=
183 * SET OF AttributeTypeAndValue
184 *
185 * AttributeTypeAndValue ::= SEQUENCE {
186 * type AttributeType,
187 * value AttributeValue }
188 *
189 * AttributeType ::= OBJECT IDENTIFIER
190 *
191 * AttributeValue ::= ANY DEFINED BY AttributeType
192 */
193int x509_get_name( unsigned char **p, const unsigned char *end,
194 x509_name *cur )
195{
196 int ret;
197 size_t len;
198 const unsigned char *end2;
199 x509_name *use;
200
201 if( ( ret = asn1_get_tag( p, end, &len,
202 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200203 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200204
205 end2 = end;
206 end = *p + len;
207 use = cur;
208
209 do
210 {
211 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
212 return( ret );
213
214 if( *p != end )
215 {
216 use->next = (x509_name *) polarssl_malloc(
217 sizeof( x509_name ) );
218
219 if( use->next == NULL )
220 return( POLARSSL_ERR_X509_MALLOC_FAILED );
221
222 memset( use->next, 0, sizeof( x509_name ) );
223
224 use = use->next;
225 }
226 }
227 while( *p != end );
228
229 /*
230 * recurse until end of SEQUENCE is reached
231 */
232 if( *p == end2 )
233 return( 0 );
234
235 cur->next = (x509_name *) polarssl_malloc(
236 sizeof( x509_name ) );
237
238 if( cur->next == NULL )
239 return( POLARSSL_ERR_X509_MALLOC_FAILED );
240
241 memset( cur->next, 0, sizeof( x509_name ) );
242
243 return( x509_get_name( p, end2, cur->next ) );
244}
245
246/*
247 * Time ::= CHOICE {
248 * utcTime UTCTime,
249 * generalTime GeneralizedTime }
250 */
251int x509_get_time( unsigned char **p, const unsigned char *end,
252 x509_time *time )
253{
254 int ret;
255 size_t len;
256 char date[64];
257 unsigned char tag;
258
259 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200260 return( POLARSSL_ERR_X509_INVALID_DATE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200261 POLARSSL_ERR_ASN1_OUT_OF_DATA );
262
263 tag = **p;
264
265 if ( tag == ASN1_UTC_TIME )
266 {
267 (*p)++;
268 ret = asn1_get_len( p, end, &len );
Paul Bakker51876562013-09-17 14:36:05 +0200269
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200270 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200271 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200272
273 memset( date, 0, sizeof( date ) );
274 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
275 len : sizeof( date ) - 1 );
276
277 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
278 &time->year, &time->mon, &time->day,
279 &time->hour, &time->min, &time->sec ) < 5 )
Paul Bakker51876562013-09-17 14:36:05 +0200280 return( POLARSSL_ERR_X509_INVALID_DATE );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200281
282 time->year += 100 * ( time->year < 50 );
283 time->year += 1900;
284
285 *p += len;
286
287 return( 0 );
288 }
289 else if ( tag == ASN1_GENERALIZED_TIME )
290 {
291 (*p)++;
292 ret = asn1_get_len( p, end, &len );
Paul Bakker51876562013-09-17 14:36:05 +0200293
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200294 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200295 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200296
297 memset( date, 0, sizeof( date ) );
298 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
299 len : sizeof( date ) - 1 );
300
301 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
302 &time->year, &time->mon, &time->day,
303 &time->hour, &time->min, &time->sec ) < 5 )
Paul Bakker51876562013-09-17 14:36:05 +0200304 return( POLARSSL_ERR_X509_INVALID_DATE );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200305
306 *p += len;
307
308 return( 0 );
309 }
310 else
Paul Bakker51876562013-09-17 14:36:05 +0200311 return( POLARSSL_ERR_X509_INVALID_DATE +
312 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200313}
314
315int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
316{
317 int ret;
318 size_t len;
319
320 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200321 return( POLARSSL_ERR_X509_INVALID_SIGNATURE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200322 POLARSSL_ERR_ASN1_OUT_OF_DATA );
323
324 sig->tag = **p;
325
326 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200327 return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200328
329 sig->len = len;
330 sig->p = *p;
331
332 *p += len;
333
334 return( 0 );
335}
336
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100337int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
338 pk_type_t *pk_alg )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200339{
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100340 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200341
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100342 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200343 return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200344
345 return( 0 );
346}
347
348/*
349 * X.509 Extensions (No parsing of extensions, pointer should
350 * be either manually updated or extensions should be parsed!
351 */
352int x509_get_ext( unsigned char **p, const unsigned char *end,
353 x509_buf *ext, int tag )
354{
355 int ret;
356 size_t len;
357
358 if( *p == end )
359 return( 0 );
360
361 ext->tag = **p;
362
363 if( ( ret = asn1_get_tag( p, end, &ext->len,
364 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
365 return( ret );
366
367 ext->p = *p;
368 end = *p + ext->len;
369
370 /*
371 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
372 *
373 * Extension ::= SEQUENCE {
374 * extnID OBJECT IDENTIFIER,
375 * critical BOOLEAN DEFAULT FALSE,
376 * extnValue OCTET STRING }
377 */
378 if( ( ret = asn1_get_tag( p, end, &len,
379 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200380 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200381
382 if( end != *p + len )
Paul Bakker51876562013-09-17 14:36:05 +0200383 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200384 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
385
386 return( 0 );
387}
388
389#if defined(POLARSSL_FS_IO)
390/*
391 * Load all data from a file into a given buffer.
392 */
393int x509_load_file( const char *path, unsigned char **buf, size_t *n )
394{
395 FILE *f;
396 long size;
397
398 if( ( f = fopen( path, "rb" ) ) == NULL )
399 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
400
401 fseek( f, 0, SEEK_END );
402 if( ( size = ftell( f ) ) == -1 )
403 {
404 fclose( f );
405 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
406 }
407 fseek( f, 0, SEEK_SET );
408
409 *n = (size_t) size;
410
411 if( *n + 1 == 0 ||
412 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
413 {
414 fclose( f );
415 return( POLARSSL_ERR_X509_MALLOC_FAILED );
416 }
417
418 if( fread( *buf, 1, *n, f ) != *n )
419 {
420 fclose( f );
421 polarssl_free( *buf );
422 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
423 }
424
425 fclose( f );
426
427 (*buf)[*n] = '\0';
428
429 return( 0 );
430}
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200431#endif /* POLARSSL_FS_IO */
432
Paul Bakker6edcd412013-10-29 15:22:54 +0100433#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
434 !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200435#include <stdarg.h>
436
437#if !defined vsnprintf
438#define vsnprintf _vsnprintf
439#endif // vsnprintf
440
441/*
442 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
443 * Result value is not size of buffer needed, but -1 if no fit is possible.
444 *
445 * This fuction tries to 'fix' this by at least suggesting enlarging the
446 * size by 20.
447 */
448static int compat_snprintf(char *str, size_t size, const char *format, ...)
449{
450 va_list ap;
451 int res = -1;
452
453 va_start( ap, format );
454
455 res = vsnprintf( str, size, format, ap );
456
457 va_end( ap );
458
459 // No quick fix possible
460 if ( res < 0 )
461 return( (int) size + 20 );
462
463 return res;
464}
465
466#define snprintf compat_snprintf
467#endif
468
469#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
470
471#define SAFE_SNPRINTF() \
472{ \
473 if( ret == -1 ) \
474 return( -1 ); \
475 \
476 if ( (unsigned int) ret > n ) { \
477 p[n - 1] = '\0'; \
478 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
479 } \
480 \
481 n -= (unsigned int) ret; \
482 p += (unsigned int) ret; \
483}
484
485/*
486 * Store the name in printable form into buf; no more
487 * than size characters will be written
488 */
Paul Bakker86d0c192013-09-18 11:11:02 +0200489int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200490{
491 int ret;
492 size_t i, n;
493 unsigned char c;
494 const x509_name *name;
495 const char *short_name = NULL;
496 char s[128], *p;
497
498 memset( s, 0, sizeof( s ) );
499
500 name = dn;
501 p = buf;
502 n = size;
503
504 while( name != NULL )
505 {
506 if( !name->oid.p )
507 {
508 name = name->next;
509 continue;
510 }
511
512 if( name != dn )
513 {
514 ret = snprintf( p, n, ", " );
515 SAFE_SNPRINTF();
516 }
517
518 ret = oid_get_attr_short_name( &name->oid, &short_name );
519
520 if( ret == 0 )
521 ret = snprintf( p, n, "%s=", short_name );
522 else
523 ret = snprintf( p, n, "\?\?=" );
524 SAFE_SNPRINTF();
525
526 for( i = 0; i < name->val.len; i++ )
527 {
528 if( i >= sizeof( s ) - 1 )
529 break;
530
531 c = name->val.p[i];
532 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
533 s[i] = '?';
534 else s[i] = c;
535 }
536 s[i] = '\0';
537 ret = snprintf( p, n, "%s", s );
538 SAFE_SNPRINTF();
539 name = name->next;
540 }
541
542 return( (int) ( size - n ) );
543}
544
545/*
546 * Store the serial in printable form into buf; no more
547 * than size characters will be written
548 */
Paul Bakker86d0c192013-09-18 11:11:02 +0200549int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200550{
551 int ret;
552 size_t i, n, nr;
553 char *p;
554
555 p = buf;
556 n = size;
557
558 nr = ( serial->len <= 32 )
559 ? serial->len : 28;
560
561 for( i = 0; i < nr; i++ )
562 {
563 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
564 continue;
565
566 ret = snprintf( p, n, "%02X%s",
567 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
568 SAFE_SNPRINTF();
569 }
570
571 if( nr != serial->len )
572 {
573 ret = snprintf( p, n, "...." );
574 SAFE_SNPRINTF();
575 }
576
577 return( (int) ( size - n ) );
578}
579
580/*
581 * Helper for writing "RSA key size", "EC key size", etc
582 */
583int x509_key_size_helper( char *buf, size_t size, const char *name )
584{
585 char *p = buf;
586 size_t n = size;
587 int ret;
588
589 if( strlen( name ) + sizeof( " key size" ) > size )
590 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;
591
592 ret = snprintf( p, n, "%s key size", name );
593 SAFE_SNPRINTF();
594
595 return( 0 );
596}
597
598/*
599 * Return an informational string describing the given OID
600 */
601const char *x509_oid_get_description( x509_buf *oid )
602{
603 const char *desc = NULL;
604 int ret;
605
606 ret = oid_get_extended_key_usage( oid, &desc );
607
608 if( ret != 0 )
609 return( NULL );
610
611 return( desc );
612}
613
614/* Return the x.y.z.... style numeric string for the given OID */
615int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
616{
617 return oid_get_numeric_string( buf, size, oid );
618}
619
620/*
621 * Return 0 if the x509_time is still valid, or 1 otherwise.
622 */
623#if defined(POLARSSL_HAVE_TIME)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200624
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100625static void x509_get_current_time( x509_time *now )
626{
Paul Bakkerfa6a6202013-10-28 18:48:30 +0100627#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200628 SYSTEMTIME st;
629
630 GetLocalTime(&st);
631
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100632 now->year = st.wYear;
633 now->mon = st.wMonth;
634 now->day = st.wDay;
635 now->hour = st.wHour;
636 now->min = st.wMinute;
637 now->sec = st.wSecond;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200638#else
639 struct tm *lt;
640 time_t tt;
641
642 tt = time( NULL );
643 lt = localtime( &tt );
644
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100645 now->year = lt->tm_year + 1900;
646 now->mon = lt->tm_mon + 1;
647 now->day = lt->tm_mday;
648 now->hour = lt->tm_hour;
649 now->min = lt->tm_min;
650 now->sec = lt->tm_sec;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200651#endif
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100652}
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200653
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100654/*
655 * Return 0 if before <= after, 1 otherwise
656 */
657static int x509_check_time( const x509_time *before, const x509_time *after )
658{
659 if( before->year > after->year )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200660 return( 1 );
661
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100662 if( before->year == after->year &&
663 before->mon > after->mon )
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 &&
668 before->day > after->day )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200669 return( 1 );
670
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100671 if( before->year == after->year &&
672 before->mon == after->mon &&
673 before->day == after->day &&
674 before->hour > after->hour )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200675 return( 1 );
676
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100677 if( before->year == after->year &&
678 before->mon == after->mon &&
679 before->day == after->day &&
680 before->hour == after->hour &&
681 before->min > after->min )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200682 return( 1 );
683
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100684 if( before->year == after->year &&
685 before->mon == after->mon &&
686 before->day == after->day &&
687 before->hour == after->hour &&
688 before->min == after->min &&
689 before->sec > after->sec )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200690 return( 1 );
691
692 return( 0 );
693}
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100694
695int x509_time_expired( const x509_time *to )
696{
697 x509_time now;
698
699 x509_get_current_time( &now );
700
701 return( x509_check_time( &now, to ) );
702}
703
704int x509_time_future( const x509_time *from )
705{
706 x509_time now;
707
708 x509_get_current_time( &now );
709
710 return( x509_check_time( from, &now ) );
711}
712
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200713#else /* POLARSSL_HAVE_TIME */
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100714
Paul Bakker86d0c192013-09-18 11:11:02 +0200715int x509_time_expired( const x509_time *to )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200716{
717 ((void) to);
718 return( 0 );
719}
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100720
721int x509_time_future( const x509_time *from )
722{
723 ((void) from);
724 return( 0 );
725}
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200726#endif /* POLARSSL_HAVE_TIME */
727
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200728#if defined(POLARSSL_SELF_TEST)
729
730#include "polarssl/x509_crt.h"
731#include "polarssl/certs.h"
732
733/*
734 * Checkup routine
735 */
736int x509_self_test( int verbose )
737{
738#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
739 int ret;
740 int flags;
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200741 x509_crt cacert;
742 x509_crt clicert;
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200743
744 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100745 polarssl_printf( " X.509 certificate load: " );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200746
Paul Bakkerb6b09562013-09-18 14:17:41 +0200747 x509_crt_init( &clicert );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200748
Paul Bakkerddf26b42013-09-18 13:46:23 +0200749 ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
750 strlen( test_cli_crt ) );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200751 if( ret != 0 )
752 {
753 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100754 polarssl_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200755
756 return( ret );
757 }
758
Paul Bakkerb6b09562013-09-18 14:17:41 +0200759 x509_crt_init( &cacert );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200760
Paul Bakkerddf26b42013-09-18 13:46:23 +0200761 ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
762 strlen( test_ca_crt ) );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200763 if( ret != 0 )
764 {
765 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100766 polarssl_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200767
768 return( ret );
769 }
770
771 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100772 polarssl_printf( "passed\n X.509 signature verify: ");
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200773
Paul Bakkerddf26b42013-09-18 13:46:23 +0200774 ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200775 if( ret != 0 )
776 {
777 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100778 polarssl_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200779
Paul Bakker7dc4c442014-02-01 22:50:26 +0100780 polarssl_printf("ret = %d, &flags = %04x\n", ret, flags);
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200781
782 return( ret );
783 }
784
785 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100786 polarssl_printf( "passed\n\n");
Paul Bakkere9e6ae32013-09-16 22:53:25 +0200787
788 x509_crt_free( &cacert );
789 x509_crt_free( &clicert );
790
791 return( 0 );
792#else
793 ((void) verbose);
794 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
795#endif
796}
797
798#endif
799
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200800#endif /* POLARSSL_X509_USE_C */