- Added support for GeneralizedTime in X509 certificates

diff --git a/ChangeLog b/ChangeLog
index 074e99d..9302fac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@
 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 fbb1b67..808f6de 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 97a1755..430dab9 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -356,31 +356,66 @@
  *       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 @@
 
     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 @@
         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 @@
      * 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 e565c07..898c521 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -376,6 +376,9 @@
 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 @@
 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