BUG=404754 Change-Id: I5f11485fbafa07cddcf2612e2f616f90bf7c722d Reviewed-on: https://boringssl-review.googlesource.com/4554 Reviewed-by: Adam Langley <agl@google.com>kris/onging/CECPQ3_patch15
@@ -974,7 +974,7 @@ struct ssl_ctx_st { | |||||
/* current_time_cb, if not NULL, is the function to use to get the current | /* current_time_cb, if not NULL, is the function to use to get the current | ||||
* time. It sets |*out_clock| to the current time. */ | * 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 | #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_STRENGTH 80 | ||||
#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 | #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_GET_RI_SUPPORT 76 | ||||
#define SSL_CTRL_CLEAR_OPTIONS 77 | #define SSL_CTRL_CLEAR_OPTIONS 77 | ||||
#define SSL_CTRL_CLEAR_MODE 78 | #define SSL_CTRL_CLEAR_MODE 78 | ||||
@@ -1657,16 +1654,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) | |||||
#define SSL_CTRL_SET_CHANNEL_ID 119 | #define SSL_CTRL_SET_CHANNEL_ID 119 | ||||
/* DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a | /* 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 | * When the timeout expires, call |DTLSv1_handle_timeout| to handle the | ||||
* retransmit behavior. | * retransmit behavior. | ||||
* | * | ||||
* NOTE: This function must be queried again whenever the handshake state | * NOTE: This function must be queried again whenever the handshake state | ||||
* machine changes, including when |DTLSv1_handle_timeout| is called. */ | * 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 | /* DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no | ||||
* timeout had expired, it returns 0. Otherwise, it retransmits the previous | * 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| | * 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 | * 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) \ | #define SSL_session_reused(ssl) \ | ||||
SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL) | 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_MSG_CALLBACK doesnt_exist | ||||
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist | #define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist | ||||
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_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 \ | #define SSL_CTX_set_tlsext_servername_callback \ | ||||
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 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) | #if defined(__cplusplus) | ||||
@@ -711,7 +711,7 @@ int dtls1_read_failed(SSL *s, int code) { | |||||
return code; | return code; | ||||
} | } | ||||
return dtls1_handle_timeout(s); | |||||
return DTLSv1_handle_timeout(s); | |||||
} | } | ||||
int dtls1_get_queue_priority(unsigned short seq, int is_ccs) { | int dtls1_get_queue_priority(unsigned short seq, int is_ccs) { | ||||
@@ -81,8 +81,7 @@ | |||||
* before failing the DTLS handshake. */ | * before failing the DTLS handshake. */ | ||||
#define DTLS1_MAX_TIMEOUTS 12 | #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) { | int dtls1_new(SSL *s) { | ||||
DTLS1_STATE *d1; | DTLS1_STATE *d1; | ||||
@@ -152,28 +151,6 @@ void dtls1_free(SSL *s) { | |||||
s->d1 = NULL; | 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 *dtls1_get_cipher(size_t i) { | ||||
const SSL_CIPHER *ciph = ssl3_get_cipher(i); | const SSL_CIPHER *ciph = ssl3_get_cipher(i); | ||||
/* DTLS does not support stream ciphers. */ | /* DTLS does not support stream ciphers. */ | ||||
@@ -199,48 +176,51 @@ void dtls1_start_timer(SSL *s) { | |||||
&s->d1->next_timeout); | &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 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 */ | ||||
get_current_time(s, &timenow); | |||||
OPENSSL_timeval timenow; | |||||
get_current_time(ssl, &timenow); | |||||
/* If timer already expired, set remaining time to 0 */ | /* 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 */ | /* 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 | /* If remaining time is less than 15 ms, set it to 0 to prevent issues | ||||
* because of small devergences with socket timeouts. */ | * 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) { | int dtls1_is_timer_expired(SSL *s) { | ||||
OPENSSL_timeval timeleft; | OPENSSL_timeval timeleft; | ||||
/* Get time left until timeout, return false if no timer running */ | /* 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; | return 0; | ||||
} | } | ||||
@@ -294,23 +274,27 @@ int dtls1_check_timeout_num(SSL *s) { | |||||
return 0; | 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 no timer is expired, don't do anything */ | ||||
if (!dtls1_is_timer_expired(s)) { | |||||
if (!dtls1_is_timer_expired(ssl)) { | |||||
return 0; | 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; | 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) { | if (ssl->ctx->current_time_cb != NULL) { | ||||
ssl->ctx->current_time_cb(ssl, out_clock); | ssl->ctx->current_time_cb(ssl, out_clock); | ||||
return; | return; | ||||
@@ -74,7 +74,7 @@ static const SSL_PROTOCOL_METHOD DTLS_protocol_method = { | |||||
dtls1_read_bytes, | dtls1_read_bytes, | ||||
dtls1_write_app_data_bytes, | dtls1_write_app_data_bytes, | ||||
dtls1_dispatch_alert, | dtls1_dispatch_alert, | ||||
dtls1_ctrl, | |||||
ssl3_ctrl, | |||||
ssl3_ctx_ctrl, | ssl3_ctx_ctrl, | ||||
ssl3_pending, | ssl3_pending, | ||||
ssl3_num_ciphers, | ssl3_num_ciphers, | ||||
@@ -461,7 +461,7 @@ start: | |||||
rr = &s->s3->rrec; | rr = &s->s3->rrec; | ||||
/* Check for timeout */ | /* Check for timeout */ | ||||
if (dtls1_handle_timeout(s) > 0) { | |||||
if (DTLSv1_handle_timeout(s) > 0) { | |||||
goto start; | goto start; | ||||
} | } | ||||
@@ -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_get_message_header(uint8_t *data, struct hm_header_st *msg_hdr); | ||||
void dtls1_reset_seq_numbers(SSL *s, int rw); | void dtls1_reset_seq_numbers(SSL *s, int rw); | ||||
int dtls1_check_timeout_num(SSL *s); | 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_set_handshake_header(SSL *s, int type, unsigned long len); | ||||
int dtls1_handshake_write(SSL *s); | int dtls1_handshake_write(SSL *s); | ||||
@@ -862,7 +861,6 @@ int dtls1_new(SSL *s); | |||||
int dtls1_accept(SSL *s); | int dtls1_accept(SSL *s); | ||||
int dtls1_connect(SSL *s); | int dtls1_connect(SSL *s); | ||||
void dtls1_free(SSL *s); | void dtls1_free(SSL *s); | ||||
long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); | |||||
int dtls1_shutdown(SSL *s); | int dtls1_shutdown(SSL *s); | ||||
long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, | long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, | ||||
@@ -285,7 +285,7 @@ static unsigned PskServerCallback(SSL *ssl, const char *identity, | |||||
return config->psk.size(); | 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; | *out_clock = GetTestState(ssl)->clock; | ||||
} | } | ||||