[nginx] SSL: encrypted certificate keys are exempt from object cache.
noreply at nginx.com
noreply at nginx.com
Fri Jan 17 00:38:02 UTC 2025
details: https://github.com/nginx/nginx/commit/7677d5646aeb761b8b9da5af3eb10c008aae3f90
branches: master
commit: 7677d5646aeb761b8b9da5af3eb10c008aae3f90
user: Sergey Kandaurov <pluknet at nginx.com>
date: Wed, 18 Dec 2024 20:09:58 +0400
description:
SSL: encrypted certificate keys are exempt from object cache.
SSL object cache, as previously introduced in 1.27.2, did not take
into account encrypted certificate keys that might be unexpectedly
fetched from the cache regardless of the matching passphrase. To
avoid this, caching of encrypted certificate keys is now disabled
based on the passphrase callback invocation.
A notable exception is encrypted certificate keys configured without
ssl_password_file. They are loaded once resulting in the passphrase
prompt on startup and reused in other contexts as applicable.
---
src/event/ngx_event_openssl_cache.c | 53 ++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/src/event/ngx_event_openssl_cache.c b/src/event/ngx_event_openssl_cache.c
index 9d1962759..c79f77456 100644
--- a/src/event/ngx_event_openssl_cache.c
+++ b/src/event/ngx_event_openssl_cache.c
@@ -13,6 +13,8 @@
#define NGX_SSL_CACHE_DATA 1
#define NGX_SSL_CACHE_ENGINE 2
+#define NGX_SSL_CACHE_DISABLED (ngx_array_t *) (uintptr_t) -1
+
#define ngx_ssl_cache_get_conf(cycle) \
(ngx_ssl_cache_t *) ngx_get_conf(cycle->conf_ctx, ngx_openssl_cache_module)
@@ -61,6 +63,12 @@ typedef struct {
} ngx_ssl_cache_t;
+typedef struct {
+ ngx_str_t *pwd;
+ unsigned encrypted:1;
+} ngx_ssl_cache_pwd_t;
+
+
static ngx_int_t ngx_ssl_cache_init_key(ngx_pool_t *pool, ngx_uint_t index,
ngx_str_t *path, ngx_ssl_cache_key_t *id);
static ngx_ssl_cache_node_t *ngx_ssl_cache_lookup(ngx_ssl_cache_t *cache,
@@ -228,9 +236,10 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
}
if (value == NULL) {
- value = type->create(&id, err, data);
- if (value == NULL) {
- return NULL;
+ value = type->create(&id, err, &data);
+
+ if (value == NULL || data == NGX_SSL_CACHE_DISABLED) {
+ return value;
}
}
@@ -269,7 +278,7 @@ ngx_ssl_cache_connection_fetch(ngx_pool_t *pool, ngx_uint_t index, char **err,
return NULL;
}
- return ngx_ssl_cache_types[index].create(&id, err, data);
+ return ngx_ssl_cache_types[index].create(&id, err, &data);
}
@@ -472,13 +481,13 @@ ngx_ssl_cache_cert_ref(char **err, void *data)
static void *
ngx_ssl_cache_pkey_create(ngx_ssl_cache_key_t *id, char **err, void *data)
{
- ngx_array_t *passwords = data;
+ ngx_array_t **passwords = data;
- BIO *bio;
- EVP_PKEY *pkey;
- ngx_str_t *pwd;
- ngx_uint_t tries;
- pem_password_cb *cb;
+ BIO *bio;
+ EVP_PKEY *pkey;
+ ngx_uint_t tries;
+ pem_password_cb *cb;
+ ngx_ssl_cache_pwd_t cb_data, *pwd;
if (id->type == NGX_SSL_CACHE_ENGINE) {
@@ -531,12 +540,16 @@ ngx_ssl_cache_pkey_create(ngx_ssl_cache_key_t *id, char **err, void *data)
return NULL;
}
- if (passwords) {
- tries = passwords->nelts;
- pwd = passwords->elts;
+ cb_data.encrypted = 0;
+
+ if (*passwords) {
+ cb_data.pwd = (*passwords)->elts;
+ tries = (*passwords)->nelts;
+ pwd = &cb_data;
cb = ngx_ssl_cache_pkey_password_callback;
} else {
+ cb_data.pwd = NULL;
tries = 1;
pwd = NULL;
cb = NULL;
@@ -552,7 +565,7 @@ ngx_ssl_cache_pkey_create(ngx_ssl_cache_key_t *id, char **err, void *data)
if (tries-- > 1) {
ERR_clear_error();
(void) BIO_reset(bio);
- pwd++;
+ cb_data.pwd++;
continue;
}
@@ -561,6 +574,10 @@ ngx_ssl_cache_pkey_create(ngx_ssl_cache_key_t *id, char **err, void *data)
return NULL;
}
+ if (cb_data.encrypted) {
+ *passwords = NGX_SSL_CACHE_DISABLED;
+ }
+
BIO_free(bio);
return pkey;
@@ -571,7 +588,9 @@ static int
ngx_ssl_cache_pkey_password_callback(char *buf, int size, int rwflag,
void *userdata)
{
- ngx_str_t *pwd = userdata;
+ ngx_ssl_cache_pwd_t *data = userdata;
+
+ ngx_str_t *pwd;
if (rwflag) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
@@ -580,6 +599,10 @@ ngx_ssl_cache_pkey_password_callback(char *buf, int size, int rwflag,
return 0;
}
+ data->encrypted = 1;
+
+ pwd = data->pwd;
+
if (pwd == NULL) {
return 0;
}
More information about the nginx-devel
mailing list