void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session) { struct OPENSSL_timeval now; ssl_get_current_time(ssl, &now); /* To avoid overflows and underflows, if we've gone back in time, update the * time, but mark the session expired. */ if (session->time > now.tv_sec) { session->time = now.tv_sec; session->timeout = 0; session->auth_timeout = 0; return; } /* Adjust the session time and timeouts. If the session has already expired, * clamp the timeouts at zero. */ uint64_t delta = now.tv_sec - session->time; session->time = now.tv_sec; if (session->timeout < delta) { session->timeout = 0; } else { session->timeout -= delta; } if (session->auth_timeout < delta) { session->auth_timeout = 0; } else { session->auth_timeout -= delta; } }
int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { if (session == NULL) { return 0; } struct OPENSSL_timeval now; ssl_get_current_time(ssl, &now); /* Reject tickets from the future to avoid underflow. */ if (now.tv_sec < session->time) { return 0; } return session->timeout > now.tv_sec - session->time; }
void dtls1_start_timer(SSL *ssl) { /* If timer is not set, initialize duration (by default, 1 second) */ if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms; } /* Set timeout to current time */ ssl_get_current_time(ssl, &ssl->d1->next_timeout); /* Add duration to current time */ ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration_ms / 1000; ssl->d1->next_timeout.tv_usec += (ssl->d1->timeout_duration_ms % 1000) * 1000; if (ssl->d1->next_timeout.tv_usec >= 1000000) { ssl->d1->next_timeout.tv_sec++; ssl->d1->next_timeout.tv_usec -= 1000000; } BIO_ctrl(ssl->rbio, BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &ssl->d1->next_timeout); }
int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { if (!SSL_is_dtls(ssl)) { return 0; } /* If no timeout is set, just return NULL */ if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { return 0; } struct timeval timenow; ssl_get_current_time(ssl, &timenow); /* If timer already expired, set remaining time to 0 */ 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(struct timeval)); return 1; } /* Calculate time left until timer expires */ memcpy(out, &ssl->d1->next_timeout, sizeof(struct 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 (out->tv_sec == 0 && out->tv_usec < 15000) { memset(out, 0, sizeof(struct timeval)); } return 1; }
int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server) { SSL *const ssl = hs->ssl; if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) { OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED); return 0; } SSL_SESSION *session = ssl_session_new(ssl->ctx->x509_method); if (session == NULL) { return 0; } session->is_server = is_server; session->ssl_version = ssl->version; /* Fill in the time from the |SSL_CTX|'s clock. */ struct OPENSSL_timeval now; ssl_get_current_time(ssl, &now); session->time = now.tv_sec; uint16_t version = ssl3_protocol_version(ssl); if (version >= TLS1_3_VERSION) { /* TLS 1.3 uses tickets as authenticators, so we are willing to use them for * longer. */ session->timeout = ssl->session_ctx->session_psk_dhe_timeout; session->auth_timeout = SSL_DEFAULT_SESSION_AUTH_TIMEOUT; } else { /* TLS 1.2 resumption does not incorporate new key material, so we use a * much shorter timeout. */ session->timeout = ssl->session_ctx->session_timeout; session->auth_timeout = ssl->session_ctx->session_timeout; } if (is_server) { if (hs->ticket_expected || version >= TLS1_3_VERSION) { /* Don't set session IDs for sessions resumed with tickets. This will keep * them out of the session cache. */ session->session_id_length = 0; } else { session->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; if (!RAND_bytes(session->session_id, session->session_id_length)) { goto err; } } } else { session->session_id_length = 0; } if (ssl->cert->sid_ctx_length > sizeof(session->sid_ctx)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } OPENSSL_memcpy(session->sid_ctx, ssl->cert->sid_ctx, ssl->cert->sid_ctx_length); session->sid_ctx_length = ssl->cert->sid_ctx_length; /* The session is marked not resumable until it is completely filled in. */ session->not_resumable = 1; session->verify_result = X509_V_ERR_INVALID_CALL; SSL_SESSION_free(hs->new_session); hs->new_session = session; ssl_set_session(ssl, NULL); return 1; err: SSL_SESSION_free(session); return 0; }
static enum ssl_ticket_aead_result_t select_session( SSL_HANDSHAKE *hs, uint8_t *out_alert, SSL_SESSION **out_session, int32_t *out_ticket_age_skew, const SSL_CLIENT_HELLO *client_hello) { SSL *const ssl = hs->ssl; *out_session = NULL; /* Decode the ticket if we agreed on a PSK key exchange mode. */ CBS pre_shared_key; if (!hs->accept_psk_mode || !ssl_client_hello_get_extension(client_hello, &pre_shared_key, TLSEXT_TYPE_pre_shared_key)) { return ssl_ticket_aead_ignore_ticket; } /* Verify that the pre_shared_key extension is the last extension in * ClientHello. */ if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) != client_hello->extensions + client_hello->extensions_len) { OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST); *out_alert = SSL_AD_ILLEGAL_PARAMETER; return ssl_ticket_aead_error; } CBS ticket, binders; uint32_t client_ticket_age; if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &ticket, &binders, &client_ticket_age, out_alert, &pre_shared_key)) { return ssl_ticket_aead_error; } /* TLS 1.3 session tickets are renewed separately as part of the * NewSessionTicket. */ int unused_renew; SSL_SESSION *session = NULL; enum ssl_ticket_aead_result_t ret = ssl_process_ticket(ssl, &session, &unused_renew, CBS_data(&ticket), CBS_len(&ticket), NULL, 0); switch (ret) { case ssl_ticket_aead_success: break; case ssl_ticket_aead_error: *out_alert = SSL_AD_INTERNAL_ERROR; return ret; default: return ret; } if (!ssl_session_is_resumable(hs, session) || /* Historically, some TLS 1.3 tickets were missing ticket_age_add. */ !session->ticket_age_add_valid) { SSL_SESSION_free(session); return ssl_ticket_aead_ignore_ticket; } /* Recover the client ticket age and convert to seconds. */ client_ticket_age -= session->ticket_age_add; client_ticket_age /= 1000; struct OPENSSL_timeval now; ssl_get_current_time(ssl, &now); /* Compute the server ticket age in seconds. */ assert(now.tv_sec >= session->time); uint64_t server_ticket_age = now.tv_sec - session->time; /* To avoid overflowing |hs->ticket_age_skew|, we will not resume * 68-year-old sessions. */ if (server_ticket_age > INT32_MAX) { SSL_SESSION_free(session); return ssl_ticket_aead_ignore_ticket; } /* TODO(davidben,svaldez): Measure this value to decide on tolerance. For * now, accept all values. https://crbug.com/boringssl/113. */ *out_ticket_age_skew = (int32_t)client_ticket_age - (int32_t)server_ticket_age; /* Check the PSK binder. */ if (!tls13_verify_psk_binder(hs, session, &binders)) { SSL_SESSION_free(session); *out_alert = SSL_AD_DECRYPT_ERROR; return ssl_ticket_aead_error; } *out_session = session; return ssl_ticket_aead_success; }