From: Pauli Date: Mon, 29 Aug 2022 04:53:45 +0000 (+1000) Subject: libcrypto: remove reliance on struct timeval X-Git-Tag: openssl-3.2.0-alpha1~2092 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d1bb4fc47582b06dd224a788bdfaaced60e72a0;p=thirdparty%2Fopenssl.git libcrypto: remove reliance on struct timeval Reviewed-by: Todd Short Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/19082) --- diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index 0dae4e25ec7..e18072cf99b 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -14,6 +14,7 @@ #include #include +#include "internal/time.h" #include "bio_local.h" #ifndef OPENSSL_NO_DGRAM @@ -149,8 +150,6 @@ static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notificatio static int BIO_dgram_should_retry(int s); -static void get_current_time(struct timeval *t); - static const BIO_METHOD methods_dgramp = { BIO_TYPE_DGRAM, "datagram socket", @@ -193,8 +192,8 @@ typedef struct bio_dgram_data_st { unsigned int connected; unsigned int _errno; unsigned int mtu; - struct timeval next_timeout; - struct timeval socket_timeout; + OSSL_TIME next_timeout; + OSSL_TIME socket_timeout; unsigned int peekmode; char local_addr_enabled; } bio_dgram_data; @@ -283,70 +282,53 @@ static void dgram_adjust_rcv_timeout(BIO *b) { # if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; + OSSL_TIME timeleft; /* Is a timer active? */ - if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { - struct timeval timenow, timeleft; - + if (!ossl_time_is_zero(data->next_timeout)) { /* Read current socket timeout */ # ifdef OPENSSL_SYS_WINDOWS int timeout; - int sz = sizeof(timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz) < 0) { + (void *)&timeout, &sz) < 0) ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), "calling getsockopt()"); - } else { - data->socket_timeout.tv_sec = timeout / 1000; - data->socket_timeout.tv_usec = (timeout % 1000) * 1000; - } + else + data->socket_timeout = ossl_ms2time(timeout); # else - socklen_t sz = sizeof(data->socket_timeout); - if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - &(data->socket_timeout), &sz) < 0) + struct timeval tv; + socklen_t sz = sizeof(tv); + + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &tv, &sz) < 0) ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), "calling getsockopt()"); else - OPENSSL_assert(sz <= sizeof(data->socket_timeout)); + data->socket_timeout = ossl_time_from_timeval(tv); # endif - /* Get current time */ - get_current_time(&timenow); - /* Calculate time left until timer expires */ - memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); - if (timeleft.tv_usec < timenow.tv_usec) { - timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec; - timeleft.tv_sec--; - } else { - timeleft.tv_usec -= timenow.tv_usec; - } - if (timeleft.tv_sec < timenow.tv_sec) { - timeleft.tv_sec = 0; - timeleft.tv_usec = 1; - } else { - timeleft.tv_sec -= timenow.tv_sec; - } + timeleft = ossl_time_subtract(data->next_timeout, ossl_time_now()); + if (ossl_time_compare(timeleft, ossl_ticks2time(OSSL_TIME_US)) < 0) + timeleft = ossl_ticks2time(OSSL_TIME_US); /* * Adjust socket timeout if next handshake message timer will expire * earlier. */ - if ((data->socket_timeout.tv_sec == 0 - && data->socket_timeout.tv_usec == 0) - || (data->socket_timeout.tv_sec > timeleft.tv_sec) - || (data->socket_timeout.tv_sec == timeleft.tv_sec - && data->socket_timeout.tv_usec >= timeleft.tv_usec)) { + if (ossl_time_is_zero(data->socket_timeout) + || ossl_time_compare(data->socket_timeout, timeleft) >= 0) { # ifdef OPENSSL_SYS_WINDOWS - timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; + timeout = (int)ossl_time2ms(timeleft); if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout)) < 0) ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), "calling setsockopt()"); # else - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, - sizeof(struct timeval)) < 0) + tv = ossl_time_to_timeval(timeleft); + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &tv, + sizeof(tv)) < 0) ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), "calling setsockopt()"); # endif @@ -382,17 +364,18 @@ static void dgram_reset_rcv_timeout(BIO *b) bio_dgram_data *data = (bio_dgram_data *)b->ptr; /* Is a timer active? */ - if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { + if (!ossl_time_is_zero(data->next_timeout)) { # ifdef OPENSSL_SYS_WINDOWS - int timeout = data->socket_timeout.tv_sec * 1000 + - data->socket_timeout.tv_usec / 1000; + int timeout = (int)ossl_time2ms(data->socket_timeout); + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout)) < 0) ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), "calling setsockopt()"); # else - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - &(data->socket_timeout), sizeof(struct timeval)) < 0) + struct timeval tv = ossl_time_to_timeval(data->socket_timeout); + + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), "calling setsockopt()"); # endif @@ -737,7 +720,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr)); break; case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: - memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); + data->next_timeout = ossl_time_from_timeval(*(struct timeval *)ptr); break; # if defined(SO_RCVTIMEO) case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: @@ -745,6 +728,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) { struct timeval *tv = (struct timeval *)ptr; int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + if ((ret = setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout))) < 0) ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), @@ -2794,29 +2778,4 @@ int BIO_dgram_non_fatal_error(int err) return 0; } -static void get_current_time(struct timeval *t) -{ -# if defined(_WIN32) - SYSTEMTIME st; - unsigned __int64 now_ul; - FILETIME now_ft; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &now_ft); - now_ul = ((unsigned __int64)now_ft.dwHighDateTime << 32) | now_ft.dwLowDateTime; -# ifdef __MINGW32__ - now_ul -= 116444736000000000ULL; -# else - now_ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ -# endif - t->tv_sec = (long)(now_ul / 10000000); - t->tv_usec = ((int)(now_ul % 10000000)) / 10; -# else - if (gettimeofday(t, NULL) < 0) - ERR_raise_data(ERR_LIB_SYS, errno, - "calling gettimeofday"); - -# endif -} - #endif diff --git a/crypto/ct/ct_policy.c b/crypto/ct/ct_policy.c index 80a8baabe16..ad792b740de 100644 --- a/crypto/ct/ct_policy.c +++ b/crypto/ct/ct_policy.c @@ -13,7 +13,7 @@ #include #include -#include +#include "internal/time.h" #include "ct_local.h" @@ -29,6 +29,7 @@ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX)); + OSSL_TIME now; if (ctx == NULL) { ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); @@ -45,9 +46,9 @@ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, } } - /* time(NULL) shouldn't ever fail, so don't bother checking for -1. */ - ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) * - 1000; + now = ossl_time_add(ossl_time_now(), + ossl_seconds2time(SCT_CLOCK_DRIFT_TOLERANCE)); + ctx->epoch_time_in_ms = ossl_time2ms(now); return ctx; } diff --git a/crypto/ts/ts_rsp_sign.c b/crypto/ts/ts_rsp_sign.c index dce50eb451f..88be6fa7bc0 100644 --- a/crypto/ts/ts_rsp_sign.c +++ b/crypto/ts/ts_rsp_sign.c @@ -15,6 +15,7 @@ #include #include "internal/cryptlib.h" #include "internal/sizes.h" +#include "internal/time.h" #include "crypto/ess.h" #include "ts_local.h" @@ -58,46 +59,27 @@ static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) return NULL; } -#if defined(OPENSSL_SYS_UNIX) - static int def_time_cb(struct TS_resp_ctx *ctx, void *data, long *sec, long *usec) { + OSSL_TIME t; struct timeval tv; - if (gettimeofday(&tv, NULL) != 0) { - ERR_raise(ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR); - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Time is not available."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); - return 0; - } - *sec = tv.tv_sec; - *usec = tv.tv_usec; - return 1; -} - -#else - -static int def_time_cb(struct TS_resp_ctx *ctx, void *data, - long *sec, long *usec) -{ - time_t t; - if (time(&t) == (time_t)-1) { + t = ossl_time_now(); + if (ossl_time_is_zero(t)) { ERR_raise(ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR); TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Time is not available."); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); return 0; } - *sec = (long)t; - *usec = 0; + tv = ossl_time_to_timeval(t); + *sec = (long int)tv.tv_sec; + *usec = (long int)tv.tv_usec; return 1; } -#endif - static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, void *data) { diff --git a/include/internal/e_os.h b/include/internal/e_os.h index 9e2f14072f6..0e520364344 100644 --- a/include/internal/e_os.h +++ b/include/internal/e_os.h @@ -322,15 +322,10 @@ static ossl_inline void ossl_sleep(unsigned long millis) /* Fallback to a busy wait */ static ossl_inline void ossl_sleep(unsigned long millis) { - struct timeval start, now; - unsigned long elapsedms; - - gettimeofday(&start, NULL); - do { - gettimeofday(&now, NULL); - elapsedms = (((now.tv_sec - start.tv_sec) * 1000000) - + now.tv_usec - start.tv_usec) / 1000; - } while (elapsedms < millis); + const OSSL_TIME finish = ossl_time_add(ossl_time_now(), ossl_ms2time(millis)); + + while (ossl_time_compare(ossl_time_now(), finish) < 0) + /* busy wait */ ; } #endif /* defined OPENSSL_SYS_UNIX */