mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 17:52:38 +08:00
SSL: made it possible to iterate though all certificates.
A pointer to a previously configured certificate now stored in a certificate. This makes it possible to iterate though all certificates configured in the SSL context. This is now used to configure OCSP stapling for all certificates, and in ngx_ssl_session_id_context(). As SSL_CTX_use_certificate() frees previously loaded certificate of the same type, and we have no way to find out if it's the case, X509_free() calls are now posponed till ngx_ssl_cleanup_ctx(). Note that in OpenSSL 1.0.2+ this can be done without storing things in exdata using the SSL_CTX_set_current_cert() and SSL_CTX_get0_certificate() functions. These are not yet available in all supported versions though, so it's easier to continue to use exdata for now.
This commit is contained in:
parent
503b3569b9
commit
e844475905
@ -105,6 +105,7 @@ int ngx_ssl_server_conf_index;
|
|||||||
int ngx_ssl_session_cache_index;
|
int ngx_ssl_session_cache_index;
|
||||||
int ngx_ssl_session_ticket_keys_index;
|
int ngx_ssl_session_ticket_keys_index;
|
||||||
int ngx_ssl_certificate_index;
|
int ngx_ssl_certificate_index;
|
||||||
|
int ngx_ssl_next_certificate_index;
|
||||||
int ngx_ssl_stapling_index;
|
int ngx_ssl_stapling_index;
|
||||||
|
|
||||||
|
|
||||||
@ -187,6 +188,13 @@ ngx_ssl_init(ngx_log_t *log)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_ssl_next_certificate_index = X509_get_ex_new_index(0, NULL, NULL, NULL,
|
||||||
|
NULL);
|
||||||
|
if (ngx_ssl_next_certificate_index == -1) {
|
||||||
|
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ngx_ssl_stapling_index = X509_get_ex_new_index(0, NULL, NULL, NULL, NULL);
|
ngx_ssl_stapling_index = X509_get_ex_new_index(0, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
if (ngx_ssl_stapling_index == -1) {
|
if (ngx_ssl_stapling_index == -1) {
|
||||||
@ -214,6 +222,12 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, NULL) == 0) {
|
||||||
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
|
"SSL_CTX_set_ex_data() failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ssl->buffer_size = NGX_SSL_BUFSIZE;
|
ssl->buffer_size = NGX_SSL_BUFSIZE;
|
||||||
|
|
||||||
/* client side options */
|
/* client side options */
|
||||||
@ -350,6 +364,16 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (X509_set_ex_data(x509, ngx_ssl_next_certificate_index,
|
||||||
|
SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index))
|
||||||
|
== 0)
|
||||||
|
{
|
||||||
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_set_ex_data() failed");
|
||||||
|
X509_free(x509);
|
||||||
|
BIO_free(bio);
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509)
|
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509)
|
||||||
== 0)
|
== 0)
|
||||||
{
|
{
|
||||||
@ -360,8 +384,6 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
X509_free(x509);
|
|
||||||
|
|
||||||
/* read rest of the chain */
|
/* read rest of the chain */
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
@ -2163,7 +2185,7 @@ ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Session ID context is set based on the string provided,
|
* Session ID context is set based on the string provided,
|
||||||
* the server certificate, and the client CA list.
|
* the server certificates, and the client CA list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
md = EVP_MD_CTX_create();
|
md = EVP_MD_CTX_create();
|
||||||
@ -2183,8 +2205,10 @@ ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
|
for (cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
|
||||||
|
cert;
|
||||||
|
cert = X509_get_ex_data(cert, ngx_ssl_next_certificate_index))
|
||||||
|
{
|
||||||
if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
|
if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
"X509_digest() failed");
|
"X509_digest() failed");
|
||||||
@ -2196,6 +2220,7 @@ ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx)
|
|||||||
"EVP_DigestUpdate() failed");
|
"EVP_DigestUpdate() failed");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list = SSL_CTX_get_client_CA_list(ssl->ctx);
|
list = SSL_CTX_get_client_CA_list(ssl->ctx);
|
||||||
|
|
||||||
@ -2950,6 +2975,16 @@ ngx_ssl_cleanup_ctx(void *data)
|
|||||||
{
|
{
|
||||||
ngx_ssl_t *ssl = data;
|
ngx_ssl_t *ssl = data;
|
||||||
|
|
||||||
|
X509 *cert, *next;
|
||||||
|
|
||||||
|
cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
|
||||||
|
|
||||||
|
while (cert) {
|
||||||
|
next = X509_get_ex_data(cert, ngx_ssl_next_certificate_index);
|
||||||
|
X509_free(cert);
|
||||||
|
cert = next;
|
||||||
|
}
|
||||||
|
|
||||||
SSL_CTX_free(ssl->ctx);
|
SSL_CTX_free(ssl->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +227,7 @@ extern int ngx_ssl_server_conf_index;
|
|||||||
extern int ngx_ssl_session_cache_index;
|
extern int ngx_ssl_session_cache_index;
|
||||||
extern int ngx_ssl_session_ticket_keys_index;
|
extern int ngx_ssl_session_ticket_keys_index;
|
||||||
extern int ngx_ssl_certificate_index;
|
extern int ngx_ssl_certificate_index;
|
||||||
|
extern int ngx_ssl_next_certificate_index;
|
||||||
extern int ngx_ssl_stapling_index;
|
extern int ngx_ssl_stapling_index;
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,13 +126,16 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
|
|||||||
{
|
{
|
||||||
X509 *cert;
|
X509 *cert;
|
||||||
|
|
||||||
cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
|
for (cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
|
||||||
|
cert;
|
||||||
|
cert = X509_get_ex_data(cert, ngx_ssl_next_certificate_index))
|
||||||
|
{
|
||||||
if (ngx_ssl_stapling_certificate(cf, ssl, cert, file, responder, verify)
|
if (ngx_ssl_stapling_certificate(cf, ssl, cert, file, responder, verify)
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback);
|
SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback);
|
||||||
|
|
||||||
@ -455,11 +458,14 @@ ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
|||||||
X509 *cert;
|
X509 *cert;
|
||||||
ngx_ssl_stapling_t *staple;
|
ngx_ssl_stapling_t *staple;
|
||||||
|
|
||||||
cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
|
for (cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
|
||||||
|
cert;
|
||||||
|
cert = X509_get_ex_data(cert, ngx_ssl_next_certificate_index))
|
||||||
|
{
|
||||||
staple = X509_get_ex_data(cert, ngx_ssl_stapling_index);
|
staple = X509_get_ex_data(cert, ngx_ssl_stapling_index);
|
||||||
|
|
||||||
staple->resolver = resolver;
|
staple->resolver = resolver;
|
||||||
staple->resolver_timeout = resolver_timeout;
|
staple->resolver_timeout = resolver_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user