@@ -16271,8 +16271,38 @@ static WC_INLINE int GetTime_Long(long* value, const byte* date, int* idx)
1627116271 * Reminder: idx is incremented in each call to GetTime()
1627216272 * Return 0 on failure, 1 for success. */
1627316273int ExtractDate(const unsigned char* date, unsigned char format,
16274- struct tm* certTime, int* idx)
16274+ struct tm* certTime, int* idx, int len )
1627516275{
16276+ int i = *idx;
16277+
16278+ /* Validate date string length based on format. Can not assume null
16279+ * terminated strings. Must check for the 'Z'.
16280+ * Subtract 2; one for zero indexing and one to exclude null terminator
16281+ * built into macro values. */
16282+ if (format == ASN_UTC_TIME) {
16283+ /* UTCTime format requires YYMMDDHHMMSSZ (13 chars). */
16284+ /* Bounds check: ensure we have enough data before accessing. */
16285+ if (len < i + ASN_UTC_TIME_SIZE - 1) {
16286+ return 0;
16287+ }
16288+ if (date[i + ASN_UTC_TIME_SIZE - 2] != 'Z') {
16289+ return 0;
16290+ }
16291+ }
16292+ else if (format == ASN_GENERALIZED_TIME) {
16293+ /* GeneralizedTime format requires YYYYMMDDHHMMSSZ (15 chars). */
16294+ /* Bounds check: ensure we have enough data before accessing. */
16295+ if (len < i + ASN_GENERALIZED_TIME_SIZE - 1) {
16296+ return 0;
16297+ }
16298+ if (date[ i + ASN_GENERALIZED_TIME_SIZE - 2] != 'Z') {
16299+ return 0;
16300+ }
16301+ }
16302+ else {
16303+ return 0;
16304+ }
16305+
1627616306 XMEMSET(certTime, 0, sizeof(struct tm));
1627716307
1627816308 /* Get the first two bytes of the year (century) */
@@ -16341,12 +16371,12 @@ int ExtractDate(const unsigned char* date, unsigned char format,
1634116371
1634216372
1634316373#ifdef WOLFSSL_ASN_TIME_STRING
16344- int GetTimeString(byte* date, int format, char* buf, int len)
16374+ int GetTimeString(byte* date, int format, char* buf, int len, int dateLen )
1634516375{
1634616376 struct tm t;
1634716377 int idx = 0;
1634816378
16349- if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
16379+ if (!ExtractDate(date, (unsigned char)format, &t, &idx, dateLen )) {
1635016380 return 0;
1635116381 }
1635216382
@@ -16576,13 +16606,13 @@ static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
1657616606/* date = ASN.1 raw */
1657716607/* format = ASN_UTC_TIME or ASN_GENERALIZED_TIME */
1657816608/* dateType = ASN_AFTER or ASN_BEFORE */
16579- int wc_ValidateDate(const byte* date, byte format, int dateType)
16609+ int wc_ValidateDate(const byte* date, byte format, int dateType, int len )
1658016610{
16581- return wc_ValidateDateWithTime(date, format, dateType, 0);
16611+ return wc_ValidateDateWithTime(date, format, dateType, 0, len );
1658216612}
1658316613
1658416614int wc_ValidateDateWithTime(const byte* date, byte format, int dateType,
16585- time_t checkTime)
16615+ time_t checkTime, int len )
1658616616{
1658716617 time_t ltime;
1658816618 struct tm certTime;
@@ -16631,7 +16661,7 @@ int wc_ValidateDateWithTime(const byte* date, byte format, int dateType,
1663116661 }
1663216662#endif
1663316663
16634- if (!ExtractDate(date, format, &certTime, &i)) {
16664+ if (!ExtractDate(date, format, &certTime, &i, len )) {
1663516665 WOLFSSL_MSG("Error extracting the date");
1663616666 return 0;
1663716667 }
@@ -16853,7 +16883,7 @@ static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx)
1685316883#ifndef NO_ASN_TIME_CHECK
1685416884 if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE &&
1685516885 (! AsnSkipDateCheck) &&
16856- !XVALIDATE_DATE(date, format, dateType)) {
16886+ !XVALIDATE_DATE(date, format, dateType, length )) {
1685716887 if (dateType == ASN_BEFORE) {
1685816888 WOLFSSL_ERROR_VERBOSE(ASN_BEFORE_DATE_E);
1685916889 return ASN_BEFORE_DATE_E;
@@ -16911,7 +16941,7 @@ int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
1691116941{
1691216942 int idx = 0;
1691316943 (void)length;
16914- if (!ExtractDate(date, format, timearg, &idx))
16944+ if (!ExtractDate(date, format, timearg, &idx, length ))
1691516945 return ASN_TIME_E;
1691616946 return 0;
1691716947}
@@ -23590,7 +23620,8 @@ static int CheckDate(ASNGetData *dataASN, int dateType)
2359023620#ifndef NO_ASN_TIME_CHECK
2359123621 /* Check date is a valid string and ASN_BEFORE or ASN_AFTER now. */
2359223622 if ((ret == 0) && (! AsnSkipDateCheck)) {
23593- if (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType)) {
23623+ if (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType,
23624+ (int)dataASN->data.ref.length)) {
2359423625 if (dateType == ASN_BEFORE) {
2359523626 ret = ASN_BEFORE_DATE_E;
2359623627 }
@@ -38381,7 +38412,7 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
3838138412#ifndef NO_ASN_TIME_CHECK
3838238413#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
3838338414 if ((! AsnSkipDateCheck) && !XVALIDATE_DATE(single->status->thisDate,
38384- single->status->thisDateFormat, ASN_BEFORE))
38415+ single->status->thisDateFormat, ASN_BEFORE, MAX_DATE_SIZE ))
3838538416 return ASN_BEFORE_DATE_E;
3838638417#endif
3838738418#endif
@@ -38419,7 +38450,7 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
3841938450#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
3842038451 if ((! AsnSkipDateCheck) &&
3842138452 !XVALIDATE_DATE(single->status->nextDate,
38422- single->status->nextDateFormat, ASN_AFTER))
38453+ single->status->nextDateFormat, ASN_AFTER, MAX_DATE_SIZE ))
3842338454 return ASN_AFTER_DATE_E;
3842438455#endif
3842538456#endif
@@ -38493,7 +38524,8 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
3849338524 #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
3849438525 /* Check date is a valid string and ASN_BEFORE now. */
3849538526 if ((! AsnSkipDateCheck) &&
38496- !XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, ASN_BEFORE))
38527+ !XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, ASN_BEFORE,
38528+ MAX_DATE_SIZE))
3849738529 {
3849838530 ret = ASN_BEFORE_DATE_E;
3849938531 }
@@ -38518,7 +38550,8 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
3851838550 #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
3851938551 /* Check date is a valid string and ASN_AFTER now. */
3852038552 if ((! AsnSkipDateCheck) &&
38521- !XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, ASN_AFTER))
38553+ !XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, ASN_AFTER,
38554+ MAX_DATE_SIZE))
3852238555 {
3852338556 ret = ASN_AFTER_DATE_E;
3852438557 }
@@ -40605,7 +40638,8 @@ static int ParseCRL_CertList(RevokedCert* rcert, DecodedCRL* dcrl,
4060540638#if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_CRL_DATE_CHECK)
4060640639 if (verify != NO_VERIFY &&
4060740640 (! AsnSkipDateCheck) &&
40608- !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) {
40641+ !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER,
40642+ MAX_DATE_SIZE)) {
4060940643 WOLFSSL_MSG("CRL after date is no longer valid");
4061040644 WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR);
4061140645 return CRL_CERT_DATE_ERR;
@@ -41267,7 +41301,8 @@ int ParseCRL(RevokedCert* rcert, DecodedCRL* dcrl, const byte* buff, word32 sz,
4126741301 /* Next date was set, so validate it. */
4126841302 if (verify != NO_VERIFY &&
4126941303 (! AsnSkipDateCheck) &&
41270- !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) {
41304+ !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER,
41305+ MAX_DATE_SIZE)) {
4127141306 WOLFSSL_MSG("CRL after date is no longer valid");
4127241307 ret = CRL_CERT_DATE_ERR;
4127341308 WOLFSSL_ERROR_VERBOSE(ret);
0 commit comments