diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 788df1a2..78d39a6a 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -974,7 +974,7 @@ struct ssl_ctx_st { /* current_time_cb, if not NULL, is the function to use to get the current * time. It sets |*out_clock| to the current time. */ - void (*current_time_cb)(SSL *ssl, OPENSSL_timeval *out_clock); + void (*current_time_cb)(const SSL *ssl, OPENSSL_timeval *out_clock); }; #define SSL_SESS_CACHE_OFF 0x0000 @@ -1620,9 +1620,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) #define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 #define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 -#define DTLS_CTRL_GET_TIMEOUT 73 -#define DTLS_CTRL_HANDLE_TIMEOUT 74 - #define SSL_CTRL_GET_RI_SUPPORT 76 #define SSL_CTRL_CLEAR_OPTIONS 77 #define SSL_CTRL_CLEAR_MODE 78 @@ -1657,16 +1654,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) #define SSL_CTRL_SET_CHANNEL_ID 119 /* DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a - * timeout in progress, it sets |*((OPENSSL_timeval*)arg)| to the time remaining - * and returns one. Otherwise, it returns zero. + * timeout in progress, it sets |*out| to the time remaining and returns one. + * Otherwise, it returns zero. * * When the timeout expires, call |DTLSv1_handle_timeout| to handle the * retransmit behavior. * * NOTE: This function must be queried again whenever the handshake state * machine changes, including when |DTLSv1_handle_timeout| is called. */ -#define DTLSv1_get_timeout(ssl, arg) \ - SSL_ctrl(ssl, DTLS_CTRL_GET_TIMEOUT, 0, (void *)arg) +OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, OPENSSL_timeval *out); /* DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no * timeout had expired, it returns 0. Otherwise, it retransmits the previous @@ -1675,9 +1671,10 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) * * NOTE: The caller's external timer should be compatible with the one |ssl| * queries within some fudge factor. Otherwise, the call will be a no-op, but - * |DTLSv1_get_timeout| will return an updated timeout. */ -#define DTLSv1_handle_timeout(ssl) \ - SSL_ctrl(ssl, DTLS_CTRL_HANDLE_TIMEOUT, 0, NULL) + * |DTLSv1_get_timeout| will return an updated timeout. + * + * WARNING: This function breaks the usual return value convention. */ +OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl); #define SSL_session_reused(ssl) \ SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL) @@ -2357,10 +2354,14 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused); #define SSL_CTRL_SET_MSG_CALLBACK doesnt_exist #define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist #define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB doesnt_exist +#define DTLS_CTRL_GET_TIMEOUT doesnt_exist +#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist #define SSL_CTX_set_tlsext_servername_callback \ SSL_CTX_set_tlsext_servername_callback #define SSL_CTX_set_tlsext_ticket_key_cb SSL_CTX_set_tlsext_ticket_key_cb +#define DTLSv1_get_timeout DTLSv1_get_timeout +#define DTLSv1_handle_timeout DTLSv1_handle_timeout #if defined(__cplusplus) diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 85b0af9c..6ce508fa 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -711,7 +711,7 @@ int dtls1_read_failed(SSL *s, int code) { return code; } - return dtls1_handle_timeout(s); + return DTLSv1_handle_timeout(s); } int dtls1_get_queue_priority(unsigned short seq, int is_ccs) { diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 3c1fd094..e4809cac 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -81,8 +81,7 @@ * before failing the DTLS handshake. */ #define DTLS1_MAX_TIMEOUTS 12 -static void get_current_time(SSL *ssl, OPENSSL_timeval *out_clock); -static OPENSSL_timeval *dtls1_get_timeout(SSL *s, OPENSSL_timeval *timeleft); +static void get_current_time(const SSL *ssl, OPENSSL_timeval *out_clock); int dtls1_new(SSL *s) { DTLS1_STATE *d1; @@ -152,28 +151,6 @@ void dtls1_free(SSL *s) { s->d1 = NULL; } -long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) { - int ret = 0; - - switch (cmd) { - case DTLS_CTRL_GET_TIMEOUT: - if (dtls1_get_timeout(s, (OPENSSL_timeval *)parg) != NULL) { - ret = 1; - } - break; - - case DTLS_CTRL_HANDLE_TIMEOUT: - ret = dtls1_handle_timeout(s); - break; - - default: - ret = ssl3_ctrl(s, cmd, larg, parg); - break; - } - - return ret; -} - const SSL_CIPHER *dtls1_get_cipher(size_t i) { const SSL_CIPHER *ciph = ssl3_get_cipher(i); /* DTLS does not support stream ciphers. */ @@ -199,48 +176,51 @@ void dtls1_start_timer(SSL *s) { &s->d1->next_timeout); } -static OPENSSL_timeval *dtls1_get_timeout(SSL *s, OPENSSL_timeval *timeleft) { - OPENSSL_timeval timenow; +int DTLSv1_get_timeout(const SSL *ssl, OPENSSL_timeval *out) { + if (!SSL_IS_DTLS(ssl)) { + return 0; + } /* If no timeout is set, just return NULL */ - if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - return NULL; + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + return 0; } /* Get current time */ - get_current_time(s, &timenow); + OPENSSL_timeval timenow; + get_current_time(ssl, &timenow); /* If timer already expired, set remaining time to 0 */ - if (s->d1->next_timeout.tv_sec < timenow.tv_sec || - (s->d1->next_timeout.tv_sec == timenow.tv_sec && - s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { - memset(timeleft, 0, sizeof(OPENSSL_timeval)); - return timeleft; + if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec || + (ssl->d1->next_timeout.tv_sec == timenow.tv_sec && + ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + memset(out, 0, sizeof(OPENSSL_timeval)); + return 1; } /* Calculate time left until timer expires */ - memcpy(timeleft, &s->d1->next_timeout, sizeof(OPENSSL_timeval)); - timeleft->tv_sec -= timenow.tv_sec; - timeleft->tv_usec -= timenow.tv_usec; - if (timeleft->tv_usec < 0) { - timeleft->tv_sec--; - timeleft->tv_usec += 1000000; + memcpy(out, &ssl->d1->next_timeout, sizeof(OPENSSL_timeval)); + out->tv_sec -= timenow.tv_sec; + out->tv_usec -= timenow.tv_usec; + if (out->tv_usec < 0) { + out->tv_sec--; + out->tv_usec += 1000000; } /* If remaining time is less than 15 ms, set it to 0 to prevent issues * because of small devergences with socket timeouts. */ - if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { - memset(timeleft, 0, sizeof(OPENSSL_timeval)); + if (out->tv_sec == 0 && out->tv_usec < 15000) { + memset(out, 0, sizeof(OPENSSL_timeval)); } - return timeleft; + return 1; } int dtls1_is_timer_expired(SSL *s) { OPENSSL_timeval timeleft; /* Get time left until timeout, return false if no timer running */ - if (dtls1_get_timeout(s, &timeleft) == NULL) { + if (!DTLSv1_get_timeout(s, &timeleft)) { return 0; } @@ -294,23 +274,27 @@ int dtls1_check_timeout_num(SSL *s) { return 0; } -int dtls1_handle_timeout(SSL *s) { +int DTLSv1_handle_timeout(SSL *ssl) { + if (!SSL_IS_DTLS(ssl)) { + return -1; + } + /* if no timer is expired, don't do anything */ - if (!dtls1_is_timer_expired(s)) { + if (!dtls1_is_timer_expired(ssl)) { return 0; } - dtls1_double_timeout(s); + dtls1_double_timeout(ssl); - if (dtls1_check_timeout_num(s) < 0) { + if (dtls1_check_timeout_num(ssl) < 0) { return -1; } - dtls1_start_timer(s); - return dtls1_retransmit_buffered_messages(s); + dtls1_start_timer(ssl); + return dtls1_retransmit_buffered_messages(ssl); } -static void get_current_time(SSL *ssl, OPENSSL_timeval *out_clock) { +static void get_current_time(const SSL *ssl, OPENSSL_timeval *out_clock) { if (ssl->ctx->current_time_cb != NULL) { ssl->ctx->current_time_cb(ssl, out_clock); return; diff --git a/ssl/d1_meth.c b/ssl/d1_meth.c index 0485b997..a11fbdd8 100644 --- a/ssl/d1_meth.c +++ b/ssl/d1_meth.c @@ -74,7 +74,7 @@ static const SSL_PROTOCOL_METHOD DTLS_protocol_method = { dtls1_read_bytes, dtls1_write_app_data_bytes, dtls1_dispatch_alert, - dtls1_ctrl, + ssl3_ctrl, ssl3_ctx_ctrl, ssl3_pending, ssl3_num_ciphers, diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index 5bb01da2..f4f0cce9 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -461,7 +461,7 @@ start: rr = &s->s3->rrec; /* Check for timeout */ - if (dtls1_handle_timeout(s) > 0) { + if (DTLSv1_handle_timeout(s) > 0) { goto start; } diff --git a/ssl/internal.h b/ssl/internal.h index d4311ccb..1beb157a 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -812,7 +812,6 @@ void dtls1_clear_record_buffer(SSL *s); void dtls1_get_message_header(uint8_t *data, struct hm_header_st *msg_hdr); void dtls1_reset_seq_numbers(SSL *s, int rw); int dtls1_check_timeout_num(SSL *s); -int dtls1_handle_timeout(SSL *s); int dtls1_set_handshake_header(SSL *s, int type, unsigned long len); int dtls1_handshake_write(SSL *s); @@ -862,7 +861,6 @@ int dtls1_new(SSL *s); int dtls1_accept(SSL *s); int dtls1_connect(SSL *s); void dtls1_free(SSL *s); -long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); int dtls1_shutdown(SSL *s); long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index bf526b8e..9750adbf 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc @@ -285,7 +285,7 @@ static unsigned PskServerCallback(SSL *ssl, const char *identity, return config->psk.size(); } -static void CurrentTimeCallback(SSL *ssl, OPENSSL_timeval *out_clock) { +static void CurrentTimeCallback(const SSL *ssl, OPENSSL_timeval *out_clock) { *out_clock = GetTestState(ssl)->clock; }