summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/event/ngx_event_openssl.c64
-rw-r--r--src/event/ngx_event_openssl.h2
2 files changed, 47 insertions, 19 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index ba66119b0..a7d1080ee 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -3773,6 +3773,7 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
cache->ticket_keys[0].expire = 0;
cache->ticket_keys[1].expire = 0;
+ cache->ticket_keys[2].expire = 0;
cache->fail_time = 0;
@@ -4250,7 +4251,7 @@ ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
return NGX_OK;
}
- keys = ngx_array_create(cf->pool, paths ? paths->nelts : 2,
+ keys = ngx_array_create(cf->pool, paths ? paths->nelts : 3,
sizeof(ngx_ssl_ticket_key_t));
if (keys == NULL) {
return NGX_ERROR;
@@ -4285,9 +4286,13 @@ ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
/* placeholder for keys in shared memory */
- key = ngx_array_push_n(keys, 2);
+ key = ngx_array_push_n(keys, 3);
key[0].shared = 1;
+ key[0].expire = 0;
key[1].shared = 1;
+ key[1].expire = 0;
+ key[2].shared = 1;
+ key[2].expire = 0;
return NGX_OK;
}
@@ -4347,6 +4352,7 @@ ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
}
key->shared = 0;
+ key->expire = 1;
if (size == 48) {
key->size = 48;
@@ -4514,7 +4520,7 @@ ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
/* renew if non-default key */
- if (i != 0) {
+ if (i != 0 && key[i].expire) {
return 2;
}
@@ -4545,9 +4551,21 @@ ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log)
return NGX_OK;
}
+ /*
+ * if we don't need to update expiration of the current key
+ * and the previous key is still needed, don't sync with shared
+ * memory to save some work; in the worst case other worker process
+ * will switch to the next key, but this process will still be able
+ * to decrypt tickets encrypted with it
+ */
+
now = ngx_time();
expire = now + SSL_CTX_get_timeout(ssl_ctx);
+ if (key[0].expire >= expire && key[1].expire >= now) {
+ return NGX_OK;
+ }
+
shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);
cache = shm_zone->data;
@@ -4567,28 +4585,38 @@ ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log)
return NGX_ERROR;
}
- key->shared = 1;
- key->expire = expire;
- key->size = 80;
- ngx_memcpy(key->name, buf, 16);
- ngx_memcpy(key->hmac_key, buf + 16, 32);
- ngx_memcpy(key->aes_key, buf + 48, 32);
+ key[0].shared = 1;
+ key[0].expire = expire;
+ key[0].size = 80;
+ ngx_memcpy(key[0].name, buf, 16);
+ ngx_memcpy(key[0].hmac_key, buf + 16, 32);
+ ngx_memcpy(key[0].aes_key, buf + 48, 32);
ngx_explicit_memzero(&buf, 80);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
"ssl ticket key: \"%*xs\"",
- (size_t) 16, key->name);
+ (size_t) 16, key[0].name);
+
+ /*
+ * copy the current key to the next key, as initialization of
+ * the previous key will replace the current key with the next
+ * key
+ */
+
+ key[2] = key[0];
}
if (key[1].expire < now) {
/*
* if the previous key is no longer needed (or not initialized),
- * replace it with the current key and generate new current key
+ * replace it with the current key, replace the current key with
+ * the next key, and generate new next key
*/
key[1] = key[0];
+ key[0] = key[2];
if (RAND_bytes(buf, 80) != 1) {
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
@@ -4596,18 +4624,18 @@ ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log)
return NGX_ERROR;
}
- key->shared = 1;
- key->expire = expire;
- key->size = 80;
- ngx_memcpy(key->name, buf, 16);
- ngx_memcpy(key->hmac_key, buf + 16, 32);
- ngx_memcpy(key->aes_key, buf + 48, 32);
+ key[2].shared = 1;
+ key[2].expire = 0;
+ key[2].size = 80;
+ ngx_memcpy(key[2].name, buf, 16);
+ ngx_memcpy(key[2].hmac_key, buf + 16, 32);
+ ngx_memcpy(key[2].aes_key, buf + 48, 32);
ngx_explicit_memzero(&buf, 80);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
"ssl ticket key: \"%*xs\"",
- (size_t) 16, key->name);
+ (size_t) 16, key[2].name);
}
/*
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 45d8b78a7..88f91382d 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -160,7 +160,7 @@ typedef struct {
ngx_rbtree_t session_rbtree;
ngx_rbtree_node_t sentinel;
ngx_queue_t expire_queue;
- ngx_ssl_ticket_key_t ticket_keys[2];
+ ngx_ssl_ticket_key_t ticket_keys[3];
time_t fail_time;
} ngx_ssl_session_cache_t;