From 9b04dbc05785e452a5f5a7f01b2b3c23c8b2994d Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Thu, 27 Mar 2025 20:35:20 -0400 Subject: [PATCH 1/8] Validate asn date based on string length --- wolfcrypt/src/asn.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e64f278922..6e7553d4c2 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -16273,6 +16273,26 @@ 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 */ + if (format == ASN_UTC_TIME) { + /* UTCTime format requires YYMMDDHHMMSSZ. + * subtract 1 to exclude null terminator. */ + if (XSTRLEN((const char*)date + i) < (ASN_UTC_TIME_SIZE - 1)) { + return ASN_PARSE_E; + } + } + else if (format == ASN_GENERALIZED_TIME) { + /* GeneralizedTime format requires YYYYMMDDHHMMSSZ. + * subtract 1 to exclude null terminator. */ + if (XSTRLEN((const char*)date + i) < (ASN_GENERALIZED_TIME_SIZE - 1)) { + return ASN_PARSE_E; + } + } else { + return ASN_PARSE_E; + } + XMEMSET(certTime, 0, sizeof(struct tm)); /* Get the first two bytes of the year (century) */ From 87bff471c1159e84dad81218a6df31f0b2f34ab9 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Fri, 28 Mar 2025 17:52:46 -0400 Subject: [PATCH 2/8] Stop assuming dates are NULL terminated --- wolfcrypt/src/asn.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6e7553d4c2..62afbfbcbe 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -16275,22 +16275,22 @@ int ExtractDate(const unsigned char* date, unsigned char format, { int i = *idx; - /* Validate date string length based on format */ + /* 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. - * subtract 1 to exclude null terminator. */ - if (XSTRLEN((const char*)date + i) < (ASN_UTC_TIME_SIZE - 1)) { - return ASN_PARSE_E; + /* 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. - * subtract 1 to exclude null terminator. */ - if (XSTRLEN((const char*)date + i) < (ASN_GENERALIZED_TIME_SIZE - 1)) { - return ASN_PARSE_E; + /* GeneralizedTime format requires YYYYMMDDHHMMSSZ. */ + if (date[ i + ASN_GENERALIZED_TIME_SIZE - 2] != 'Z') { + return 0; } } else { - return ASN_PARSE_E; + return 0; } XMEMSET(certTime, 0, sizeof(struct tm)); From 551e85f4003be63a703fe4b7e7dd09bf42e37472 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Fri, 4 Apr 2025 10:47:14 -0400 Subject: [PATCH 3/8] Comment fixup --- wolfcrypt/src/asn.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 62afbfbcbe..8a6c9d8f17 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -16275,9 +16275,10 @@ int ExtractDate(const unsigned char* date, unsigned char format, { 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 */ + /* 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') { From d4bdadbaa333a1c5aef0af50cf3317143ac11714 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Fri, 4 Apr 2025 10:49:09 -0400 Subject: [PATCH 4/8] Drop else --- wolfcrypt/src/asn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 8a6c9d8f17..c5d86d0eac 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -16290,7 +16290,8 @@ int ExtractDate(const unsigned char* date, unsigned char format, if (date[ i + ASN_GENERALIZED_TIME_SIZE - 2] != 'Z') { return 0; } - } else { + } + else { return 0; } From c0e0b104a58cdf579cb8f52307483b6967533197 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Tue, 22 Apr 2025 15:02:08 -0400 Subject: [PATCH 5/8] add a test --- certs/crl/bad_time_fmt.pem | 13 +++++++++++++ tests/api.c | 10 +++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 certs/crl/bad_time_fmt.pem 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/tests/api.c b/tests/api.c index 10631d5e9b..70c7de348b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -27601,9 +27601,17 @@ 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")); + ExpectNull(crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)); + BIO_free(bio); + bio = NULL; + #endif /* NO_ASN_TIME */ #endif #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) From 7079d4160716a7a83270cf13579ad1d8e4bb6f7d Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Mon, 12 May 2025 15:50:37 -0400 Subject: [PATCH 6/8] squash me --- src/x509.c | 18 ++++++------------ tests/api.c | 13 ++++++++++--- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/x509.c b/src/x509.c index 8fc94f5f1d..cdac8ca8a8 100644 --- a/src/x509.c +++ b/src/x509.c @@ -9071,13 +9071,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 { @@ -9102,13 +9099,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 70c7de348b..c96d373b38 100644 --- a/tests/api.c +++ b/tests/api.c @@ -27608,11 +27608,18 @@ static int test_sk_X509_CRL(void) #ifndef NO_ASN_TIME /* Test CRL with invalid GeneralizedTime */ ExpectNotNull(bio = BIO_new_file("./certs/crl/bad_time_fmt.pem", "rb")); - ExpectNull(crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)); + ExpectNotNull(crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)); BIO_free(bio); bio = NULL; - #endif /* NO_ASN_TIME */ -#endif + 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 /* !NO_ASN_TIME */ +#endif /* !NO_BIO */ #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) ExpectTrue((fp = XFOPEN("./certs/crl/crl.der", "rb")) != XBADFILE); From 0fe54babe673b1d5edfc37e652d9472e4432fd3e Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Mon, 12 May 2025 16:23:09 -0400 Subject: [PATCH 7/8] Added a new file; added to include.am --- certs/crl/include.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 \ From 8b8eed82cfd839516ae83421dc35c9a07041adc4 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Wed, 24 Dec 2025 16:53:14 -0500 Subject: [PATCH 8/8] Rebase and refactor to pass in length for bounds checking. --- src/crl.c | 3 ++- src/ocsp.c | 4 +-- src/ssl.c | 3 ++- src/ssl_asn1.c | 2 +- src/x509.c | 16 ++++++------ src/x509_str.c | 10 +++++--- wolfcrypt/src/asn.c | 49 +++++++++++++++++++++++-------------- wolfssl/wolfcrypt/asn.h | 10 +++++--- wolfssl/wolfcrypt/wc_port.h | 2 +- 9 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/crl.c b/src/crl.c index 9056bd1c6c..8b3e319ffc 100644 --- a/src/crl.c +++ b/src/crl.c @@ -446,7 +446,8 @@ static int CheckCertCRLList(WOLFSSL_CRL* crl, byte* issuerHash, byte* serial, #endif { #if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_CRL_DATE_CHECK) - if (!XVALIDATE_DATE(crle->nextDate,crle->nextDateFormat, ASN_AFTER)) { + if (!XVALIDATE_DATE(crle->nextDate, crle->nextDateFormat, + ASN_AFTER, MAX_DATE_SIZE)) { WOLFSSL_MSG("CRL next date is no longer valid"); nextDateValid = 0; } diff --git a/src/ocsp.c b/src/ocsp.c index 2348af7df1..77cce2b1a7 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -296,10 +296,10 @@ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request, else if (*status) { #ifndef NO_ASN_TIME if (XVALIDATE_DATE((*status)->thisDate, - (*status)->thisDateFormat, ASN_BEFORE) + (*status)->thisDateFormat, ASN_BEFORE, MAX_DATE_SIZE) && ((*status)->nextDate[0] != 0) && XVALIDATE_DATE((*status)->nextDate, - (*status)->nextDateFormat, ASN_AFTER)) + (*status)->nextDateFormat, ASN_AFTER, MAX_DATE_SIZE)) #endif { ret = xstat2err((*status)->status); diff --git a/src/ssl.c b/src/ssl.c index 0d265f999a..c71b188ac8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -22021,7 +22021,8 @@ int wolfSSL_get_ocsp_producedDate_tm(WOLFSSL *ssl, struct tm *produced_tm) { return BAD_FUNC_ARG; if (ExtractDate(ssl->ocspProducedDate, - (unsigned char)ssl->ocspProducedDateFormat, produced_tm, &idx)) + (unsigned char)ssl->ocspProducedDateFormat, produced_tm, &idx, + MAX_DATE_SZ)) return 0; else return ASN_PARSE_E; diff --git a/src/ssl_asn1.c b/src/ssl_asn1.c index d501b6a681..2fe3cab470 100644 --- a/src/ssl_asn1.c +++ b/src/ssl_asn1.c @@ -4194,7 +4194,7 @@ char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len) } /* Get time as human readable string. */ - if ((buf != NULL) && !GetTimeString(t->data, t->type, buf, len)) { + if ((buf != NULL) && !GetTimeString(t->data, t->type, buf, len, t->length)) { buf = NULL; } diff --git a/src/x509.c b/src/x509.c index cdac8ca8a8..5efc5fe0cd 100644 --- a/src/x509.c +++ b/src/x509.c @@ -6440,9 +6440,9 @@ static int X509PrintValidity(WOLFSSL_BIO* bio, WOLFSSL_ASN1_TIME * notBefore, } if (notBefore->length > 0) { if (GetTimeString(notBefore->data, ASN_UTC_TIME, - tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) { + tmp, sizeof(tmp), notBefore->length) != WOLFSSL_SUCCESS) { if (GetTimeString(notBefore->data, ASN_GENERALIZED_TIME, - tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) { + tmp, sizeof(tmp), notBefore->length) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error getting not before date"); return WOLFSSL_FAILURE; } @@ -6462,9 +6462,9 @@ static int X509PrintValidity(WOLFSSL_BIO* bio, WOLFSSL_ASN1_TIME * notBefore, } if (notAfter->length > 0) { if (GetTimeString(notAfter->data, ASN_UTC_TIME, - tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) { + tmp, sizeof(tmp), notAfter->length) != WOLFSSL_SUCCESS) { if (GetTimeString(notAfter->data, ASN_GENERALIZED_TIME, - tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) { + tmp, sizeof(tmp), notAfter->length) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error getting not after date"); return WOLFSSL_FAILURE; } @@ -9018,9 +9018,9 @@ static int X509CRLPrintRevoked(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, if (revoked->revDate[0] != 0) { if (GetTimeString(revoked->revDate, ASN_UTC_TIME, - tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) { if (GetTimeString(revoked->revDate, ASN_GENERALIZED_TIME, - tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error getting revocation date"); return WOLFSSL_FAILURE; } @@ -9072,7 +9072,7 @@ static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, if (crl->crlList->lastDate[0] != 0) { if (GetTimeString(crl->crlList->lastDate, crl->crlList->lastDateFormat, - tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error getting last update date"); return WOLFSSL_FAILURE; } @@ -9100,7 +9100,7 @@ static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, if (crl->crlList->nextDate[0] != 0) { if (GetTimeString(crl->crlList->nextDate, crl->crlList->nextDateFormat, - tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error getting next update date"); return WOLFSSL_FAILURE; } diff --git a/src/x509_str.c b/src/x509_str.c index 432a48897d..6432bab2d8 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -375,23 +375,25 @@ static int X509StoreVerifyCertDate(WOLFSSL_X509_STORE_CTX* ctx, int ret) WOLFSSL_MSG("Override date validation, WOLFSSL_USE_CHECK_TIME"); if (wc_ValidateDateWithTime(afterDate, (byte)ctx->current_cert->notAfter.type, ASN_AFTER, - checkTime) < 1) { + checkTime, ctx->current_cert->notAfter.length) < 1) { ret = ASN_AFTER_DATE_E; } else if (wc_ValidateDateWithTime(beforeDate, (byte)ctx->current_cert->notBefore.type, ASN_BEFORE, - checkTime) < 1) { + checkTime, ctx->current_cert->notBefore.length) < 1) { ret = ASN_BEFORE_DATE_E; } } } #else if (XVALIDATE_DATE(afterDate, - (byte)ctx->current_cert->notAfter.type, ASN_AFTER) < 1) { + (byte)ctx->current_cert->notAfter.type, ASN_AFTER, + ctx->current_cert->notAfter.length) < 1) { ret = ASN_AFTER_DATE_E; } else if (XVALIDATE_DATE(beforeDate, - (byte)ctx->current_cert->notBefore.type, ASN_BEFORE) < 1) { + (byte)ctx->current_cert->notBefore.type, ASN_BEFORE, + ctx->current_cert->notBefore.length) < 1) { ret = ASN_BEFORE_DATE_E; } #endif /* USE_WOLF_VALIDDATE */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c5d86d0eac..dc17a3357a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -16271,7 +16271,7 @@ static WC_INLINE int GetTime_Long(long* value, const byte* date, int* idx) * Reminder: idx is incremented in each call to GetTime() * Return 0 on failure, 1 for success. */ int ExtractDate(const unsigned char* date, unsigned char format, - struct tm* certTime, int* idx) + struct tm* certTime, int* idx, int len) { int i = *idx; @@ -16280,13 +16280,21 @@ int ExtractDate(const unsigned char* date, unsigned char format, * 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. */ + /* UTCTime format requires YYMMDDHHMMSSZ (13 chars). */ + /* Bounds check: ensure we have enough data before accessing. */ + if (len < i + ASN_UTC_TIME_SIZE - 1) { + return 0; + } if (date[i + ASN_UTC_TIME_SIZE - 2] != 'Z') { return 0; } } else if (format == ASN_GENERALIZED_TIME) { - /* GeneralizedTime format requires YYYYMMDDHHMMSSZ. */ + /* GeneralizedTime format requires YYYYMMDDHHMMSSZ (15 chars). */ + /* Bounds check: ensure we have enough data before accessing. */ + if (len < i + ASN_GENERALIZED_TIME_SIZE - 1) { + return 0; + } if (date[ i + ASN_GENERALIZED_TIME_SIZE - 2] != 'Z') { return 0; } @@ -16363,12 +16371,12 @@ int ExtractDate(const unsigned char* date, unsigned char format, #ifdef WOLFSSL_ASN_TIME_STRING -int GetTimeString(byte* date, int format, char* buf, int len) +int GetTimeString(byte* date, int format, char* buf, int len, int dateLen) { struct tm t; int idx = 0; - if (!ExtractDate(date, (unsigned char)format, &t, &idx)) { + if (!ExtractDate(date, (unsigned char)format, &t, &idx, dateLen)) { return 0; } @@ -16598,13 +16606,13 @@ static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b) /* date = ASN.1 raw */ /* format = ASN_UTC_TIME or ASN_GENERALIZED_TIME */ /* dateType = ASN_AFTER or ASN_BEFORE */ -int wc_ValidateDate(const byte* date, byte format, int dateType) +int wc_ValidateDate(const byte* date, byte format, int dateType, int len) { - return wc_ValidateDateWithTime(date, format, dateType, 0); + return wc_ValidateDateWithTime(date, format, dateType, 0, len); } int wc_ValidateDateWithTime(const byte* date, byte format, int dateType, - time_t checkTime) + time_t checkTime, int len) { time_t ltime; struct tm certTime; @@ -16653,7 +16661,7 @@ int wc_ValidateDateWithTime(const byte* date, byte format, int dateType, } #endif - if (!ExtractDate(date, format, &certTime, &i)) { + if (!ExtractDate(date, format, &certTime, &i, len)) { WOLFSSL_MSG("Error extracting the date"); return 0; } @@ -16875,7 +16883,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)) { + !XVALIDATE_DATE(date, format, dateType, length)) { if (dateType == ASN_BEFORE) { WOLFSSL_ERROR_VERBOSE(ASN_BEFORE_DATE_E); return ASN_BEFORE_DATE_E; @@ -16933,7 +16941,7 @@ int wc_GetDateAsCalendarTime(const byte* date, int length, byte format, { int idx = 0; (void)length; - if (!ExtractDate(date, format, timearg, &idx)) + if (!ExtractDate(date, format, timearg, &idx, length)) return ASN_TIME_E; return 0; } @@ -23612,7 +23620,8 @@ 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) && (! AsnSkipDateCheck)) { - if (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType)) { + if (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType, + (int)dataASN->data.ref.length)) { if (dateType == ASN_BEFORE) { ret = ASN_BEFORE_DATE_E; } @@ -38403,7 +38412,7 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, #ifndef NO_ASN_TIME_CHECK #ifndef WOLFSSL_NO_OCSP_DATE_CHECK if ((! AsnSkipDateCheck) && !XVALIDATE_DATE(single->status->thisDate, - single->status->thisDateFormat, ASN_BEFORE)) + single->status->thisDateFormat, ASN_BEFORE, MAX_DATE_SIZE)) return ASN_BEFORE_DATE_E; #endif #endif @@ -38441,7 +38450,7 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, #ifndef WOLFSSL_NO_OCSP_DATE_CHECK if ((! AsnSkipDateCheck) && !XVALIDATE_DATE(single->status->nextDate, - single->status->nextDateFormat, ASN_AFTER)) + single->status->nextDateFormat, ASN_AFTER, MAX_DATE_SIZE)) return ASN_AFTER_DATE_E; #endif #endif @@ -38515,7 +38524,8 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK) /* Check date is a valid string and ASN_BEFORE now. */ if ((! AsnSkipDateCheck) && - !XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, ASN_BEFORE)) + !XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, ASN_BEFORE, + MAX_DATE_SIZE)) { ret = ASN_BEFORE_DATE_E; } @@ -38540,7 +38550,8 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK) /* Check date is a valid string and ASN_AFTER now. */ if ((! AsnSkipDateCheck) && - !XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, ASN_AFTER)) + !XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, ASN_AFTER, + MAX_DATE_SIZE)) { ret = ASN_AFTER_DATE_E; } @@ -40627,7 +40638,8 @@ 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)) { + !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER, + MAX_DATE_SIZE)) { WOLFSSL_MSG("CRL after date is no longer valid"); WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR); return CRL_CERT_DATE_ERR; @@ -41289,7 +41301,8 @@ int ParseCRL(RevokedCert* rcert, DecodedCRL* dcrl, const byte* buff, word32 sz, /* Next date was set, so validate it. */ if (verify != NO_VERIFY && (! AsnSkipDateCheck) && - !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) { + !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER, + MAX_DATE_SIZE)) { WOLFSSL_MSG("CRL after date is no longer valid"); ret = CRL_CERT_DATE_ERR; WOLFSSL_ERROR_VERBOSE(ret); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 84ad93f1bb..99da1e84fa 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2244,7 +2244,8 @@ WOLFSSL_LOCAL int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, typedef struct tm wolfssl_tm; #ifdef WOLFSSL_ASN_TIME_STRING -WOLFSSL_LOCAL int GetTimeString(byte* date, int format, char* buf, int len); +WOLFSSL_LOCAL int GetTimeString(byte* date, int format, char* buf, int len, + int dateLen); #endif #if !defined(NO_ASN_TIME) && !defined(USER_TIME) && \ !defined(TIME_OVERRIDES) && (defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7)) @@ -2252,12 +2253,13 @@ WOLFSSL_LOCAL int GetFormattedTime(void* currTime, byte* buf, word32 len); WOLFSSL_LOCAL int GetAsnTimeString(void* currTime, byte* buf, word32 len); #endif WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format, - wolfssl_tm* certTime, int* idx); + wolfssl_tm* certTime, int* idx, int len); 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_LOCAL int wc_ValidateDate(const byte* date, byte format, int dateType, + int len); #ifndef NO_ASN_TIME WOLFSSL_LOCAL int wc_ValidateDateWithTime(const byte* date, byte format, - int dateType, time_t checkTime); + int dateType, time_t checkTime, int len); #endif WOLFSSL_TEST_VIS int wc_AsnSetSkipDateCheck(int skip_p); WOLFSSL_LOCAL int wc_AsnGetSkipDateCheck(void); diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index d9d97f3085..ff9cd730d2 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1586,7 +1586,7 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); #endif #if !defined(XVALIDATE_DATE) && !defined(HAVE_VALIDATE_DATE) #define USE_WOLF_VALIDDATE - #define XVALIDATE_DATE(d, f, t) wc_ValidateDate((d), (f), (t)) + #define XVALIDATE_DATE(d, f, t, l) wc_ValidateDate((d), (f), (t), (l)) #endif /* wolf struct tm and time_t */