Properly ASN.1 encode dates in certificates depending on the year.
authorTobias Brunner <tobias@strongswan.org>
Fri, 23 Dec 2011 15:29:41 +0000 (16:29 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 23 Dec 2011 15:29:41 +0000 (16:29 +0100)
src/libstrongswan/asn1/asn1.c
src/libstrongswan/asn1/asn1.h
src/libstrongswan/crypto/pkcs7.c
src/libstrongswan/plugins/x509/x509_ac.c
src/libstrongswan/plugins/x509/x509_cert.c
src/libstrongswan/plugins/x509/x509_crl.c

index 96bf50a..e74edde 100644 (file)
@@ -426,8 +426,9 @@ time_t asn1_to_time(const chunk_t *utctime, asn1_t type)
 /**
  *  Convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
  */
-chunk_t asn1_from_time(const time_t *time, asn1_t type)
+chunk_t asn1_from_time(const time_t *time)
 {
+       asn1_t type;
        int offset;
        const char *format;
        char buf[BUF_LEN];
@@ -435,6 +436,9 @@ chunk_t asn1_from_time(const time_t *time, asn1_t type)
        struct tm t;
 
        gmtime_r(time, &t);
+       /* RFC 5280 says that dates through the year 2049 MUST be encoded as UTCTIME
+        * and dates in 2050 or later MUST be encoded as GENERALIZEDTIME */
+       type = (t.tm_year < 150) ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME;
        if (type == ASN1_GENERALIZEDTIME)
        {
                format = "%04d%02d%02d%02d%02d%02dZ";
@@ -443,7 +447,7 @@ chunk_t asn1_from_time(const time_t *time, asn1_t type)
        else /* ASN1_UTCTIME */
        {
                format = "%02d%02d%02d%02d%02d%02dZ";
-               offset = (t.tm_year < 100)? 0 : -100;
+               offset = (t.tm_year < 100) ? 0 : -100;
        }
        snprintf(buf, BUF_LEN, format, t.tm_year + offset,
                         t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
index 05a0608..d5468a4 100644 (file)
@@ -35,8 +35,8 @@ typedef enum {
        ASN1_BOOLEAN =                  0x01,
        ASN1_INTEGER =                  0x02,
        ASN1_BIT_STRING =               0x03,
-       ASN1_OCTET_STRING =     0x04,
-       ASN1_NULL =                     0x05,
+       ASN1_OCTET_STRING =             0x04,
+       ASN1_NULL =                             0x05,
        ASN1_OID =                              0x06,
        ASN1_ENUMERATED =               0x0A,
        ASN1_UTF8STRING =               0x0C,
@@ -48,7 +48,7 @@ typedef enum {
        ASN1_UTCTIME =                  0x17,
        ASN1_GENERALIZEDTIME =  0x18,
        ASN1_GRAPHICSTRING =    0x19,
-       ASN1_VISIBLESTRING =    0x1A,
+       ASN1_VISIBLESTRING =    0x1A,
        ASN1_GENERALSTRING =    0x1B,
        ASN1_UNIVERSALSTRING =  0x1C,
        ASN1_BMPSTRING =                0x1E,
@@ -75,7 +75,7 @@ typedef enum {
        ASN1_CONTEXT_C_4 =              0xA4,
        ASN1_CONTEXT_C_5 =              0xA5,
 
-       ASN1_INVALID =                  0x100,
+       ASN1_INVALID =                  0x100,
 } asn1_t;
 
 #define ASN1_INVALID_LENGTH    0xffffffff
@@ -191,11 +191,12 @@ time_t asn1_to_time(const chunk_t *utctime, asn1_t type);
 /**
  * Converts time_t to an ASN.1 UTCTIME or GENERALIZEDTIME string
  *
+ * The type is automatically chosen based on the encoded year.
+ *
  * @param time         time_t in UTC
- * @param type         ASN1_UTCTIME or ASN1_GENERALIZEDTIME
  * @return                     body of an ASN.1 code time object
  */
-chunk_t asn1_from_time(const time_t *time, asn1_t type);
+chunk_t asn1_from_time(const time_t *time);
 
 /**
  * Parse an ASN.1 UTCTIME or GENERALIZEDTIME object
index 2593d8b..578021a 100644 (file)
@@ -825,7 +825,7 @@ METHOD(pkcs7_t, build_signedData, bool,
 
                        /* take the current time as signingTime */
                        time_t now = time(NULL);
-                       chunk_t signingTime = asn1_from_time(&now, ASN1_UTCTIME);
+                       chunk_t signingTime = asn1_from_time(&now);
 
                        chunk_t messageDigest, attributes;
 
index d9b0b62..7492aeb 100644 (file)
@@ -527,8 +527,8 @@ static chunk_t build_v2_form(private_x509_ac_t *this)
 static chunk_t build_attr_cert_validity(private_x509_ac_t *this)
 {
        return asn1_wrap(ASN1_SEQUENCE, "mm",
-                               asn1_from_time(&this->notBefore, ASN1_GENERALIZEDTIME),
-                               asn1_from_time(&this->notAfter,  ASN1_GENERALIZEDTIME));
+                               asn1_from_time(&this->notBefore),
+                               asn1_from_time(&this->notAfter));
 }
 
 
index f828c92..25646a7 100644 (file)
@@ -2316,8 +2316,8 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
                asn1_algorithmIdentifier(cert->algorithm),
                issuer->get_encoding(issuer),
                asn1_wrap(ASN1_SEQUENCE, "mm",
-                       asn1_from_time(&cert->notBefore, ASN1_UTCTIME),
-                       asn1_from_time(&cert->notAfter, ASN1_UTCTIME)),
+                       asn1_from_time(&cert->notBefore),
+                       asn1_from_time(&cert->notAfter)),
                subject->get_encoding(subject),
                key_info, extensions);
 
index 7bcca16..f401413 100644 (file)
@@ -736,7 +736,7 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
                }
                revoked = asn1_wrap(ASN1_SEQUENCE, "mmm",
                                                        asn1_integer("c", serial),
-                                                       asn1_from_time(&date, ASN1_UTCTIME),
+                                                       asn1_from_time(&date),
                                                        entry_ext);
                certList = chunk_cat("mm", certList, revoked);
        }
@@ -773,8 +773,8 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
                                                        ASN1_INTEGER_1,
                                                        asn1_algorithmIdentifier(this->algorithm),
                                                        this->issuer->get_encoding(this->issuer),
-                                                       asn1_from_time(&this->thisUpdate, ASN1_UTCTIME),
-                                                       asn1_from_time(&this->nextUpdate, ASN1_UTCTIME),
+                                                       asn1_from_time(&this->thisUpdate),
+                                                       asn1_from_time(&this->nextUpdate),
                                                        asn1_wrap(ASN1_SEQUENCE, "m", certList),
                                                        extensions);