BBlack has submitted this change and it was merged.
Change subject: Port Filipe da Silva's multicert patches, bump libssl to 1.0.2
......................................................................
Port Filipe da Silva's multicert patches, bump libssl to 1.0.2
Bug: T86654
Change-Id: I4c28c06ddebbcb37a0f3ade35c3a26834df80401
---
M debian/control
A debian/patches/1001-SSL-refactor-and-split-ngx_ssl_certificate-in-two.patch
A debian/patches/1002-SSL-introduce-ngx_ssl_certificate_t-array-list.patch
A debian/patches/1003-Stapling-SSL-add-Multiple-SSL-certificate-support.patch
A debian/patches/1004-Stapling-fixing-indentation.patch
A debian/patches/1005-SSL-add-Multiple-SSL-certificate-support-to-http-mod.patch
A debian/patches/1006-SSL-add-Multiple-SSL-certificate-support-to-other-mo.patch
M debian/patches/series
8 files changed, 1,394 insertions(+), 1 deletion(-)
Approvals:
BBlack: Verified; Looks good to me, approved
diff --git a/debian/control b/debian/control
index b3bfcc3..1548aef 100644
--- a/debian/control
+++ b/debian/control
@@ -20,7 +20,7 @@
libpam0g-dev,
libpcre3-dev,
libperl-dev,
- libssl-dev,
+ libssl-dev (>= 1.0.2),
libxslt1-dev,
po-debconf,
zlib1g-dev
diff --git
a/debian/patches/1001-SSL-refactor-and-split-ngx_ssl_certificate-in-two.patch
b/debian/patches/1001-SSL-refactor-and-split-ngx_ssl_certificate-in-two.patch
new file mode 100644
index 0000000..dadac83
--- /dev/null
+++
b/debian/patches/1001-SSL-refactor-and-split-ngx_ssl_certificate-in-two.patch
@@ -0,0 +1,80 @@
+From 35a3bd2fedf2a821d0e50a7934f32a0bce0bd2a7 Mon Sep 17 00:00:00 2001
+From: Brandon L Black <[email protected]>
+Date: Thu, 18 Jun 2015 14:06:05 +0000
+Subject: [PATCH 2/7] SSL: refactor and split ngx_ssl_certificate in two.
+ Preparation for Multiple SSL certificate support.
+
+These patches are based on the ones from Filipe da Silva here:
+http://mailman.nginx.org/pipermail/nginx-devel/2015-March/006734.html
+00-SplitMethod.diff
+ # HG changeset patch
+ # Parent 953ef81705e1e2d735e956e5fc6406a862e29419
+---
+ src/event/ngx_event_openssl.c | 34 ++++++++++++++++++++++++++++++++--
+ 1 file changed, 32 insertions(+), 2 deletions(-)
+
+diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
+index 1b789e6..3fee271 100644
+--- a/src/event/ngx_event_openssl.c
++++ b/src/event/ngx_event_openssl.c
+@@ -18,6 +18,10 @@ typedef struct {
+ } ngx_openssl_conf_t;
+
+
++static ngx_int_t ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
++ ngx_str_t *cert);
++static ngx_int_t ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl,
++ ngx_str_t *key, ngx_array_t *passwords);
+ static int ngx_ssl_password_callback(char *buf, int size, int rwflag,
+ void *userdata);
+ static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
+@@ -301,11 +305,26 @@ 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)
+ {
++ /* load server certificate */
++ if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
++ /* load private key */
++ if (ngx_ssl_private_key(cf, ssl, key, passwords) != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
++ return NGX_OK;
++}
++
++
++ngx_int_t
++ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert)
++{
+ BIO *bio;
+ X509 *x509;
+ u_long n;
+- ngx_str_t *pwd;
+- ngx_uint_t tries;
+
+ if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
+ return NGX_ERROR;
+@@ -388,6 +407,17 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert,
+
+ BIO_free(bio);
+
++ return NGX_OK;
++}
++
++
++static ngx_int_t
++ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *key,
++ ngx_array_t *passwords)
++{
++ ngx_str_t *pwd;
++ ngx_uint_t tries;
++
+ if (ngx_strncmp(key->data, "engine:", sizeof("engine:") - 1) == 0) {
+
+ #ifndef OPENSSL_NO_ENGINE
+--
+2.1.0
+
diff --git
a/debian/patches/1002-SSL-introduce-ngx_ssl_certificate_t-array-list.patch
b/debian/patches/1002-SSL-introduce-ngx_ssl_certificate_t-array-list.patch
new file mode 100644
index 0000000..55ec7ce
--- /dev/null
+++ b/debian/patches/1002-SSL-introduce-ngx_ssl_certificate_t-array-list.patch
@@ -0,0 +1,234 @@
+From bd83ca9aaf28e2f5a8efe941208a99d624206f82 Mon Sep 17 00:00:00 2001
+From: Brandon L Black <[email protected]>
+Date: Thu, 18 Jun 2015 14:08:17 +0000
+Subject: [PATCH 3/7] SSL: introduce ngx_ssl_certificate_t array list.
+ Preparation for Multi Server-Cert support.
+
+These patches are based on the ones from Filipe da Silva here:
+http://mailman.nginx.org/pipermail/nginx-devel/2015-March/006734.html
+01-AddCertList.diff
+ # HG changeset patch
+ # Parent 7f818f872a33fa2ab0c09942a17901a10bc8acf7
+---
+ src/event/ngx_event_openssl.c | 71 +++++++++++++++++++++++++++++++---
+ src/event/ngx_event_openssl.h | 5 +++
+ src/event/ngx_event_openssl_stapling.c | 41 ++++++++++++++++++--
+ 3 files changed, 108 insertions(+), 9 deletions(-)
+
+diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
+index 3fee271..54507b9 100644
+--- a/src/event/ngx_event_openssl.c
++++ b/src/event/ngx_event_openssl.c
+@@ -18,6 +18,10 @@ typedef struct {
+ } ngx_openssl_conf_t;
+
+
++static ngx_int_t ngx_ssl_certificate_init(ngx_conf_t *cf, ngx_ssl_t *ssl,
++ ngx_uint_t nbcerts);
++static ngx_uint_t ngx_ssl_certificate_push(ngx_conf_t *cf, ngx_ssl_t *ssl,
++ X509 * x509);
+ static ngx_int_t ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
+ ngx_str_t *cert);
+ static ngx_int_t ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl,
+@@ -301,10 +305,57 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols,
void *data)
+ }
+
+
++ngx_int_t
++ngx_ssl_certificate_init(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t nbcerts)
++{
++ ngx_array_t *certificates;
++
++ certificates = ngx_array_create(cf->pool, nbcerts,
++ sizeof(ngx_ssl_certificate_t));
++ if (certificates == NULL) {
++ return NGX_ERROR;
++ }
++
++ if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, certificates)
++ == 0)
++ {
++ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
++ "SSL_CTX_set_ex_data() failed");
++ return NGX_ERROR;
++ }
++
++ return NGX_OK;
++}
++
++
++ngx_uint_t
++ngx_ssl_certificate_push(ngx_conf_t *cf, ngx_ssl_t *ssl, X509 * x509)
++{
++ ngx_array_t *certificates;
++ ngx_ssl_certificate_t *cert;
++
++ certificates = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
++
++ cert = ngx_array_push(certificates);
++ if (cert == NULL) {
++ return -1;
++ }
++
++ cert->x509 = x509;
++
++ return certificates->nelts;
++}
++
++
+ 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)
+ {
++ /* Init server certificate list */
++ if (ngx_ssl_certificate_init(cf, ssl, 1U) != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
+ /* load server certificate */
+ if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK)
+ {
+@@ -325,6 +376,7 @@ ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert)
+ BIO *bio;
+ X509 *x509;
+ u_long n;
++ ngx_uint_t count;
+
+ if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
+ return NGX_ERROR;
+@@ -359,11 +411,8 @@ ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t
*ssl, ngx_str_t *cert)
+ return NGX_ERROR;
+ }
+
+- if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509)
+- == 0)
+- {
+- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+- "SSL_CTX_set_ex_data() failed");
++ /* store cert for future use in stapling and sessions */
++ if ((count = ngx_ssl_certificate_push(cf, ssl, x509)) <= 0) {
+ X509_free(x509);
+ BIO_free(bio);
+ return NGX_ERROR;
+@@ -2161,6 +2210,9 @@ ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t
*sess_ctx)
+ STACK_OF(X509_NAME) *list;
+ u_char buf[EVP_MAX_MD_SIZE];
+
++ ngx_array_t *certificates;
++ ngx_ssl_certificate_t *certificate;
++
+ /*
+ * Session ID context is set based on the string provided,
+ * the server certificate, and the client CA list.
+@@ -2180,7 +2232,14 @@ ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t
*sess_ctx)
+ goto failed;
+ }
+
+- cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
++ certificates = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
++ if (!certificates || certificates->nelts == 0) {
++ goto failed;
++ }
++ certificate = certificates->elts;
++
++ /* TOFIX: not only use just first one */
++ cert = certificate[0].x509;
+
+ if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
+index 08eff64..004100c 100644
+--- a/src/event/ngx_event_openssl.h
++++ b/src/event/ngx_event_openssl.h
+@@ -45,6 +45,11 @@ typedef struct {
+
+
+ typedef struct {
++ X509 *x509;
++} ngx_ssl_certificate_t;
++
++
++typedef struct {
+ ngx_ssl_conn_t *connection;
+
+ ngx_int_t last;
+diff --git a/src/event/ngx_event_openssl_stapling.c
b/src/event/ngx_event_openssl_stapling.c
+index 60051ad..5971668 100644
+--- a/src/event/ngx_event_openssl_stapling.c
++++ b/src/event/ngx_event_openssl_stapling.c
+@@ -86,6 +86,10 @@ struct ngx_ssl_ocsp_ctx_s {
+ static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl,
+ ngx_str_t *file);
+ static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl);
++static ngx_int_t ngx_ssl_stapling_issuer_lookup(ngx_conf_t *cf,
++ ngx_ssl_t *ssl, ngx_ssl_certificate_t *certificate);
++static ngx_int_t ngx_ssl_stapling_certid_push(ngx_ssl_stapling_t *staple,
++ X509 *cert, X509 *issuer);
+ static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl,
+ ngx_str_t *responder);
+
+@@ -261,6 +265,29 @@ failed:
+ static ngx_int_t
+ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+ {
++ ngx_array_t *certificates;
++ ngx_ssl_certificate_t *certificate;
++
++ certificates = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
++ if (!certificates || certificates->nelts == 0) {
++ return NGX_ERROR;
++ }
++
++ /* TOFIX: not only use just first one */
++ certificate = certificates->elts;
++
++ if (ngx_ssl_stapling_issuer_lookup(cf, ssl, certificate) != NGX_OK) {
++ return NGX_ERROR;
++ }
++
++ return NGX_OK;
++}
++
++
++static ngx_int_t
++ngx_ssl_stapling_issuer_lookup(ngx_conf_t *cf, ngx_ssl_t *ssl,
++ ngx_ssl_certificate_t *certificate)
++{
+ int i, n, rc;
+ X509 *cert, *issuer;
+ X509_STORE *store;
+@@ -269,7 +296,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+ 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 = certificate->x509;
+
+ #if OPENSSL_VERSION_NUMBER >= 0x10001000L
+ SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain);
+@@ -290,8 +317,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
+ "SSL get issuer: found %p in extra certs", issuer);
+
+- staple->cert = cert;
+- staple->issuer = issuer;
++ ngx_ssl_stapling_certid_push(staple, cert, issuer);
+
+ return NGX_OK;
+ }
+@@ -339,6 +365,15 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
+ "SSL get issuer: found %p in cert store", issuer);
+
++ ngx_ssl_stapling_certid_push(staple, cert, issuer);
++
++ return NGX_OK;
++}
++
++
++static ngx_int_t ngx_ssl_stapling_certid_push(ngx_ssl_stapling_t *staple,
++ X509 *cert, X509 *issuer)
++{
+ staple->cert = cert;
+ staple->issuer = issuer;
+
diff --git
a/debian/patches/1003-Stapling-SSL-add-Multiple-SSL-certificate-support.patch
b/debian/patches/1003-Stapling-SSL-add-Multiple-SSL-certificate-support.patch
new file mode 100644
index 0000000..0394ed5
--- /dev/null
+++
b/debian/patches/1003-Stapling-SSL-add-Multiple-SSL-certificate-support.patch
@@ -0,0 +1,252 @@
+From a6b2c78935c88614a2c74870bde8d5b5ed0baa5b Mon Sep 17 00:00:00 2001
+From: Brandon L Black <[email protected]>
+Date: Thu, 18 Jun 2015 14:10:42 +0000
+Subject: [PATCH 4/7] Stapling SSL: add Multiple SSL certificate support.
+ OpenSSL >= 1.0.2 required. Only OCSP responder URL from first certificate
+ will be contacted.
+
+These patches are based on the ones from Filipe da Silva here:
+http://mailman.nginx.org/pipermail/nginx-devel/2015-March/006734.html
+02-AddStaplingCertIssuerList.diff
+ # HG changeset patch
+ # Parent 816e9d420de0e74e86f6cd4cecd578d57fac60e3
+---
+ src/event/ngx_event_openssl_stapling.c | 108 +++++++++++++++++++++++++++------
+ 1 file changed, 89 insertions(+), 19 deletions(-)
+
+diff --git a/src/event/ngx_event_openssl_stapling.c
b/src/event/ngx_event_openssl_stapling.c
+index 5971668..72392a8 100644
+--- a/src/event/ngx_event_openssl_stapling.c
++++ b/src/event/ngx_event_openssl_stapling.c
+@@ -28,8 +28,8 @@ typedef struct {
+
+ SSL_CTX *ssl_ctx;
+
+- X509 *cert;
+- X509 *issuer;
++ ngx_array_t *certs;
++ ngx_array_t *issuers;
+
+ time_t valid;
+ time_t refresh;
+@@ -42,8 +42,8 @@ typedef struct {
+ typedef struct ngx_ssl_ocsp_ctx_s ngx_ssl_ocsp_ctx_t;
+
+ struct ngx_ssl_ocsp_ctx_s {
+- X509 *cert;
+- X509 *issuer;
++ ngx_array_t *certs;
++ ngx_array_t *issuers;
+
+ ngx_uint_t naddrs;
+
+@@ -86,6 +86,8 @@ struct ngx_ssl_ocsp_ctx_s {
+ static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl,
+ ngx_str_t *file);
+ static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl);
++static ngx_int_t ngx_ssl_stapling_issuer_init(ngx_conf_t *cf, ngx_ssl_t *ssl,
++ ngx_int_t nbcerts);
+ static ngx_int_t ngx_ssl_stapling_issuer_lookup(ngx_conf_t *cf,
+ ngx_ssl_t *ssl, ngx_ssl_certificate_t *certificate);
+ static ngx_int_t ngx_ssl_stapling_certid_push(ngx_ssl_stapling_t *staple,
+@@ -263,6 +265,28 @@ failed:
+
+
+ static ngx_int_t
++ngx_ssl_stapling_issuer_init(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_int_t
nbcerts)
++{
++ ngx_ssl_stapling_t *staple;
++
++ staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
++
++ staple->certs = ngx_array_create(cf->pool, nbcerts,
++ sizeof(ngx_ssl_certificate_t));
++
++ staple->issuers = ngx_array_create(cf->pool, nbcerts,
++ sizeof(ngx_ssl_certificate_t));
++
++ if (staple->certs == NULL || staple->issuers == NULL) {
++ staple->certs = staple->issuers = NULL;
++ return NGX_ERROR;
++ }
++
++ return NGX_OK;
++}
++
++
++static ngx_int_t
+ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+ {
+ ngx_array_t *certificates;
+@@ -273,6 +297,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+ return NGX_ERROR;
+ }
+
++ ngx_ssl_stapling_issuer_init(cf, ssl, certificates->nelts);
+ /* TOFIX: not only use just first one */
+ certificate = certificates->elts;
+
+@@ -374,8 +399,19 @@ ngx_ssl_stapling_issuer_lookup(ngx_conf_t *cf, ngx_ssl_t
*ssl,
+ static ngx_int_t ngx_ssl_stapling_certid_push(ngx_ssl_stapling_t *staple,
+ X509 *cert, X509 *issuer)
+ {
+- staple->cert = cert;
+- staple->issuer = issuer;
++ ngx_ssl_certificate_t *item;
++
++ item = ngx_array_push(staple->certs);
++ if (item == NULL) {
++ return NGX_ERROR;
++ }
++ item->x509 = cert;
++
++ item = ngx_array_push(staple->issuers);
++ if (item == NULL) {
++ return NGX_ERROR;
++ }
++ item->x509 = issuer;
+
+ return NGX_OK;
+ }
+@@ -387,15 +423,17 @@ ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t
*ssl, ngx_str_t *responder)
+ ngx_url_t u;
+ char *s;
+ ngx_ssl_stapling_t *staple;
++ ngx_ssl_certificate_t *cert;
+ STACK_OF(OPENSSL_STRING) *aia;
+
+ staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
+
+ if (responder->len == 0) {
+
+- /* extract OCSP responder URL from certificate */
++ /* extract OCSP responder URL from *first* certificate */
++ cert = staple->certs->elts;
+
+- aia = X509_get1_ocsp(staple->cert);
++ aia = X509_get1_ocsp(cert->x509);
+ if (aia == NULL) {
+ ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
+ "\"ssl_stapling\" ignored, "
+@@ -543,8 +581,8 @@ ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple)
+ return;
+ }
+
+- ctx->cert = staple->cert;
+- ctx->issuer = staple->issuer;
++ ctx->certs = staple->certs;
++ ctx->issuers = staple->issuers;
+
+ ctx->addrs = staple->addrs;
+ ctx->host = staple->host;
+@@ -575,6 +613,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
+ size_t len;
+ time_t now, valid;
+ ngx_str_t response;
++ ngx_uint_t i, nelts;
+ X509_STORE *store;
+ STACK_OF(X509) *chain;
+ OCSP_CERTID *id;
+@@ -582,6 +621,8 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
+ OCSP_BASICRESP *basic;
+ ngx_ssl_stapling_t *staple;
+ ASN1_GENERALIZEDTIME *thisupdate, *nextupdate;
++ ngx_ssl_certificate_t *cert;
++ ngx_ssl_certificate_t *issuer;
+
+ staple = ctx->data;
+ now = ngx_time();
+@@ -635,15 +676,25 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
+ #endif
+
+ if (OCSP_basic_verify(basic, chain, store,
+- staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY)
+- != 1)
+- {
++ staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY
++#if OPENSSL_VERSION_NUMBER < 0x10000000L
++ /* ECDSA/SHA-2 signature verification not supported */
++ | OCSP_NOSIGS
++#endif
++ ) != 1)
++ {
+ ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
+ "OCSP_basic_verify() failed");
+ goto error;
+ }
+
+- id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
++ nelts = ctx->certs->nelts;
++ cert = ctx->certs->elts;
++ issuer = ctx->issuers->elts;
++
++ for (i = 0; i < nelts; i++, cert++, issuer++) {
++
++ id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509);
+ if (id == NULL) {
+ ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+ "OCSP_cert_to_id() failed");
+@@ -685,6 +736,8 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
+ }
+
+ OCSP_CERTID_free(id);
++ } /* END OF For each 'cert/issuer' pair */
++
+ OCSP_BASICRESP_free(basic);
+ OCSP_RESPONSE_free(ocsp);
+
+@@ -783,10 +836,16 @@ ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time)
+ static void
+ ngx_ssl_stapling_cleanup(void *data)
+ {
+- ngx_ssl_stapling_t *staple = data;
+-
+- if (staple->issuer) {
+- X509_free(staple->issuer);
++ ngx_uint_t i, nelts;
++ ngx_ssl_stapling_t *staple = data;
++ ngx_ssl_certificate_t *issuer;
++
++ if (staple->issuers) {
++ issuer = staple->issuers->elts;
++ nelts = staple->issuers->nelts;
++ for (i = 0; i < nelts; i++, issuer++) {
++ X509_free(issuer->x509);
++ }
+ }
+
+ if (staple->staple.data) {
+@@ -1199,6 +1258,10 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
+ OCSP_CERTID *id;
+ OCSP_REQUEST *ocsp;
+
++ ngx_uint_t i, nelts;
++ ngx_ssl_certificate_t *cert;
++ ngx_ssl_certificate_t *issuer;
++
+ ocsp = OCSP_REQUEST_new();
+ if (ocsp == NULL) {
+ ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+@@ -1206,7 +1269,13 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
+ return NGX_ERROR;
+ }
+
+- id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
++ nelts = ctx->certs->nelts;
++ cert = ctx->certs->elts;
++ issuer = ctx->issuers->elts;
++
++ for (i = 0; i < nelts; i++, cert++, issuer++) {
++
++ id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509);
+ if (id == NULL) {
+ ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+ "OCSP_cert_to_id() failed");
+@@ -1219,6 +1288,7 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
+ OCSP_CERTID_free(id);
+ goto failed;
+ }
++ } /* END OF For each 'cert/issuer' pair */
+
+ len = i2d_OCSP_REQUEST(ocsp, NULL);
+ if (len <= 0) {
diff --git a/debian/patches/1004-Stapling-fixing-indentation.patch
b/debian/patches/1004-Stapling-fixing-indentation.patch
new file mode 100644
index 0000000..9f3e3c0
--- /dev/null
+++ b/debian/patches/1004-Stapling-fixing-indentation.patch
@@ -0,0 +1,164 @@
+From 4a3e6d915f03d69954961d3d21f6088ce516e196 Mon Sep 17 00:00:00 2001
+From: Brandon L Black <[email protected]>
+Date: Thu, 18 Jun 2015 14:29:24 +0000
+Subject: [PATCH 5/7] Stapling : fixing indentation
+
+NOTE: This was the only patch in this series which didn't apply
+cleanly to 1.9.2. I had to do a pair of fixups for new code added
+since, but they were was trivial (just indented the new code as
+well, so that this is still a whitespace-only commit, aside from
+the (existing) reordering of local variable declarations in one
+file).
+
+These patches are based on the ones from Filipe da Silva here:
+http://mailman.nginx.org/pipermail/nginx-devel/2015-March/006734.html
+03-FixIndentation.diff
+ # HG changeset patch
+ # Parent 3e2f451bd0366149bb0d56782351ad69fd05a9b9
+---
+ src/event/ngx_event_openssl_stapling.c | 103 ++++++++++++++++-----------------
+ 1 file changed, 51 insertions(+), 52 deletions(-)
+
+diff --git a/src/event/ngx_event_openssl_stapling.c
b/src/event/ngx_event_openssl_stapling.c
+index 72392a8..5622b65 100644
+--- a/src/event/ngx_event_openssl_stapling.c
++++ b/src/event/ngx_event_openssl_stapling.c
+@@ -694,48 +694,48 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
+
+ for (i = 0; i < nelts; i++, cert++, issuer++) {
+
+- id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509);
+- if (id == NULL) {
+- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+- "OCSP_cert_to_id() failed");
+- goto error;
+- }
+-
+- if (OCSP_resp_find_status(basic, id, &n, NULL, NULL,
+- &thisupdate, &nextupdate)
+- != 1)
+- {
+- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+- "certificate status not found in the OCSP response");
+- goto error;
+- }
+-
+- if (n != V_OCSP_CERTSTATUS_GOOD) {
+- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+- "certificate status \"%s\" in the OCSP response",
+- OCSP_cert_status_str(n));
+- goto error;
+- }
++ id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509);
++ if (id == NULL) {
++ ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
++ "OCSP_cert_to_id() failed");
++ goto error;
++ }
+
+- if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) {
+- ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
+- "OCSP_check_validity() failed");
+- goto error;
+- }
++ if (OCSP_resp_find_status(basic, id, &n, NULL, NULL,
++ &thisupdate, &nextupdate)
++ != 1)
++ {
++ ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
++ "certificate status not found in the OCSP
response");
++ goto error;
++ }
+
+- if (nextupdate) {
+- valid = ngx_ssl_stapling_time(nextupdate);
+- if (valid == (time_t) NGX_ERROR) {
++ if (n != V_OCSP_CERTSTATUS_GOOD) {
+ ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+- "invalid nextUpdate time in certificate status");
++ "certificate status \"%s\" in the OCSP response",
++ OCSP_cert_status_str(n));
+ goto error;
+ }
+
+- } else {
+- valid = NGX_MAX_TIME_T_VALUE;
+- }
++ if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) {
++ ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
++ "OCSP_check_validity() failed");
++ goto error;
++ }
++
++ if (nextupdate) {
++ valid = ngx_ssl_stapling_time(nextupdate);
++ if (valid == (time_t) NGX_ERROR) {
++ ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
++ "invalid nextUpdate time in certificate
status");
++ goto error;
++ }
++
++ } else {
++ valid = NGX_MAX_TIME_T_VALUE;
++ }
+
+- OCSP_CERTID_free(id);
++ OCSP_CERTID_free(id);
+ } /* END OF For each 'cert/issuer' pair */
+
+ OCSP_BASICRESP_free(basic);
+@@ -1250,15 +1250,14 @@ ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev)
+ static ngx_int_t
+ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
+ {
+- int len;
+- u_char *p;
+- uintptr_t escape;
+- ngx_str_t binary, base64;
+- ngx_buf_t *b;
+- OCSP_CERTID *id;
+- OCSP_REQUEST *ocsp;
+-
++ int len;
++ u_char *p;
++ uintptr_t escape;
+ ngx_uint_t i, nelts;
++ ngx_str_t binary, base64;
++ ngx_buf_t *b;
++ OCSP_CERTID *id;
++ OCSP_REQUEST *ocsp;
+ ngx_ssl_certificate_t *cert;
+ ngx_ssl_certificate_t *issuer;
+
+@@ -1275,19 +1274,19 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
+
+ for (i = 0; i < nelts; i++, cert++, issuer++) {
+
+- id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509);
+- if (id == NULL) {
+- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+- "OCSP_cert_to_id() failed");
+- goto failed;
+- }
++ id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509);
++ if (id == NULL) {
++ ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
++ "OCSP_cert_to_id() failed");
++ goto failed;
++ }
+
+- if (OCSP_request_add0_id(ocsp, id) == NULL) {
+- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+- "OCSP_request_add0_id() failed");
+- OCSP_CERTID_free(id);
+- goto failed;
+- }
++ if (OCSP_request_add0_id(ocsp, id) == NULL) {
++ ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
++ "OCSP_request_add0_id() failed");
++ OCSP_CERTID_free(id);
++ goto failed;
++ }
+ } /* END OF For each 'cert/issuer' pair */
+
+ len = i2d_OCSP_REQUEST(ocsp, NULL);
diff --git
a/debian/patches/1005-SSL-add-Multiple-SSL-certificate-support-to-http-mod.patch
b/debian/patches/1005-SSL-add-Multiple-SSL-certificate-support-to-http-mod.patch
new file mode 100644
index 0000000..a6e2ebe
--- /dev/null
+++
b/debian/patches/1005-SSL-add-Multiple-SSL-certificate-support-to-http-mod.patch
@@ -0,0 +1,279 @@
+From d2d00f06cd89a2a4b856934f1d92a56207911ae4 Mon Sep 17 00:00:00 2001
+From: Brandon L Black <[email protected]>
+Date: Thu, 18 Jun 2015 14:32:18 +0000
+Subject: [PATCH 6/7] SSL: add Multiple SSL certificate support to http module.
+ OpenSSL >= 1.0.2 required.
+
+These patches are based on the ones from Filipe da Silva here:
+http://mailman.nginx.org/pipermail/nginx-devel/2015-March/006734.html
+04-MultiCertSupport.diff
+ # HG changeset patch
+ # Parent 21ada59fc75291c5bc9c6a158261899f763018fc
+---
+ src/event/ngx_event_openssl.c | 48 ++++++++++++++++++++++++++++++++
+ src/event/ngx_event_openssl.h | 2 ++
+ src/event/ngx_event_openssl_stapling.c | 16 ++++++++---
+ src/http/modules/ngx_http_ssl_module.c | 51 ++++++++++++++++++++++++----------
+ src/http/modules/ngx_http_ssl_module.h | 4 +--
+ 5 files changed, 100 insertions(+), 21 deletions(-)
+
+diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
+index 54507b9..37038ae 100644
+--- a/src/event/ngx_event_openssl.c
++++ b/src/event/ngx_event_openssl.c
+@@ -347,6 +347,42 @@ ngx_ssl_certificate_push(ngx_conf_t *cf, ngx_ssl_t *ssl,
X509 * x509)
+ }
+
+
++ngx_int_t
++ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs,
++ ngx_array_t *keys, ngx_array_t *passwords)
++{
++ ngx_uint_t i, j;
++ ngx_str_t *cert;
++ ngx_str_t *key;
++
++ /* Init server certificate list */
++ if (ngx_ssl_certificate_init(cf, ssl, certs->nelts) != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
++
++ /* Load server certificates */
++ cert = certs->elts;
++ for (i = 0; i < certs->nelts; i++, cert++) {
++ if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
++ }
++
++ /* Load private keys */
++ key = keys->elts;
++ for (j = 0; j < keys->nelts; j++, key++) {
++ if (ngx_ssl_private_key(cf, ssl, key, passwords) != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
++ }
++
++ return NGX_OK;
++}
++
++
+ 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)
+@@ -444,10 +480,22 @@ ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t
*ssl, ngx_str_t *cert)
+ 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 (n == 0) { */
++ /* same as count == 1 -> always true, as case is rejected by config
code */
+ 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;
+diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
+index 004100c..fbbbc0c 100644
+--- a/src/event/ngx_event_openssl.h
++++ b/src/event/ngx_event_openssl.h
+@@ -129,6 +129,8 @@ ngx_int_t ngx_ssl_init(ngx_log_t *log);
+ ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data);
+ 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);
++ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl,
++ ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords);
+ ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
+ ngx_str_t *cert, ngx_int_t depth);
+ ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
+diff --git a/src/event/ngx_event_openssl_stapling.c
b/src/event/ngx_event_openssl_stapling.c
+index 5622b65..715390f 100644
+--- a/src/event/ngx_event_openssl_stapling.c
++++ b/src/event/ngx_event_openssl_stapling.c
+@@ -289,6 +289,7 @@ ngx_ssl_stapling_issuer_init(ngx_conf_t *cf, ngx_ssl_t
*ssl, ngx_int_t nbcerts)
+ static ngx_int_t
+ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+ {
++ ngx_uint_t i, nelts;
+ ngx_array_t *certificates;
+ ngx_ssl_certificate_t *certificate;
+
+@@ -297,12 +298,19 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+ return NGX_ERROR;
+ }
+
+- ngx_ssl_stapling_issuer_init(cf, ssl, certificates->nelts);
+- /* TOFIX: not only use just first one */
++ nelts = certificates->nelts;
++ if (ngx_ssl_stapling_issuer_init(cf, ssl, nelts) != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
++
+ certificate = certificates->elts;
+
+- if (ngx_ssl_stapling_issuer_lookup(cf, ssl, certificate) != NGX_OK) {
+- return NGX_ERROR;
++ for (i = 0; i < nelts; i++, certificate++) {
++ if (ngx_ssl_stapling_issuer_lookup(cf, ssl, certificate) != NGX_OK)
++ {
++ return NGX_ERROR;
++ }
+ }
+
+ return NGX_OK;
+diff --git a/src/http/modules/ngx_http_ssl_module.c
b/src/http/modules/ngx_http_ssl_module.c
+index d6a1794..a9d6d0e 100644
+--- a/src/http/modules/ngx_http_ssl_module.c
++++ b/src/http/modules/ngx_http_ssl_module.c
+@@ -81,16 +81,16 @@ static ngx_command_t ngx_http_ssl_commands[] = {
+
+ { ngx_string("ssl_certificate"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+- ngx_conf_set_str_slot,
++ ngx_conf_set_str_array_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+- offsetof(ngx_http_ssl_srv_conf_t, certificate),
++ offsetof(ngx_http_ssl_srv_conf_t, certificates),
+ NULL },
+
+ { ngx_string("ssl_certificate_key"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+- ngx_conf_set_str_slot,
++ ngx_conf_set_str_array_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+- offsetof(ngx_http_ssl_srv_conf_t, certificate_key),
++ offsetof(ngx_http_ssl_srv_conf_t, certificate_keys),
+ NULL },
+
+ { ngx_string("ssl_password_file"),
+@@ -505,8 +505,6 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
+ * set by ngx_pcalloc():
+ *
+ * sscf->protocols = 0;
+- * sscf->certificate = { 0, NULL };
+- * sscf->certificate_key = { 0, NULL };
+ * sscf->dhparam = { 0, NULL };
+ * sscf->ecdh_curve = { 0, NULL };
+ * sscf->client_certificate = { 0, NULL };
+@@ -523,6 +521,8 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
+ sscf->buffer_size = NGX_CONF_UNSET_SIZE;
+ sscf->verify = NGX_CONF_UNSET_UINT;
+ sscf->verify_depth = NGX_CONF_UNSET_UINT;
++ sscf->certificates = NGX_CONF_UNSET_PTR;
++ sscf->certificate_keys = NGX_CONF_UNSET_PTR;
+ sscf->passwords = NGX_CONF_UNSET_PTR;
+ sscf->builtin_session_cache = NGX_CONF_UNSET;
+ sscf->session_timeout = NGX_CONF_UNSET;
+@@ -570,8 +570,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent,
void *child)
+ ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
+ ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
+
+- ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
+- ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key,
"");
++ ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
++ ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
++ NULL);
+
+ ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
+
+@@ -598,7 +599,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent,
void *child)
+
+ if (conf->enable) {
+
+- if (conf->certificate.len == 0) {
++ if (!conf->certificates || conf->certificates->nelts == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate\" is defined for "
+ "the \"ssl\" directive in %s:%ui",
+@@ -606,7 +607,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent,
void *child)
+ return NGX_CONF_ERROR;
+ }
+
+- if (conf->certificate_key.len == 0) {
++ if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate_key\" is defined for "
+ "the \"ssl\" directive in %s:%ui",
+@@ -616,18 +617,38 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void
*parent, void *child)
+
+ } else {
+
+- if (conf->certificate.len == 0) {
++ if (!conf->certificates || conf->certificates->nelts == 0) {
+ return NGX_CONF_OK;
+ }
+
+- if (conf->certificate_key.len == 0) {
++ if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) {
++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
++ "no \"ssl_certificate_key\" is defined "
++ "for certificate \"%V\"", &conf->certificates[0]);
++ return NGX_CONF_ERROR;
++ }
++ if (conf->certificate_keys->nelts < conf->certificates->nelts) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate_key\" is defined "
+- "for certificate \"%V\"", &conf->certificate);
++ "for certificate \"%V\"",
++ &conf->certificates[conf->certificate_keys->nelts]);
+ return NGX_CONF_ERROR;
+ }
+ }
+
++#ifndef SSL_CTX_add0_chain_cert
++ if (conf->certificates->nelts > 1) {
++ /*
++ * no multiple certificates support for OpenSSL < 1.0.2,
++ * so we need to alarm user
++ */
++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
++ "Multiple certificate configured in "
++ "\"ssl_certificate\", but OpenSSL < 1.0.2 used");
++ return NGX_CONF_ERROR;
++ }
++#endif
++
+ if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+@@ -663,8 +684,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent,
void *child)
+ cln->handler = ngx_ssl_cleanup_ctx;
+ cln->data = &conf->ssl;
+
+- if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate,
+- &conf->certificate_key, conf->passwords)
++ if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
++ conf->certificate_keys, conf->passwords)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+diff --git a/src/http/modules/ngx_http_ssl_module.h
b/src/http/modules/ngx_http_ssl_module.h
+index 8e69e9e..d4d1397 100644
+--- a/src/http/modules/ngx_http_ssl_module.h
++++ b/src/http/modules/ngx_http_ssl_module.h
+@@ -32,8 +32,8 @@ typedef struct {
+
+ time_t session_timeout;
+
+- ngx_str_t certificate;
+- ngx_str_t certificate_key;
++ ngx_array_t *certificates;
++ ngx_array_t *certificate_keys;
+ ngx_str_t dhparam;
+ ngx_str_t ecdh_curve;
+ ngx_str_t client_certificate;
diff --git
a/debian/patches/1006-SSL-add-Multiple-SSL-certificate-support-to-other-mo.patch
b/debian/patches/1006-SSL-add-Multiple-SSL-certificate-support-to-other-mo.patch
new file mode 100644
index 0000000..e7df934
--- /dev/null
+++
b/debian/patches/1006-SSL-add-Multiple-SSL-certificate-support-to-other-mo.patch
@@ -0,0 +1,377 @@
+From 46b4de4d5cf5e7996871023af2912f889beb00d4 Mon Sep 17 00:00:00 2001
+From: Brandon L Black <[email protected]>
+Date: Thu, 18 Jun 2015 14:34:01 +0000
+Subject: [PATCH 7/7] SSL: add Multiple SSL certificate support to other
+ modules. OpenSSL >= 1.0.2 required.
+
+These patches are based on the ones from Filipe da Silva here:
+http://mailman.nginx.org/pipermail/nginx-devel/2015-March/006734.html
+05-MultiCertSupport2.patch
+ # HG changeset patch
+ # Parent 4a901ee83540eae0e3e7091bdc1b8d2c6dae33ef
+---
+ src/http/modules/ngx_http_proxy_module.c | 63 +++++++++++++++++++++++---------
+ src/http/modules/ngx_http_uwsgi_module.c | 61 ++++++++++++++++++++++---------
+ src/mail/ngx_mail_ssl_module.c | 32 ++++++++--------
+ src/mail/ngx_mail_ssl_module.h | 4 +-
+ 4 files changed, 108 insertions(+), 52 deletions(-)
+
+diff --git a/src/http/modules/ngx_http_proxy_module.c
b/src/http/modules/ngx_http_proxy_module.c
+index 514c23b..70e8c93 100644
+--- a/src/http/modules/ngx_http_proxy_module.c
++++ b/src/http/modules/ngx_http_proxy_module.c
+@@ -97,8 +97,8 @@ typedef struct {
+ ngx_uint_t ssl_verify_depth;
+ ngx_str_t ssl_trusted_certificate;
+ ngx_str_t ssl_crl;
+- ngx_str_t ssl_certificate;
+- ngx_str_t ssl_certificate_key;
++ ngx_array_t *ssl_certificates;
++ ngx_array_t *ssl_certificate_keys;
+ ngx_array_t *ssl_passwords;
+ #endif
+ } ngx_http_proxy_loc_conf_t;
+@@ -672,16 +672,16 @@ static ngx_command_t ngx_http_proxy_commands[] = {
+
+ { ngx_string("proxy_ssl_certificate"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+- ngx_conf_set_str_slot,
++ ngx_conf_set_str_array_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+- offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate),
++ offsetof(ngx_http_proxy_loc_conf_t, ssl_certificates),
+ NULL },
+
+ { ngx_string("proxy_ssl_certificate_key"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+- ngx_conf_set_str_slot,
++ ngx_conf_set_str_array_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+- offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_key),
++ offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_keys),
+ NULL },
+
+ { ngx_string("proxy_ssl_password_file"),
+@@ -2858,6 +2858,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
+ conf->upstream.ssl_verify = NGX_CONF_UNSET;
+ conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
+ conf->ssl_passwords = NGX_CONF_UNSET_PTR;
++ conf->ssl_certificates = NGX_CONF_UNSET_PTR;
++ conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR;
+ #endif
+
+ /* "proxy_cyclic_temp_file" is disabled */
+@@ -3188,10 +3190,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void
*parent, void *child)
+ prev->ssl_trusted_certificate, "");
+ ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
+
+- ngx_conf_merge_str_value(conf->ssl_certificate,
+- prev->ssl_certificate, "");
+- ngx_conf_merge_str_value(conf->ssl_certificate_key,
+- prev->ssl_certificate_key, "");
++ ngx_conf_merge_ptr_value(conf->ssl_certificates,
++ prev->ssl_certificates, NULL);
++ ngx_conf_merge_ptr_value(conf->ssl_certificate_keys,
++ prev->ssl_certificate_keys, NULL);
++
+ ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
+
+ if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) {
+@@ -4278,6 +4281,7 @@ static ngx_int_t
+ ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
+ {
+ ngx_pool_cleanup_t *cln;
++ ngx_str_t *oddkey;
+
+ plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+ if (plcf->upstream.ssl == NULL) {
+@@ -4300,18 +4304,43 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf,
ngx_http_proxy_loc_conf_t *plcf)
+ cln->handler = ngx_ssl_cleanup_ctx;
+ cln->data = plcf->upstream.ssl;
+
+- if (plcf->ssl_certificate.len) {
++ if (plcf->ssl_certificates && plcf->ssl_certificates->nelts > 0) {
++
++ if (!plcf->ssl_certificate_keys
++ || plcf->ssl_certificate_keys->nelts
++ < plcf->ssl_certificates->nelts)
++ {
++
++ oddkey = plcf->ssl_certificates->elts;
+
+- if (plcf->ssl_certificate_key.len == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+- "no \"proxy_ssl_certificate_key\" is defined "
+- "for certificate \"%V\"", &plcf->ssl_certificate);
++ "no \"proxy_ssl_certificate_key\" is defined for "
++ "ssl certificate \"%V\"",
++ oddkey[(plcf->ssl_certificate_keys)
++ ? plcf->ssl_certificate_keys->nelts
++ : 0]);
++
+ return NGX_ERROR;
+ }
+
+- if (ngx_ssl_certificate(cf, plcf->upstream.ssl,
&plcf->ssl_certificate,
+- &plcf->ssl_certificate_key,
plcf->ssl_passwords)
+- != NGX_OK)
++#ifndef SSL_CTX_add0_chain_cert
++ if (plcf->ssl_certificates->nelts > 1) {
++ /*
++ * no multiple certificates support for OpenSSL < 1.0.2,
++ * so we need to alarm user
++ */
++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
++ "Multiple certificate configured "
++ "in \"proxy_ssl_certificate\", "
++ "but OpenSSL version < 1.0.2 used");
++ return NGX_ERROR;
++ }
++#endif
++
++ if (ngx_ssl_certificates(cf, plcf->upstream.ssl,
plcf->ssl_certificates,
++ plcf->ssl_certificate_keys,
++ plcf->ssl_passwords)
++ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+diff --git a/src/http/modules/ngx_http_uwsgi_module.c
b/src/http/modules/ngx_http_uwsgi_module.c
+index a50c553..96913f1 100644
+--- a/src/http/modules/ngx_http_uwsgi_module.c
++++ b/src/http/modules/ngx_http_uwsgi_module.c
+@@ -54,8 +54,8 @@ typedef struct {
+ ngx_uint_t ssl_verify_depth;
+ ngx_str_t ssl_trusted_certificate;
+ ngx_str_t ssl_crl;
+- ngx_str_t ssl_certificate;
+- ngx_str_t ssl_certificate_key;
++ ngx_array_t *ssl_certificates;
++ ngx_array_t *ssl_certificate_keys;
+ ngx_array_t *ssl_passwords;
+ #endif
+ } ngx_http_uwsgi_loc_conf_t;
+@@ -517,16 +517,16 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
+
+ { ngx_string("uwsgi_ssl_certificate"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+- ngx_conf_set_str_slot,
++ ngx_conf_set_str_array_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+- offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate),
++ offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificates),
+ NULL },
+
+ { ngx_string("uwsgi_ssl_certificate_key"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+- ngx_conf_set_str_slot,
++ ngx_conf_set_str_array_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+- offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_key),
++ offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_keys),
+ NULL },
+
+ { ngx_string("uwsgi_ssl_password_file"),
+@@ -1430,6 +1430,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
+ conf->upstream.ssl_verify = NGX_CONF_UNSET;
+ conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
+ conf->ssl_passwords = NGX_CONF_UNSET_PTR;
++ conf->ssl_certificates = NGX_CONF_UNSET_PTR;
++ conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR;
+ #endif
+
+ /* "uwsgi_cyclic_temp_file" is disabled */
+@@ -1743,11 +1745,10 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void
*parent, void *child)
+ ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
+ prev->ssl_trusted_certificate, "");
+ ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
+-
+- ngx_conf_merge_str_value(conf->ssl_certificate,
+- prev->ssl_certificate, "");
+- ngx_conf_merge_str_value(conf->ssl_certificate_key,
+- prev->ssl_certificate_key, "");
++ ngx_conf_merge_ptr_value(conf->ssl_certificates,
++ prev->ssl_certificates, NULL);
++ ngx_conf_merge_ptr_value(conf->ssl_certificate_keys,
++ prev->ssl_certificate_keys, NULL);
+ ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
+
+ if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) {
+@@ -2284,6 +2285,7 @@ static ngx_int_t
+ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
+ {
+ ngx_pool_cleanup_t *cln;
++ ngx_str_t *oddkey;
+
+ uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+ if (uwcf->upstream.ssl == NULL) {
+@@ -2306,17 +2308,42 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
ngx_http_uwsgi_loc_conf_t *uwcf)
+ cln->handler = ngx_ssl_cleanup_ctx;
+ cln->data = uwcf->upstream.ssl;
+
+- if (uwcf->ssl_certificate.len) {
++ if (uwcf->ssl_certificates && uwcf->ssl_certificates->nelts > 0) {
++
++ if (!uwcf->ssl_certificate_keys
++ || uwcf->ssl_certificate_keys->nelts
++ < uwcf->ssl_certificates->nelts)
++ {
++
++ oddkey = uwcf->ssl_certificates->elts;
+
+- if (uwcf->ssl_certificate_key.len == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+- "no \"uwsgi_ssl_certificate_key\" is defined "
+- "for certificate \"%V\"", &uwcf->ssl_certificate);
++ "no \"uwsgi_ssl_certificate_key\" is defined for "
++ "ssl certificate \"%V\"",
++ oddkey[(uwcf->ssl_certificate_keys)
++ ? uwcf->ssl_certificate_keys->nelts
++ : 0]);
++
+ return NGX_ERROR;
+ }
+
+- if (ngx_ssl_certificate(cf, uwcf->upstream.ssl,
&uwcf->ssl_certificate,
+- &uwcf->ssl_certificate_key,
uwcf->ssl_passwords)
++#ifndef SSL_CTX_add0_chain_cert
++ if (uwcf->ssl_certificates->nelts > 1) {
++ /*
++ * no multiple certificates support for OpenSSL < 1.0.2,
++ * so we need to alarm user
++ */
++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
++ "Multiple certificate configured "
++ "in \"uwsgi_ssl_certificate\", but "
++ "OpenSSL < 1.0.2 used");
++ return NGX_ERROR;
++ }
++#endif
++
++ if (ngx_ssl_certificates(cf, uwcf->upstream.ssl,
uwcf->ssl_certificates,
++ uwcf->ssl_certificate_keys,
++ uwcf->ssl_passwords)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c
+index 1075410..3869243 100644
+--- a/src/mail/ngx_mail_ssl_module.c
++++ b/src/mail/ngx_mail_ssl_module.c
+@@ -73,16 +73,16 @@ static ngx_command_t ngx_mail_ssl_commands[] = {
+
+ { ngx_string("ssl_certificate"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+- ngx_conf_set_str_slot,
++ ngx_conf_set_str_array_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+- offsetof(ngx_mail_ssl_conf_t, certificate),
++ offsetof(ngx_mail_ssl_conf_t, certificates),
+ NULL },
+
+ { ngx_string("ssl_certificate_key"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+- ngx_conf_set_str_slot,
++ ngx_conf_set_str_array_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+- offsetof(ngx_mail_ssl_conf_t, certificate_key),
++ offsetof(ngx_mail_ssl_conf_t, certificate_keys),
+ NULL },
+
+ { ngx_string("ssl_password_file"),
+@@ -238,8 +238,6 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
+ * set by ngx_pcalloc():
+ *
+ * scf->protocols = 0;
+- * scf->certificate = { 0, NULL };
+- * scf->certificate_key = { 0, NULL };
+ * scf->dhparam = { 0, NULL };
+ * scf->ecdh_curve = { 0, NULL };
+ * scf->client_certificate = { 0, NULL };
+@@ -250,6 +248,8 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
+ */
+
+ scf->enable = NGX_CONF_UNSET;
++ scf->certificates = NGX_CONF_UNSET_PTR;
++ scf->certificate_keys = NGX_CONF_UNSET_PTR;
+ scf->starttls = NGX_CONF_UNSET_UINT;
+ scf->passwords = NGX_CONF_UNSET_PTR;
+ scf->prefer_server_ciphers = NGX_CONF_UNSET;
+@@ -290,8 +290,9 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void
*child)
+ ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
+ ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
+
+- ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
+- ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key,
"");
++ ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
++ ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
++ NULL);
+
+ ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
+
+@@ -328,7 +329,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void
*child)
+
+ if (*mode) {
+
+- if (conf->certificate.len == 0) {
++ if (!conf->certificates || conf->certificates->nelts == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate\" is defined for "
+ "the \"%s\" directive in %s:%ui",
+@@ -336,7 +337,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void
*child)
+ return NGX_CONF_ERROR;
+ }
+
+- if (conf->certificate_key.len == 0) {
++ if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate_key\" is defined for "
+ "the \"%s\" directive in %s:%ui",
+@@ -346,15 +347,14 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent,
void *child)
+
+ } else {
+
+- if (conf->certificate.len == 0) {
++ if (!conf->certificates || conf->certificates->nelts == 0) {
+ return NGX_CONF_OK;
+ }
+
+- if (conf->certificate_key.len == 0) {
++ if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate_key\" is defined "
+- "for certificate \"%V\"",
+- &conf->certificate);
++ "for certificate \"%V\"", &conf->certificates[0]);
+ return NGX_CONF_ERROR;
+ }
+ }
+@@ -371,8 +371,8 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void
*child)
+ cln->handler = ngx_ssl_cleanup_ctx;
+ cln->data = &conf->ssl;
+
+- if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate,
+- &conf->certificate_key, conf->passwords)
++ if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
++ conf->certificate_keys, conf->passwords)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+diff --git a/src/mail/ngx_mail_ssl_module.h b/src/mail/ngx_mail_ssl_module.h
+index 296a6a2..0753e26 100644
+--- a/src/mail/ngx_mail_ssl_module.h
++++ b/src/mail/ngx_mail_ssl_module.h
+@@ -35,8 +35,8 @@ typedef struct {
+
+ time_t session_timeout;
+
+- ngx_str_t certificate;
+- ngx_str_t certificate_key;
++ ngx_array_t *certificates;
++ ngx_array_t *certificate_keys;
+ ngx_str_t dhparam;
+ ngx_str_t ecdh_curve;
+ ngx_str_t client_certificate;
+--
+2.1.0
+
diff --git a/debian/patches/series b/debian/patches/series
index 73f535e..86f8eff 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,8 @@
perl-use-dpkg-buildflags.patch
+# 1000-series is forward ports of
http://mailman.nginx.org/pipermail/nginx-devel/2015-March/006734.html cleanly
onto 1.9.2-1+wmf1 baseline
+1001-SSL-refactor-and-split-ngx_ssl_certificate-in-two.patch
+1002-SSL-introduce-ngx_ssl_certificate_t-array-list.patch
+1003-Stapling-SSL-add-Multiple-SSL-certificate-support.patch
+1004-Stapling-fixing-indentation.patch
+1005-SSL-add-Multiple-SSL-certificate-support-to-http-mod.patch
+1006-SSL-add-Multiple-SSL-certificate-support-to-other-mo.patch
--
To view, visit https://gerrit.wikimedia.org/r/224728
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I4c28c06ddebbcb37a0f3ade35c3a26834df80401
Gerrit-PatchSet: 1
Gerrit-Project: operations/software/nginx
Gerrit-Branch: wmf-1.9.3-1
Gerrit-Owner: BBlack <[email protected]>
Gerrit-Reviewer: BBlack <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits