summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event/ngx_event_openssl.c58
-rw-r--r--src/event/ngx_event_openssl_cache.c17
2 files changed, 63 insertions, 12 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 375d58be6..1a29f0e75 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -458,10 +458,18 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
{
char *err;
X509 *x509, **elm;
+ u_long n;
EVP_PKEY *pkey;
+ ngx_uint_t mask;
STACK_OF(X509) *chain;
- chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT, &err, cert, NULL);
+ mask = 0;
+ elm = NULL;
+
+retry:
+
+ chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT | mask,
+ &err, cert, NULL);
if (chain == NULL) {
if (err != NULL) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
@@ -501,11 +509,16 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
}
}
- elm = ngx_array_push(&ssl->certs);
if (elm == NULL) {
- X509_free(x509);
- sk_X509_pop_free(chain, X509_free);
- return NGX_ERROR;
+ elm = ngx_array_push(&ssl->certs);
+ if (elm == NULL) {
+ X509_free(x509);
+ sk_X509_pop_free(chain, X509_free);
+ return NGX_ERROR;
+ }
+
+ } else {
+ X509_free(*elm);
}
*elm = x509;
@@ -528,11 +541,21 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
}
#else
- {
- int n;
/* SSL_CTX_set0_chain() is only available in OpenSSL 1.0.2+ */
+#ifdef SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS
+ /* OpenSSL 1.0.1+ */
+ SSL_CTX_clear_extra_chain_certs(ssl->ctx);
+#else
+
+ if (ssl->ctx->extra_certs) {
+ sk_X509_pop_free(ssl->ctx->extra_certs, X509_free);
+ ssl->ctx->extra_certs = NULL;
+ }
+
+#endif
+
n = sk_X509_num(chain);
while (n--) {
@@ -548,10 +571,11 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
}
sk_X509_free(chain);
- }
+
#endif
- pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY, &err, key, passwords);
+ pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY | mask,
+ &err, key, passwords);
if (pkey == NULL) {
if (err != NULL) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
@@ -563,9 +587,23 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
}
if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
+ EVP_PKEY_free(pkey);
+
+ /* there can be mismatched pairs on uneven cache update */
+
+ n = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(n) == ERR_LIB_X509
+ && ERR_GET_REASON(n) == X509_R_KEY_VALUES_MISMATCH
+ && mask == 0)
+ {
+ ERR_clear_error();
+ mask = NGX_SSL_CACHE_INVALIDATE;
+ goto retry;
+ }
+
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"SSL_CTX_use_PrivateKey(\"%s\") failed", key->data);
- EVP_PKEY_free(pkey);
return NGX_ERROR;
}
diff --git a/src/event/ngx_event_openssl_cache.c b/src/event/ngx_event_openssl_cache.c
index 42f5e1c9f..61fceed7b 100644
--- a/src/event/ngx_event_openssl_cache.c
+++ b/src/event/ngx_event_openssl_cache.c
@@ -193,6 +193,7 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
time_t mtime;
uint32_t hash;
ngx_int_t rc;
+ ngx_uint_t invalidate;
ngx_file_uniq_t uniq;
ngx_file_info_t fi;
ngx_ssl_cache_t *cache, *old_cache;
@@ -202,10 +203,17 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
*err = NULL;
+ invalidate = index & NGX_SSL_CACHE_INVALIDATE;
+ index &= ~NGX_SSL_CACHE_INVALIDATE;
+
if (ngx_ssl_cache_init_key(cf->pool, index, path, &id) != NGX_OK) {
return NULL;
}
+ if (id.type == NGX_SSL_CACHE_DATA) {
+ invalidate = 0;
+ }
+
cache = (ngx_ssl_cache_t *) ngx_get_conf(cf->cycle->conf_ctx,
ngx_openssl_cache_module);
@@ -215,7 +223,12 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
cn = ngx_ssl_cache_lookup(cache, type, &id, hash);
if (cn != NULL) {
- return type->ref(err, cn->value);
+ if (!invalidate) {
+ return type->ref(err, cn->value);
+ }
+
+ type->free(cn->value);
+ ngx_rbtree_delete(&cache->rbtree, &cn->node);
}
value = NULL;
@@ -236,7 +249,7 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
old_cache = ngx_ssl_cache_get_old_conf(cf->cycle);
- if (old_cache && old_cache->inheritable) {
+ if (old_cache && old_cache->inheritable && !invalidate) {
cn = ngx_ssl_cache_lookup(old_cache, type, &id, hash);
if (cn != NULL) {