From 9120018f3df6563920b1cafc60146e795d998818 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Thu, 18 Feb 2010 21:26:15 +0000 Subject: [PATCH] - Added support for GeneralizedTime in X509 certificates --- ChangeLog | 1 + include/polarssl/x509.h | 1 + library/x509parse.c | 76 ++++++++++++++++++-------- tests/suites/test_suite_x509parse.data | 5 +- 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 074e99dac..9302face1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ PolarSSL ChangeLog Changes * Added option parsing for host and port selection to ssl_client2 + * Added support for GeneralizedTime in X509 parsing Bug fixes * Fixed bug resulting in failure to send the last diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h index fbb1b6740..808f6deb6 100644 --- a/include/polarssl/x509.h +++ b/include/polarssl/x509.h @@ -92,6 +92,7 @@ #define ASN1_T61_STRING 0x14 #define ASN1_IA5_STRING 0x16 #define ASN1_UTC_TIME 0x17 +#define ASN1_GENERALIZED_TIME 0x18 #define ASN1_UNIVERSAL_STRING 0x1C #define ASN1_BMP_STRING 0x1E #define ASN1_PRIMITIVE 0x00 diff --git a/library/x509parse.c b/library/x509parse.c index 97a1755e3..430dab923 100644 --- a/library/x509parse.c +++ b/library/x509parse.c @@ -356,31 +356,66 @@ static int x509_get_name( unsigned char **p, * utcTime UTCTime, * generalTime GeneralizedTime } */ -static int x509_get_UTCTime( unsigned char **p, +static int x509_get_time( unsigned char **p, unsigned char *end, x509_time *time ) { int ret, len; char date[64]; + unsigned char tag; - if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret ); + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_OUT_OF_DATA ); - memset( date, 0, sizeof( date ) ); - memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ? - len : (int) sizeof( date ) - 1 ); + tag = **p; - if( sscanf( date, "%2d%2d%2d%2d%2d%2d", - &time->year, &time->mon, &time->day, - &time->hour, &time->min, &time->sec ) < 5 ) - return( POLARSSL_ERR_X509_CERT_INVALID_DATE ); + if ( tag == ASN1_UTC_TIME ) + { + (*p)++; + ret = asn1_get_len( p, end, &len ); + + if( ret != 0 ) + return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret ); - time->year += 100 * ( time->year < 90 ); - time->year += 1900; + memset( date, 0, sizeof( date ) ); + memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ? + len : (int) sizeof( date ) - 1 ); - *p += len; + if( sscanf( date, "%2d%2d%2d%2d%2d%2d", + &time->year, &time->mon, &time->day, + &time->hour, &time->min, &time->sec ) < 5 ) + return( POLARSSL_ERR_X509_CERT_INVALID_DATE ); - return( 0 ); + time->year += 100 * ( time->year < 90 ); + time->year += 1900; + + *p += len; + + return( 0 ); + } + else if ( tag == ASN1_GENERALIZED_TIME ) + { + (*p)++; + ret = asn1_get_len( p, end, &len ); + + if( ret != 0 ) + return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret ); + + memset( date, 0, sizeof( date ) ); + memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ? + len : (int) sizeof( date ) - 1 ); + + if( sscanf( date, "%4d%2d%2d%2d%2d%2d", + &time->year, &time->mon, &time->day, + &time->hour, &time->min, &time->sec ) < 5 ) + return( POLARSSL_ERR_X509_CERT_INVALID_DATE ); + + *p += len; + + return( 0 ); + } + else + return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); } @@ -402,13 +437,10 @@ static int x509_get_dates( unsigned char **p, end = *p + len; - /* - * TODO: also handle GeneralizedTime - */ - if( ( ret = x509_get_UTCTime( p, end, from ) ) != 0 ) + if( ( ret = x509_get_time( p, end, from ) ) != 0 ) return( ret ); - if( ( ret = x509_get_UTCTime( p, end, to ) ) != 0 ) + if( ( ret = x509_get_time( p, end, to ) ) != 0 ) return( ret ); if( *p != end ) @@ -742,7 +774,7 @@ static int x509_get_entries( unsigned char **p, if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 ) return( ret ); - if( ( ret = x509_get_UTCTime( p, end, &cur_entry->revocation_date ) ) != 0 ) + if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 ) return( ret ); if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 ) @@ -1320,13 +1352,13 @@ int x509parse_crl( x509_crl *chain, unsigned char *buf, int buflen ) * thisUpdate Time * nextUpdate Time OPTIONAL */ - if( ( ret = x509_get_UTCTime( &p, end, &crl->this_update ) ) != 0 ) + if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 ) { x509_crl_free( crl ); return( ret ); } - if( ( ret = x509_get_UTCTime( &p, end, &crl->next_update ) ) != 0 ) + if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 ) { if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) && diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index e565c07f1..898c52107 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -376,6 +376,9 @@ x509parse_crt:"308197308180a0030201008204deadbeef300d06092a864886f70d01010205003 X509 Certificate ASN1 (correct) x509parse_crt:"308196308180a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d0101020500030200ff":"cert. version \: 1\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ?\?=Test\nsubject name \: ?\?=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA+MD2\nRSA key size \: 128 bits\n":0 +X509 Certificate ASN1 (GeneralizedTime instead of UTCTime) +x509parse_crt:"308198308182a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301e180e3230313030313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d0101020500030200ff":"cert. version \: 1\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ?\?=Test\nsubject name \: ?\?=Test\nissued on \: 2010-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA+MD2\nRSA key size \: 128 bits\n":0 + X509 Certificate ASN1 (Name with X520 CN) x509parse_crt:"308199308183a0030201008204deadbeef300d06092a864886f70d0101020500300f310d300b0603550403130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d0101020500030200ff":"cert. version \: 1\nserial number \: DE\:AD\:BE\:EF\nissuer name \: CN=Test\nsubject name \: ?\?=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA+MD2\nRSA key size \: 128 bits\n":0 @@ -455,7 +458,7 @@ X509 CRL ASN1 (TBSCertList, entries present, invalid sig_alg) x509parse_crl:"304c3049a003020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd170c30383132333132333539353900":"":POLARSSL_ERR_X509_CERT_INVALID_ALG | POLARSSL_ERR_ASN1_UNEXPECTED_TAG X509 CRL ASN1 (TBSCertList, entries present, date in entry invalid) -x509parse_crl:"304c3049a003020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd180c30383132333132333539353900":"":POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG +x509parse_crl:"304c3049a003020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd190c30383132333132333539353900":"":POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG X509 CRL ASN1 (TBSCertList, sig_alg present, sig_alg does not match) x509parse_crl:"305a3049a003020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd170c303831323331323335393539300d06092a864886f70d01010d0500":"":POLARSSL_ERR_X509_CERT_SIG_MISMATCH