diff --git a/doc/dox_comments/header_files/asn_public.h b/doc/dox_comments/header_files/asn_public.h index eec57f9ee..97ca254f4 100644 --- a/doc/dox_comments/header_files/asn_public.h +++ b/doc/dox_comments/header_files/asn_public.h @@ -1884,3 +1884,56 @@ WOLFSSL_API int wc_ParseCert(DecodedCert* cert, int type, int verify, void* cm); \sa wc_ParseCert */ WOLFSSL_API void wc_FreeDecodedCert(struct DecodedCert* cert); + +/*! + \ingroup ASN + + \brief This function registers a time callback that will be used anytime + wolfSSL needs to get the current time. The prototype of the callback should + be the same as the "time" function from the C standard library. + + \return 0 Returned on success. + + \param f function to register as the time callback. + + _Example_ + \code + int ret = 0; + // Time callback prototype + time_t my_time_cb(time_t* t); + // Register it + ret = wc_SetTimeCb(my_time_cb); + if (ret != 0) { + // failed to set time callback + } + time_t my_time_cb(time_t* t) + { + // custom time function + } + \endcode + + \sa wc_Time +*/ +WOLFSSL_API int wc_SetTimeCb(wc_time_cb f); + +/*! + \ingroup ASN + + \brief This function gets the current time. By default, it uses the XTIME + macro, which varies between platforms. The user can use a function of their + choosing instead via the wc_SetTimeCb function. + + \return Time Current time returned on success. + + \param t Optional time_t pointer to populate with current time. + + _Example_ + \code + time_t currentTime = 0; + currentTime = wc_Time(NULL); + wc_Time(¤tTime); + \endcode + + \sa wc_SetTimeCb +*/ +WOLFSSL_API time_t wc_Time(time_t* t); diff --git a/src/internal.c b/src/internal.c index 87c8a981c..0ed868420 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8341,9 +8341,14 @@ ProtocolVersion MakeDTLSv1_2(void) #endif #elif defined(TIME_OVERRIDES) - +#if !defined(NO_ASN) && !defined(NO_ASN_TIME) /* use same asn time overrides unless user wants tick override above */ + word32 LowResTimer(void) + { + return (word32) wc_Time(0); + } +#else #ifndef HAVE_TIME_T_TYPE typedef long time_t; #endif @@ -8353,6 +8358,7 @@ ProtocolVersion MakeDTLSv1_2(void) { return (word32) XTIME(0); } +#endif #elif defined(USE_WINDOWS_API) @@ -8546,7 +8552,11 @@ ProtocolVersion MakeDTLSv1_2(void) word32 LowResTimer(void) { + #if !defined(NO_ASN) && !defined(NO_ASN_TIME) + return (word32)wc_Time(0); + #else return (word32)XTIME(0); + #endif } #endif #else diff --git a/src/sniffer.c b/src/sniffer.c index 65d87e9f6..b5efd7d8b 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1048,7 +1048,7 @@ static void Trace(int idx) static void TraceHeader(void) { if (TraceOn) { - time_t ticks = XTIME(NULL); + time_t ticks = wc_Time(NULL); XFPRINTF(TraceFile, "\n%s", XCTIME(&ticks)); } } @@ -1449,7 +1449,7 @@ static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo) static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo) { SnifferSession* session; - time_t currTime = XTIME(NULL); + time_t currTime = wc_Time(NULL); word32 row = SessionHash(ipInfo, tcpInfo); wc_LockMutex(&SessionMutex); @@ -4487,7 +4487,7 @@ static void RemoveStaleSessions(void) session = SessionTable[i]; while (session) { SnifferSession* next = session->next; - if (XTIME(NULL) >= session->lastUsed + WOLFSSL_SNIFFER_TIMEOUT) { + if (wc_Time(NULL) >= session->lastUsed + WOLFSSL_SNIFFER_TIMEOUT) { TraceStaleSession(); RemoveSession(session, NULL, NULL, i); } @@ -4536,7 +4536,7 @@ static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo, session->cliPort = (word16)tcpInfo->srcPort; session->cliSeqStart = tcpInfo->sequence; session->cliExpected = 1; /* relative */ - session->lastUsed= XTIME(NULL); + session->lastUsed= wc_Time(NULL); session->keySz = 0; #ifdef HAVE_SNI session->sni = NULL; diff --git a/src/ssl.c b/src/ssl.c index 32df93ed4..ec68bfc1d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -27848,7 +27848,7 @@ int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime) if (cmpTime == NULL) { /* Use current time */ - *pTime = XTIME(0); + *pTime = wc_Time(0); } else { pTime = cmpTime; @@ -27878,7 +27878,7 @@ WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime, int offset_day, long offset_sec, time_t *in_tm) { /* get current time if in_tm is null */ - time_t t = in_tm ? *in_tm : XTIME(0); + time_t t = in_tm ? *in_tm : wc_Time(0); return wolfSSL_ASN1_TIME_adj(asnTime, t, offset_day, offset_sec); } @@ -28194,7 +28194,7 @@ int wolfSSL_ASN1_TIME_to_tm(const WOLFSSL_ASN1_TIME* asnTime, struct tm* tm) return WOLFSSL_FAILURE; } - currentTime = XTIME(0); + currentTime = wc_Time(0); if (currentTime <= 0) { WOLFSSL_MSG("Failed to get current time."); return WOLFSSL_FAILURE; @@ -31071,7 +31071,7 @@ int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from, } if (from == NULL) { - fromSecs = XTIME(0); + fromSecs = wc_Time(0); fromTm = XGMTIME(&fromSecs, tmpTs); if (fromTm == NULL) { WOLFSSL_MSG("XGMTIME for from time failed."); @@ -31090,7 +31090,7 @@ int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from, } if (to == NULL) { - toSecs = XTIME(0); + toSecs = wc_Time(0); toTm = XGMTIME(&toSecs, tmpTs); if (toTm == NULL) { WOLFSSL_MSG("XGMTIME for to time failed."); diff --git a/src/tls13.c b/src/tls13.c index 7bd68905c..47ef4cb59 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1279,6 +1279,12 @@ end: #endif #elif defined(TIME_OVERRIDES) +#if !defined(NO_ASN) && !defined(NO_ASN_TIME) + word32 TimeNowInMilliseconds(void) + { + return (word32) wc_Time(0) * 1000; + } +#else #ifndef HAVE_TIME_T_TYPE typedef long time_t; #endif @@ -1294,6 +1300,7 @@ end: { return (word32) XTIME(0) * 1000; } +#endif #elif defined(XTIME_MS) word32 TimeNowInMilliseconds(void) diff --git a/tests/api.c b/tests/api.c index 010bd2e3a..0e064e9f3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -35954,8 +35954,8 @@ static void test_wolfSSL_X509_time_adj(void) WOLFSSL_FILETYPE_ASN1)); t = 0; - not_before = XTIME(0); - not_after = XTIME(0) + (60 * 24 * 30); /* 30 days after */ + not_before = wc_Time(0); + not_after = wc_Time(0) + (60 * 24 * 30); /* 30 days after */ AssertNotNull(X509_time_adj(X509_get_notBefore(x509), not_before, &t)); AssertNotNull(X509_time_adj(X509_get_notAfter(x509), not_after, &t)); /* Check X509_gmtime_adj, too. */ @@ -49645,7 +49645,7 @@ static void test_openssl_make_self_signed_certificate(EVP_PKEY* pkey) AssertIntNE(X509_set_subject_name(x509, name), 0); AssertIntNE(X509_set_issuer_name(x509, name), 0); - not_before = (long)XTIME(NULL); + not_before = (long)wc_Time(NULL); not_after = not_before + (365 * 24 * 60 * 60); AssertNotNull(X509_time_adj(X509_get_notBefore(x509), not_before, &epoch_off)); AssertNotNull(X509_time_adj(X509_get_notAfter(x509), not_after, &epoch_off)); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 13028d952..71a87cb6d 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -12217,7 +12217,7 @@ int wc_ValidateDate(const byte* date, byte format, int dateType) #endif (void)tmpTime; - ltime = XTIME(0); + ltime = wc_Time(0); #ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW if (dateType == BEFORE) { @@ -12288,11 +12288,34 @@ int wc_GetTime(void* timePtr, word32 timeSize) return BUFFER_E; } - *ltime = XTIME(0); + *ltime = wc_Time(0); return 0; } +#ifdef TIME_OVERRIDES + #ifndef HAVE_TIME_T_TYPE + typedef long time_t; + #endif + extern time_t XTIME(time_t* t); +#endif + +static wc_time_cb timeFunc = NULL; + +int wc_SetTimeCb(wc_time_cb f) +{ + timeFunc = f; + return 0; +} + +time_t wc_Time(time_t* t) +{ + if (timeFunc != NULL) { + return timeFunc(t); + } + return XTIME(t); +} + #endif /* !NO_ASN_TIME */ @@ -23457,7 +23480,7 @@ static int SetValidity(byte* output, int daysValid) #endif (void)tmpTime; - now = XTIME(0); + now = wc_Time(0); /* before now */ before[0] = ASN_GENERALIZED_TIME; @@ -23528,7 +23551,7 @@ static int SetValidity(byte* before, byte* after, int daysValid) #endif (void)tmpTime; - now = XTIME(0); + now = wc_Time(0); /* subtract 1 day of seconds for more compliance */ then = now - 86400; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 3bcbfec6f..cfb24c83d 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1927,7 +1927,7 @@ static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd, if (signingTime == NULL || signingTimeSz == 0) return BAD_FUNC_ARG; - tm = XTIME(0); + tm = wc_Time(0); timeSz = GetAsnTimeString(&tm, signingTime, signingTimeSz); if (timeSz < 0) return timeSz; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index bf7db60b1..675f63792 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -539,6 +539,9 @@ WOLFSSL_TEST_SUBROUTINE int prime_test(void); WOLFSSL_TEST_SUBROUTINE int berder_test(void); #endif WOLFSSL_TEST_SUBROUTINE int logging_test(void); +#if !defined(NO_ASN) && !defined(NO_ASN_TIME) +WOLFSSL_TEST_SUBROUTINE int time_test(void); +#endif WOLFSSL_TEST_SUBROUTINE int mutex_test(void); #if defined(USE_WOLFSSL_MEMORY) && !defined(FREERTOS) WOLFSSL_TEST_SUBROUTINE int memcb_test(void); @@ -1396,6 +1399,13 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ else TEST_PASS("logging test passed!\n"); +#if !defined(NO_ASN) && !defined(NO_ASN_TIME) + if ( (ret = time_test()) != 0) + return err_sys("time test failed!\n", ret); + else + TEST_PASS("time test passed!\n"); +#endif + if ( (ret = mutex_test()) != 0) return err_sys("mutex test failed!\n", ret); else @@ -38599,6 +38609,35 @@ WOLFSSL_TEST_SUBROUTINE int certpiv_test(void) } #endif /* WOLFSSL_CERT_PIV */ +#if !defined(NO_ASN) && !defined(NO_ASN_TIME) +static time_t time_cb(time_t* t) +{ + if (t != NULL) { + *t = 99; + } + + return 99; +} + +WOLFSSL_TEST_SUBROUTINE int time_test(void) +{ + time_t t; + + if (wc_SetTimeCb(time_cb) != 0) + return -15000; + t = wc_Time(NULL); + if (t != 99) + return -15001; + if (wc_GetTime(&t, sizeof(time_t)) != 0) + return -15002; + if (t != 99) + return -15003; + if (wc_SetTimeCb(NULL) != 0) + return -15004; + + return 0; +} +#endif #undef ERROR_OUT diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 4c96ca3a9..7def2ac18 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -733,6 +733,10 @@ WOLFSSL_API int wc_CreateEncryptedPKCS8Key(byte*, word32, byte*, word32*, rc = wc_GetTime(&lTime, (word32)sizeof(lTime)); */ WOLFSSL_API int wc_GetTime(void* timePtr, word32 timeSize); + +typedef time_t (*wc_time_cb)(time_t* t); +WOLFSSL_API int wc_SetTimeCb(wc_time_cb f); +WOLFSSL_API time_t wc_Time(time_t* t); #endif #ifdef WOLFSSL_ENCRYPTED_KEYS