summaryrefslogtreecommitdiffhomepage
path: root/src/event
diff options
context:
space:
mode:
Diffstat (limited to 'src/event')
-rw-r--r--src/event/ngx_event_openssl.c79
-rw-r--r--src/event/ngx_event_openssl_stapling.c9
2 files changed, 57 insertions, 31 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index dc0861ce9..8077f40a9 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -2774,8 +2774,9 @@ ngx_ssl_free_buffer(ngx_connection_t *c)
ngx_int_t
ngx_ssl_shutdown(ngx_connection_t *c)
{
- int n, sslerr, mode;
- ngx_err_t err;
+ int n, sslerr, mode;
+ ngx_err_t err;
+ ngx_uint_t tries;
#if (NGX_QUIC)
if (c->qs) {
@@ -2823,55 +2824,71 @@ ngx_ssl_shutdown(ngx_connection_t *c)
ngx_ssl_clear_error(c->log);
- n = SSL_shutdown(c->ssl->connection);
+ tries = 2;
+
+ for ( ;; ) {
+
+ /*
+ * For bidirectional shutdown, SSL_shutdown() needs to be called
+ * twice: first call sends the "close notify" alert and returns 0,
+ * second call waits for the peer's "close notify" alert.
+ */
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
+ n = SSL_shutdown(c->ssl->connection);
- sslerr = 0;
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
- /* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */
+ if (n == 1) {
+ SSL_free(c->ssl->connection);
+ c->ssl = NULL;
+
+ return NGX_OK;
+ }
+
+ if (n == 0 && tries-- > 1) {
+ continue;
+ }
+
+ /* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */
- if (n != 1 && ERR_peek_error()) {
sslerr = SSL_get_error(c->ssl->connection, n);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL_get_error: %d", sslerr);
- }
- if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
- SSL_free(c->ssl->connection);
- c->ssl = NULL;
+ if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
+ c->read->handler = ngx_ssl_shutdown_handler;
+ c->write->handler = ngx_ssl_shutdown_handler;
- return NGX_OK;
- }
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
- if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
- c->read->handler = ngx_ssl_shutdown_handler;
- c->write->handler = ngx_ssl_shutdown_handler;
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- return NGX_ERROR;
- }
+ ngx_add_timer(c->read, 3000);
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- return NGX_ERROR;
+ return NGX_AGAIN;
}
- if (sslerr == SSL_ERROR_WANT_READ) {
- ngx_add_timer(c->read, 30000);
- }
+ if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
+ SSL_free(c->ssl->connection);
+ c->ssl = NULL;
- return NGX_AGAIN;
- }
+ return NGX_OK;
+ }
- err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
+ err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
- ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
+ ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
- SSL_free(c->ssl->connection);
- c->ssl = NULL;
+ SSL_free(c->ssl->connection);
+ c->ssl = NULL;
- return NGX_ERROR;
+ return NGX_ERROR;
+ }
}
diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c
index 0e79d6cc4..9d92421d6 100644
--- a/src/event/ngx_event_openssl_stapling.c
+++ b/src/event/ngx_event_openssl_stapling.c
@@ -883,6 +883,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
ocsp = ngx_pcalloc(c->pool, sizeof(ngx_ssl_ocsp_t));
if (ocsp == NULL) {
+ X509_free(cert);
return NGX_ERROR;
}
@@ -899,6 +900,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
if (ocsp->certs) {
ocsp->certs = X509_chain_up_ref(ocsp->certs);
if (ocsp->certs == NULL) {
+ X509_free(cert);
return NGX_ERROR;
}
}
@@ -910,6 +912,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
if (store == NULL) {
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
"SSL_CTX_get_cert_store() failed");
+ X509_free(cert);
return NGX_ERROR;
}
@@ -917,6 +920,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
if (store_ctx == NULL) {
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
"X509_STORE_CTX_new() failed");
+ X509_free(cert);
return NGX_ERROR;
}
@@ -926,6 +930,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
"X509_STORE_CTX_init() failed");
X509_STORE_CTX_free(store_ctx);
+ X509_free(cert);
return NGX_ERROR;
}
@@ -933,6 +938,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
if (rc <= 0) {
ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "X509_verify_cert() failed");
X509_STORE_CTX_free(store_ctx);
+ X509_free(cert);
return NGX_ERROR;
}
@@ -941,12 +947,15 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
"X509_STORE_CTX_get1_chain() failed");
X509_STORE_CTX_free(store_ctx);
+ X509_free(cert);
return NGX_ERROR;
}
X509_STORE_CTX_free(store_ctx);
}
+ X509_free(cert);
+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"ssl ocsp validate, certs:%d", sk_X509_num(ocsp->certs));