From d90394efa68bfbefaee997061b1a5d570c192b32 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 11 Jul 2025 11:25:25 -0500 Subject: [PATCH] wolfcrypt/src/asn.c and wolfssl/wolfcrypt/asn.h: add WC_ASN_RUNTIME_DATE_CHECK_CONTROL, with accessors wc_AsnSetSkipDateCheck() (WOLFSSL_TEST_VIS) and wc_AsnGetSkipDateCheck() (WOLFSSL_LOCAL). use this to permafix test_wolfSSL_CRL_duplicate_extensions() in api.c, which has an expiring-soon handcrafted certificate in it. --- .wolfssl_known_macro_extras | 1 + tests/api.c | 7 ++++- wolfcrypt/src/asn.c | 59 ++++++++++++++++++++++++++++++------- wolfssl/wolfcrypt/asn.h | 2 ++ 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 2eb737945..ca4b5615b 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -558,6 +558,7 @@ WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING WC_AES_BS_WORD_SIZE WC_AES_GCM_DEC_AUTH_EARLY WC_ASN_HASH_SHA256 +WC_ASN_RUNTIME_DATE_CHECK_CONTROL WC_ASYNC_ENABLE_3DES WC_ASYNC_ENABLE_AES WC_ASYNC_ENABLE_ARC4 diff --git a/tests/api.c b/tests/api.c index 49b6f4634..fc0001fad 100644 --- a/tests/api.c +++ b/tests/api.c @@ -4261,7 +4261,8 @@ static int test_wolfSSL_CRL_duplicate_extensions(void) { EXPECT_DECLS; #if defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_CERTS) && \ - defined(HAVE_CRL) && !defined(NO_RSA) && !defined(WOLFSSL_NO_ASN_STRICT) + defined(HAVE_CRL) && !defined(NO_RSA) && !defined(WOLFSSL_NO_ASN_STRICT) && \ + (defined(WC_ASN_RUNTIME_DATE_CHECK_CONTROL) || defined(NO_ASN_TIME_CHECK)) const unsigned char crl_duplicate_akd[] = "-----BEGIN X509 CRL-----\n" "MIICCDCB8QIBATANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJVUzETMBEGA1UE\n" @@ -4280,6 +4281,8 @@ static int test_wolfSSL_CRL_duplicate_extensions(void) WOLFSSL_CERT_MANAGER* cm = NULL; int ret; + (void)wc_AsnSetSkipDateCheck(1); + cm = wolfSSL_CertManagerNew(); ExpectNotNull(cm); @@ -4291,6 +4294,8 @@ static int test_wolfSSL_CRL_duplicate_extensions(void) ExpectIntEQ(ret, ASN_PARSE_E); wolfSSL_CertManagerFree(cm); + + (void)wc_AsnSetSkipDateCheck(0); #endif return EXPECT_RESULT(); } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6dba89f9a..8db0caccd 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -359,6 +359,30 @@ WOLFSSL_LOCAL word32 SetASNLength(word32 length, byte* output) return i; } +#ifdef WC_ASN_RUNTIME_DATE_CHECK_CONTROL +static int AsnSkipDateCheck = 0; +int wc_AsnSetSkipDateCheck(int skip_p) +{ + AsnSkipDateCheck = (skip_p != 0); + return 0; +} +int wc_AsnGetSkipDateCheck(void) +{ + return AsnSkipDateCheck; +} +#else +#define AsnSkipDateCheck 0 +int wc_AsnSetSkipDateCheck(int skip_p) +{ + (void)skip_p; + return NOT_COMPILED_IN; +} +int wc_AsnGetSkipDateCheck(void) +{ + return 0; +} +#endif + #ifdef WOLFSSL_ASN_TEMPLATE /* Calculate the size of a DER encoded length value. * @@ -16848,6 +16872,7 @@ static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx) #ifndef NO_ASN_TIME_CHECK if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE && + (! AsnSkipDateCheck) && !XVALIDATE_DATE(date, format, dateType)) { if (dateType == ASN_BEFORE) { WOLFSSL_ERROR_VERBOSE(ASN_BEFORE_DATE_E); @@ -23301,7 +23326,7 @@ static int CheckDate(ASNGetData *dataASN, int dateType) #ifndef NO_ASN_TIME_CHECK /* Check date is a valid string and ASN_BEFORE or ASN_AFTER now. */ - if (ret == 0) { + if ((ret == 0) && (! AsnSkipDateCheck)) { if (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType)) { if (dateType == ASN_BEFORE) { ret = ASN_BEFORE_DATE_E; @@ -23480,7 +23505,7 @@ static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt, ? X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC : X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT; if ((CheckDate(&dataASN[i], ASN_BEFORE) < 0) && (verify != NO_VERIFY) && - (verify != VERIFY_SKIP_DATE)) { + (verify != VERIFY_SKIP_DATE) && (! AsnSkipDateCheck)) { badDate = ASN_BEFORE_DATE_E; } /* Store reference to ASN_BEFORE date. */ @@ -23492,7 +23517,7 @@ static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt, ? X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC : X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT; if ((CheckDate(&dataASN[i], ASN_AFTER) < 0) && (verify != NO_VERIFY) && - (verify != VERIFY_SKIP_DATE)) { + (verify != VERIFY_SKIP_DATE) && (! AsnSkipDateCheck)) { badDate = ASN_AFTER_DATE_E; } /* Store reference to ASN_AFTER date. */ @@ -25117,7 +25142,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, if (ret == WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) || ret == WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) { cert->badDate = ret; - if (verify == VERIFY_SKIP_DATE) + if ((verify == VERIFY_SKIP_DATE) || AsnSkipDateCheck) ret = 0; } else @@ -25368,7 +25393,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, if (ret == WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) || ret == WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) { cert->badDate = ret; - if (verify == VERIFY_SKIP_DATE) + if ((verify == VERIFY_SKIP_DATE) || AsnSkipDateCheck) ret = 0; } else if (ret < 0) { @@ -38154,7 +38179,7 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, #ifndef NO_ASN_TIME_CHECK #ifndef WOLFSSL_NO_OCSP_DATE_CHECK - if (!XVALIDATE_DATE(single->status->thisDate, + if ((! AsnSkipDateCheck) && !XVALIDATE_DATE(single->status->thisDate, single->status->thisDateFormat, ASN_BEFORE)) return ASN_BEFORE_DATE_E; #endif @@ -38191,7 +38216,9 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, #ifndef NO_ASN_TIME_CHECK #ifndef WOLFSSL_NO_OCSP_DATE_CHECK - if (!XVALIDATE_DATE(single->status->nextDate, single->status->nextDateFormat, ASN_AFTER)) + if ((! AsnSkipDateCheck) && + !XVALIDATE_DATE(single->status->nextDate, + single->status->nextDateFormat, ASN_AFTER)) return ASN_AFTER_DATE_E; #endif #endif @@ -38264,7 +38291,9 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, cs->thisDateFormat = ASN_GENERALIZED_TIME; #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK) /* Check date is a valid string and ASN_BEFORE now. */ - if (!XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, ASN_BEFORE)) { + if ((! AsnSkipDateCheck) && + !XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, ASN_BEFORE)) + { ret = ASN_BEFORE_DATE_E; } #endif /* !NO_ASN_TIME_CHECK && !WOLFSSL_NO_OCSP_DATE_CHECK */ @@ -38287,7 +38316,9 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, cs->nextDateFormat = ASN_GENERALIZED_TIME; #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK) /* Check date is a valid string and ASN_AFTER now. */ - if (!XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, ASN_AFTER)) { + if ((! AsnSkipDateCheck) && + !XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, ASN_AFTER)) + { ret = ASN_AFTER_DATE_E; } #endif /* !NO_ASN_TIME_CHECK && !WOLFSSL_NO_OCSP_DATE_CHECK */ @@ -40373,6 +40404,7 @@ static int ParseCRL_CertList(RevokedCert* rcert, DecodedCRL* dcrl, { #if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_CRL_DATE_CHECK) if (verify != NO_VERIFY && + (! AsnSkipDateCheck) && !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) { WOLFSSL_MSG("CRL after date is no longer valid"); WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR); @@ -41034,6 +41066,7 @@ end: if (dcrl->nextDateFormat != 0) { /* Next date was set, so validate it. */ if (verify != NO_VERIFY && + (! AsnSkipDateCheck) && !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) { WOLFSSL_MSG("CRL after date is no longer valid"); ret = CRL_CERT_DATE_ERR; @@ -43247,7 +43280,9 @@ int ParseX509Acert(DecodedAcert* acert, int verify) /* check BEFORE date. */ idx = ACERT_IDX_ACINFO_VALIDITY_NOTB_GT; if (CheckDate(&dataASN[idx], BEFORE) < 0) { - if ((verify != NO_VERIFY) && (verify != VERIFY_SKIP_DATE)) { + if ((verify != NO_VERIFY) && (verify != VERIFY_SKIP_DATE) && + (! AsnSkipDateCheck)) + { badDate = ASN_BEFORE_DATE_E; } } @@ -43259,7 +43294,9 @@ int ParseX509Acert(DecodedAcert* acert, int verify) /* check AFTER date. */ idx = ACERT_IDX_ACINFO_VALIDITY_NOTA_GT; if (CheckDate(&dataASN[idx], AFTER) < 0) { - if ((verify != NO_VERIFY) && (verify != VERIFY_SKIP_DATE)) { + if ((verify != NO_VERIFY) && (verify != VERIFY_SKIP_DATE) && + (! AsnSkipDateCheck)) + { badDate = ASN_BEFORE_DATE_E; } } diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 7937351a9..afbd41cfe 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2193,6 +2193,8 @@ WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format, wolfssl_tm* certTime, int* idx); WOLFSSL_LOCAL int DateGreaterThan(const struct tm* a, const struct tm* b); WOLFSSL_LOCAL int wc_ValidateDate(const byte* date, byte format, int dateType); +WOLFSSL_TEST_VIS int wc_AsnSetSkipDateCheck(int skip_p); +WOLFSSL_LOCAL int wc_AsnGetSkipDateCheck(void); /* ASN.1 helper functions */ #ifdef WOLFSSL_CERT_GEN