[PATCH 1 of 3] SSL: added trusted certificates into session id context
Maxim Dounin
mdounin at mdounin.ru
Sun Mar 9 00:27:40 UTC 2025
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1741442050 -10800
# Sat Mar 08 16:54:10 2025 +0300
# Node ID 48cff1a93a0e8ed50699e9201a805d5e14aab84d
# Parent 1996ea0bc55d2bc950297f9d7990a5b07948f5e2
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.
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