diff --git a/certs/crl/bad_time_fmt.pem b/certs/crl/bad_time_fmt.pem new file mode 100644 index 0000000000..589771d8f5 --- /dev/null +++ b/certs/crl/bad_time_fmt.pem @@ -0,0 +1,13 @@ +-----BEGIN X509 CRL----- +MIIB7DCB1QIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzELMAkGA1UE +CAwCVVMxCzAJBgNVBAcMAlVTMQswCQYDVQQKDAJVUzELMAkGA1UEAwwCVVMxCzAJ +BgNVBAsMAlVTGA0yNDAxMjMwMDAwMDBaGA0zNDAxMjAwMDAwMDBaMDUwMwIUHIAC +LvgfJAXulqYS3LYf4KxwHl4XDTI1MDMxMzAyNDQ0MFowDDAKBgNVHRUEAwoBBqAc +MBowGAYDVR0UBBECDxnP/97adO3y9qRGDM7hQDANBgkqhkiG9w0BAQsFAAOCAQEA +aDY9jBdAJiAujUkaLYLVtzNWF/0SxD5CB4dYIcZMqtPKLn5ykcxkXvnRbVihJ+Kn +AAv9Fkn5iwj77EGwxNjyZktQ4gAmcMhCTBEcAHbmi92tHttot9Sr44+CN+0NaaQD +OflIeVw7Zir90TWufjScy8/e7FkVm+aD5CicrbJWqoe21pB1Q1jS49iNrZzqZ2vw +HLiqNAzpecxwUih/YPe5+CBk5Nq4vICeieGVC/JO9r5SkdDwWQTl0I3kSK6n4Jh7 +53FmIen80F2ZZuZu4/fhJ7C4rlr6W9i6FrK06s5mk1PeYFHKhCkwI8wp8cIudJQD +lLsK2u4CTcuTKdbDLsszYA== +-----END X509 CRL----- diff --git a/certs/crl/include.am b/certs/crl/include.am index d3194933a4..6f7f6f26bf 100644 --- a/certs/crl/include.am +++ b/certs/crl/include.am @@ -16,7 +16,8 @@ EXTRA_DIST += \ certs/crl/wolfssl.cnf \ certs/crl/crl.der \ certs/crl/crl2.der \ - certs/crl/crl_rsapss.pem + certs/crl/crl_rsapss.pem \ + certs/crl/bad_time_fmt.pem EXTRA_DIST += \ certs/crl/crl.revoked \ diff --git a/src/x509.c b/src/x509.c index eda280e735..67e090ddb8 100644 --- a/src/x509.c +++ b/src/x509.c @@ -9046,13 +9046,10 @@ static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, } if (crl->crlList->lastDate[0] != 0) { - if (GetTimeString(crl->crlList->lastDate, ASN_UTC_TIME, + if (GetTimeString(crl->crlList->lastDate, crl->crlList->lastDateFormat, tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { - if (GetTimeString(crl->crlList->lastDate, ASN_GENERALIZED_TIME, - tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error getting last update date"); - return WOLFSSL_FAILURE; - } + WOLFSSL_MSG("Error getting last update date"); + return WOLFSSL_FAILURE; } } else { @@ -9077,13 +9074,10 @@ static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, } if (crl->crlList->nextDate[0] != 0) { - if (GetTimeString(crl->crlList->nextDate, ASN_UTC_TIME, + if (GetTimeString(crl->crlList->nextDate, crl->crlList->nextDateFormat, tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { - if (GetTimeString(crl->crlList->nextDate, ASN_GENERALIZED_TIME, - tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error getting next update date"); - return WOLFSSL_FAILURE; - } + WOLFSSL_MSG("Error getting next update date"); + return WOLFSSL_FAILURE; } } else { diff --git a/tests/api.c b/tests/api.c index e67f38f7d5..ce43607eb0 100644 --- a/tests/api.c +++ b/tests/api.c @@ -46392,10 +46392,25 @@ static int test_sk_X509_CRL(void) ExpectIntEQ(BIO_get_mem_data(bio, NULL), 1324); #endif BIO_free(bio); + bio = NULL; + wolfSSL_X509_CRL_free(crl); + crl = NULL; + +#ifndef NO_ASN_TIME + /* Test CRL with invalid GeneralizedTime */ + ExpectNotNull(bio = BIO_new_file("./certs/crl/bad_time_fmt.pem", "rb")); + ExpectNotNull(crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)); + BIO_free(bio); + bio = NULL; + ExpectNotNull(bio = BIO_new(BIO_s_mem())); + ExpectIntEQ(wolfSSL_X509_CRL_print(bio, crl), WOLFSSL_FAILURE); + BIO_free(bio); + bio = NULL; wolfSSL_X509_CRL_free(crl); crl = NULL; -#endif +#endif /* !NO_ASN_TIME */ +#endif /* !NO_BIO */ #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) ExpectTrue((fp = XFOPEN("./certs/crl/crl.der", "rb")) != XBADFILE); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 30afd46e55..be89ec618c 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15984,6 +15984,28 @@ static WC_INLINE int GetTime_Long(long* value, const byte* date, int* idx) int ExtractDate(const unsigned char* date, unsigned char format, struct tm* certTime, int* idx) { + int i = *idx; + + /* Validate date string length based on format. Can not assume null + * terminated strings. Must check for the 'Z'. + * Subtract 2; one for zero indexing and one to exclude null terminator + * built into macro values. */ + if (format == ASN_UTC_TIME) { + /* UTCTime format requires YYMMDDHHMMSSZ. */ + if (date[i + ASN_UTC_TIME_SIZE - 2] != 'Z') { + return 0; + } + } + else if (format == ASN_GENERALIZED_TIME) { + /* GeneralizedTime format requires YYYYMMDDHHMMSSZ. */ + if (date[ i + ASN_GENERALIZED_TIME_SIZE - 2] != 'Z') { + return 0; + } + } + else { + return 0; + } + XMEMSET(certTime, 0, sizeof(struct tm)); /* Get the first two bytes of the year (century) */