[PATCH 1 of 5] SSL: introduce support of last openssl 1.0.2 features.
Filipe DA SILVA
fdasilva at ingima.com
Mon Apr 27 15:38:57 UTC 2015
Hi,
This is my last version of 'Multiple server certificates support ' patches.
I restaged the changes in a more smart way.
It is more respectful of 'contributing' requirements.
It relies on OpenSSL to maintain a list of server certificates.
It now stores a stapling context within/for each server certificate.
Reviews and comments are welcome.
Regards,
Filipe da Silva
Ingima
---
# HG changeset patch
# User Filipe da Silva <fdasilva at ingima.com>
# Date 1430147821 -7200
# Mon Apr 27 17:17:01 2015 +0200
# Node ID 0ac2a8668f852b604d46ff858199650bd3003fdb
# Parent fc99323a3d790dcc7b87121261b4236d098336de
SSL: introduce support of last openssl 1.0.2 features.
Rely on openSSL 1.0.2 internals to manage the server certificate list and
replace the previous SSL_CTX_ex_data(ngx_ssl_certificate_index, ...) storage.
Add two new server certificate accessor methods to encapsulate this change:
ngx_ssl_get_server_certificate & ngx_ssl_get_next_server_certificate.
Add guards around ngx_ssl_stapling_index init when OCSP stapling is unsupported.
Compatible with 'stable-1.8'.
diff -r fc99323a3d79 -r 0ac2a8668f85 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c Fri Feb 20 15:31:37 2015 +0300
+++ b/src/event/ngx_event_openssl.c Mon Apr 27 17:17:01 2015 +0200
@@ -168,6 +168,7 @@ ngx_ssl_init(ngx_log_t *log)
return NGX_ERROR;
}
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
NULL);
if (ngx_ssl_certificate_index == -1) {
@@ -175,7 +176,9 @@ ngx_ssl_init(ngx_log_t *log)
"SSL_CTX_get_ex_new_index() failed");
return NGX_ERROR;
}
-
+#endif
+
+#if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
ngx_ssl_stapling_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
NULL);
if (ngx_ssl_stapling_index == -1) {
@@ -183,6 +186,7 @@ ngx_ssl_init(ngx_log_t *log)
"SSL_CTX_get_ex_new_index() failed");
return NGX_ERROR;
}
+#endif
return NGX_OK;
}
@@ -297,6 +301,33 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_
}
+X509*
+ngx_ssl_get_server_certificate(ngx_ssl_t *ssl)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ if (SSL_CTX_set_current_cert(ssl->ctx, SSL_CERT_SET_FIRST)) {
+ return (SSL_CTX_get0_certificate(ssl->ctx));
+ }
+ return NULL;
+#else
+
+ return (SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index));
+#endif
+}
+
+
+X509*
+ngx_ssl_get_next_server_certificate(ngx_ssl_t *ssl)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ if (SSL_CTX_set_current_cert(ssl->ctx, SSL_CERT_SET_NEXT)) {
+ return (SSL_CTX_get0_certificate(ssl->ctx));
+ }
+#endif
+ return NULL;
+}
+
+
ngx_int_t
ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
ngx_str_t *key, ngx_array_t *passwords)
@@ -340,6 +371,7 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_
return NGX_ERROR;
}
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509)
== 0)
{
@@ -349,6 +381,7 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_
BIO_free(bio);
return NGX_ERROR;
}
+#endif
X509_free(x509);
@@ -376,10 +409,21 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_
return NGX_ERROR;
}
+#ifdef SSL_CTX_add0_chain_cert
+ /*
+ * OpenSSL >=1.0.2 allows multiple server certificates in a single
+ * SSL_CTX to each have a different chain
+ */
+ if (SSL_CTX_add0_chain_cert(ssl->ctx, x509) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_add0_chain_cert(\"%s\") failed",
+ cert->data);
+#else
if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"SSL_CTX_add_extra_chain_cert(\"%s\") failed",
cert->data);
+#endif
X509_free(x509);
BIO_free(bio);
return NGX_ERROR;
@@ -2150,7 +2194,7 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss
goto failed;
}
- cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
+ cert = ngx_ssl_get_server_certificate(ssl);
if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
diff -r fc99323a3d79 -r 0ac2a8668f85 src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h Fri Feb 20 15:31:37 2015 +0300
+++ b/src/event/ngx_event_openssl.h Mon Apr 27 17:17:01 2015 +0200
@@ -189,6 +189,8 @@ ngx_int_t ngx_ssl_get_fingerprint(ngx_co
ngx_str_t *s);
ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
+X509* ngx_ssl_get_server_certificate(ngx_ssl_t *ssl);
+X509* ngx_ssl_get_next_server_certificate(ngx_ssl_t *ssl);
ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);
@@ -208,7 +210,6 @@ extern int ngx_ssl_connection_index;
extern int ngx_ssl_server_conf_index;
extern int ngx_ssl_session_cache_index;
extern int ngx_ssl_session_ticket_keys_index;
-extern int ngx_ssl_certificate_index;
extern int ngx_ssl_stapling_index;
diff -r fc99323a3d79 -r 0ac2a8668f85 src/event/ngx_event_openssl_stapling.c
--- a/src/event/ngx_event_openssl_stapling.c Fri Feb 20 15:31:37 2015 +0300
+++ b/src/event/ngx_event_openssl_stapling.c Mon Apr 27 17:17:01 2015 +0200
@@ -265,9 +265,11 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf,
ngx_ssl_stapling_t *staple;
staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
- cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
+ cert = ngx_ssl_get_server_certificate(ssl->ctx);
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
+#ifdef SSL_CTX_get0_chain_certs
+ SSL_CTX_get0_chain_certs(ssl->ctx, &chain);
+#elif OPENSSL_VERSION_NUMBER >= 0x10001000L
SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain);
#else
chain = ssl->ctx->extra_certs;
@@ -532,6 +534,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc
u_char *p;
int n;
size_t len;
+ unsigned long flags;
ngx_str_t response;
X509_STORE *store;
STACK_OF(X509) *chain;
@@ -585,15 +588,28 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc
goto error;
}
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
+#ifdef SSL_CTX_get0_chain_certs
+ SSL_CTX_get0_chain_certs(staple->ssl_ctx, &chain);
+#elif OPENSSL_VERSION_NUMBER >= 0x10001000L
SSL_CTX_get_extra_chain_certs(staple->ssl_ctx, &chain);
#else
chain = staple->ssl_ctx->extra_certs;
#endif
- if (OCSP_basic_verify(basic, chain, store,
- staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY)
- != 1)
+ flags = staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY;
+
+#if OPENSSL_VERSION_NUMBER < 0x10000000L
+ /*
+ * ECDSA/SHA-2 signature verification not supported.
+ * Released with OpenSSL 1.0.0 [29 Mar 2010]
+ * *) Add support for dsa-with-SHA224 and dsa-with-SHA256.
+ * See openssl commit 06e2dd037e29f82b92e1d1b9454f1595e602fb94
+ */
+ flags = flags | OCSP_NOSIGS;
+ /* TODO: improve case handling */
+#endif
+
+ if (OCSP_basic_verify(basic, chain, store, flags) != 1)
{
ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
"OCSP_basic_verify() failed");
More information about the nginx-devel
mailing list