Rotate the default ticket encryption key.
The ticket encryption key is rotated automatically once every 24 hours,
unless a key has been configured manually (i.e. using
|SSL_CTX_set_tlsext_ticket_keys|) or one of the custom ticket encryption
methods is used.
Change-Id: I0dfff28b33e58e96b3bbf7f94dcd6d2642f37aec
Reviewed-on: https://boringssl-review.googlesource.com/18924
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 10128d8..026e218 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -357,11 +357,18 @@
}
void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock) {
- if (ssl->ctx->current_time_cb != NULL) {
+ /* TODO(martinkr): Change callers to |ssl_ctx_get_current_time| and drop the
+ * |ssl| arg from |current_time_cb| if possible. */
+ ssl_ctx_get_current_time(ssl->ctx, out_clock);
+}
+
+void ssl_ctx_get_current_time(const SSL_CTX *ctx,
+ struct OPENSSL_timeval *out_clock) {
+ if (ctx->current_time_cb != NULL) {
/* TODO(davidben): Update current_time_cb to use OPENSSL_timeval. See
* https://crbug.com/boringssl/155. */
struct timeval clock;
- ssl->ctx->current_time_cb(ssl, &clock);
+ ctx->current_time_cb(nullptr /* ssl */, &clock);
if (clock.tv_sec < 0) {
assert(0);
out_clock->tv_sec = 0;
@@ -503,13 +510,6 @@
ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
- /* Setup RFC4507 ticket keys */
- if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
- !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
- !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
- ret->options |= SSL_OP_NO_TICKET;
- }
-
/* Disable the auto-chaining feature by default. Once this has stuck without
* problems, the feature will be removed entirely. */
ret->mode = SSL_MODE_NO_AUTO_CHAIN;
@@ -571,6 +571,8 @@
OPENSSL_free(ctx->alpn_client_proto_list);
EVP_PKEY_free(ctx->tlsext_channel_id_private);
OPENSSL_free(ctx->verify_sigalgs);
+ OPENSSL_free(ctx->tlsext_ticket_key_current);
+ OPENSSL_free(ctx->tlsext_ticket_key_prev);
OPENSSL_free(ctx);
}
@@ -1587,10 +1589,18 @@
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
return 0;
}
+
+ /* The default ticket keys are initialized lazily. Trigger a key
+ * rotation to initialize them. */
+ if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) {
+ return 0;
+ }
+
uint8_t *out_bytes = reinterpret_cast<uint8_t *>(out);
- OPENSSL_memcpy(out_bytes, ctx->tlsext_tick_key_name, 16);
- OPENSSL_memcpy(out_bytes + 16, ctx->tlsext_tick_hmac_key, 16);
- OPENSSL_memcpy(out_bytes + 32, ctx->tlsext_tick_aes_key, 16);
+ MutexReadLock lock(&ctx->lock);
+ OPENSSL_memcpy(out_bytes, ctx->tlsext_ticket_key_current->name, 16);
+ OPENSSL_memcpy(out_bytes + 16, ctx->tlsext_ticket_key_current->hmac_key, 16);
+ OPENSSL_memcpy(out_bytes + 32, ctx->tlsext_ticket_key_current->aes_key, 16);
return 1;
}
@@ -1602,10 +1612,22 @@
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
return 0;
}
+ if (!ctx->tlsext_ticket_key_current) {
+ ctx->tlsext_ticket_key_current =
+ (tlsext_ticket_key *)OPENSSL_malloc(sizeof(tlsext_ticket_key));
+ if (!ctx->tlsext_ticket_key_current) {
+ return 0;
+ }
+ }
+ OPENSSL_memset(ctx->tlsext_ticket_key_current, 0, sizeof(tlsext_ticket_key));
const uint8_t *in_bytes = reinterpret_cast<const uint8_t *>(in);
- OPENSSL_memcpy(ctx->tlsext_tick_key_name, in_bytes, 16);
- OPENSSL_memcpy(ctx->tlsext_tick_hmac_key, in_bytes + 16, 16);
- OPENSSL_memcpy(ctx->tlsext_tick_aes_key, in_bytes + 32, 16);
+ OPENSSL_memcpy(ctx->tlsext_ticket_key_current->name, in_bytes, 16);
+ OPENSSL_memcpy(ctx->tlsext_ticket_key_current->hmac_key, in_bytes + 16, 16);
+ OPENSSL_memcpy(ctx->tlsext_ticket_key_current->aes_key, in_bytes + 32, 16);
+ OPENSSL_free(ctx->tlsext_ticket_key_prev);
+ ctx->tlsext_ticket_key_prev = nullptr;
+ /* Disable automatic key rotation. */
+ ctx->tlsext_ticket_key_current->next_rotation_tv_sec = 0;
return 1;
}