[PATCH 3 of 6] Stapling SSL: add Multiple SSL certificate support

Filipe DA SILVA fdasilva at ingima.com
Thu Apr 9 09:58:38 UTC 2015


# HG changeset patch
# User Filipe da Silva <fdasilva at ingima.com>
# Date 1428570686 -7200
#      Thu Apr 09 11:11:26 2015 +0200
# Node ID f0020df8b2e181edba80ff8956371f9369d9880b
# Parent  16ef1eeccdaa5c4dd3f3acbfebf5801e51a418c4
SSL: introduce ngx_ssl_certificate_t array list.
Preparation for Multiple SSL certificate support.

diff -r 16ef1eeccdaa -r f0020df8b2e1 src/event/ngx_event_openssl_stapling.c
--- a/src/event/ngx_event_openssl_stapling.c	Thu Apr 09 11:10:44 2015 +0200
+++ b/src/event/ngx_event_openssl_stapling.c	Thu Apr 09 11:11:26 2015 +0200
@@ -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;
 
@@ -41,8 +41,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;
 
@@ -85,6 +85,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,
@@ -259,6 +261,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;
@@ -269,6 +293,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, 
         return NGX_ERROR;
     }
 
+    ngx_ssl_stapling_issuer_init(cf, ssl, certificates->nelts);
     /* TOFIX: not only use just first one */
     certificate = certificates->elts;
 
@@ -371,8 +396,19 @@ 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;
 }
@@ -384,15 +420,17 @@ ngx_ssl_stapling_responder(ngx_conf_t *c
     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, "
@@ -538,8 +576,8 @@ ngx_ssl_stapling_update(ngx_ssl_stapling
         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;
@@ -569,6 +607,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc
     int                    n;
     size_t                 len;
     ngx_str_t              response;
+    ngx_uint_t             i, nelts;
     X509_STORE            *store;
     STACK_OF(X509)        *chain;
     OCSP_CERTID           *id;
@@ -576,6 +615,8 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc
     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;
     ocsp = NULL;
@@ -628,15 +669,25 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc
 #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");
@@ -666,6 +717,10 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc
     }
 
     OCSP_CERTID_free(id);
+
+    /* END OF 'for (i = 0;...' LOOP */
+    }
+
     OCSP_BASICRESP_free(basic);
     OCSP_RESPONSE_free(ocsp);
 
@@ -722,10 +777,16 @@ error:
 static void
 ngx_ssl_stapling_cleanup(void *data)
 {
-    ngx_ssl_stapling_t  *staple = data;
+    ngx_uint_t              i, nelts;
+    ngx_ssl_stapling_t     *staple = data;
+    ngx_ssl_certificate_t  *issuer;
 
-    if (staple->issuer) {
-        X509_free(staple->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) {
@@ -1138,6 +1199,10 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp
     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,
@@ -1145,7 +1210,13 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp
         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");
@@ -1159,6 +1230,9 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp
         goto failed;
     }
 
+    /* END OF for ... LOOP */
+    }
+
     len = i2d_OCSP_REQUEST(ocsp, NULL);
     if (len <= 0) {
         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nginx_MultiCert_098.patch
Type: application/octet-stream
Size: 7738 bytes
Desc: nginx_MultiCert_098.patch
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20150409/2dcfc10e/attachment.obj>


More information about the nginx-devel mailing list