[nginx] SSL: added trusted certificates into session id context.
Maxim Dounin
mdounin at mdounin.ru
Mon Mar 24 00:51:06 UTC 2025
details: http://freenginx.org/hg/nginx/rev/48cff1a93a0e
branches:
changeset: 9334:48cff1a93a0e
user: Maxim Dounin <mdounin at mdounin.ru>
date: Sat Mar 08 16:54:10 2025 +0300
description:
SSL: added trusted certificates into session id context.
This ensures that sessions cannot be incorrectly restored between servers
with identical certificates and client certificates, but with different
trusted certificates.
Note that with BoringSSL this applies to SNI-based virtual servers, since
with BoringSSL session resumption happens after the TLS servername
callback, and session id context of the selected virtual server is used
to decide whether the session can be resumed or not.
diffstat:
src/event/ngx_event_openssl.c | 60 ++++++++++++++++++++++++++++++++++++++++++-
src/event/ngx_event_openssl.h | 1 +
2 files changed, 60 insertions(+), 1 deletions(-)
diffs (123 lines):
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -131,6 +131,7 @@ int ngx_ssl_server_conf_index;
int ngx_ssl_session_cache_index;
int ngx_ssl_ticket_keys_index;
int ngx_ssl_ocsp_index;
+int ngx_ssl_trusted_list_index;
int ngx_ssl_certificate_index;
int ngx_ssl_next_certificate_index;
int ngx_ssl_certificate_name_index;
@@ -258,6 +259,14 @@ ngx_ssl_init(ngx_log_t *log)
return NGX_ERROR;
}
+ ngx_ssl_trusted_list_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
+ NULL);
+ if (ngx_ssl_trusted_list_index == -1) {
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+ "SSL_CTX_get_ex_new_index() failed");
+ return NGX_ERROR;
+ }
+
ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
NULL);
if (ngx_ssl_certificate_index == -1) {
@@ -951,6 +960,8 @@ ngx_int_t
ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
ngx_int_t depth)
{
+ STACK_OF(X509_NAME) *list;
+
SSL_CTX_set_verify(ssl->ctx, SSL_CTX_get_verify_mode(ssl->ctx),
ngx_ssl_verify_callback);
@@ -980,6 +991,24 @@ ngx_ssl_trusted_certificate(ngx_conf_t *
ERR_clear_error();
+ if (SSL_CTX_get_verify_mode(ssl->ctx) != SSL_VERIFY_PEER) {
+ return NGX_OK;
+ }
+
+ list = SSL_load_client_CA_file((char *) cert->data);
+
+ if (list == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_load_client_CA_file(\"%s\") failed", cert->data);
+ return NGX_ERROR;
+ }
+
+ if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_trusted_list_index, list) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_set_ex_data() failed");
+ return NGX_ERROR;
+ }
+
return NGX_OK;
}
@@ -3857,6 +3886,28 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss
}
}
+ list = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_trusted_list_index);
+
+ if (list != NULL) {
+ n = sk_X509_NAME_num(list);
+
+ for (i = 0; i < n; i++) {
+ name = sk_X509_NAME_value(list, i);
+
+ if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_NAME_digest() failed");
+ goto failed;
+ }
+
+ if (EVP_DigestUpdate(md, buf, len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "EVP_DigestUpdate() failed");
+ goto failed;
+ }
+ }
+ }
+
if (EVP_DigestFinal_ex(md, buf, &len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestFinal_ex() failed");
@@ -4826,7 +4877,8 @@ ngx_ssl_cleanup_ctx(void *data)
{
ngx_ssl_t *ssl = data;
- X509 *cert, *next;
+ X509 *cert, *next;
+ STACK_OF(X509_NAME) *list;
cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
@@ -4836,6 +4888,12 @@ ngx_ssl_cleanup_ctx(void *data)
cert = next;
}
+ list = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_trusted_list_index);
+
+ if (list) {
+ sk_X509_NAME_pop_free(list, X509_NAME_free);
+ }
+
SSL_CTX_free(ssl->ctx);
}
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -332,6 +332,7 @@ extern int ngx_ssl_server_conf_index;
extern int ngx_ssl_session_cache_index;
extern int ngx_ssl_ticket_keys_index;
extern int ngx_ssl_ocsp_index;
+extern int ngx_ssl_trusted_list_index;
extern int ngx_ssl_certificate_index;
extern int ngx_ssl_next_certificate_index;
extern int ngx_ssl_certificate_name_index;
More information about the nginx-devel
mailing list