[PATCH 2 of 6] SSL Stapling : ...
Filipe DA SILVA
fdasilva at ingima.com
Thu Apr 16 10:10:17 UTC 2015
# HG changeset patch
# User Filipe da Silva <fdasilva at ingima.com>
# Date 1429178261 -7200
# Thu Apr 16 11:57:41 2015 +0200
# Node ID 85fb1b1e922fd95ef0df3c7f8bc9625af3054002
# Parent d201e4afd59eaf79419836c1dcdec83e141d3f67
SSL Stapling: attach stapling_t context to X509 cert, instead of ssl_ctx.
Keep a common part of stapling config attached to initial SSL_CTX context.
diff -r d201e4afd59e -r 85fb1b1e922f src/event/ngx_event_openssl_stapling.c
--- a/src/event/ngx_event_openssl_stapling.c Thu Apr 16 11:57:41 2015 +0200
+++ b/src/event/ngx_event_openssl_stapling.c Thu Apr 16 11:57:41 2015 +0200
@@ -14,13 +14,23 @@
#if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
+/* OCSP stapling configuration per server */
typedef struct {
+ /* OCSP response to staple from file */
ngx_str_t staple;
ngx_msec_t timeout;
ngx_resolver_t *resolver;
ngx_msec_t resolver_timeout;
+ unsigned verify:1;
+} ngx_ssl_staple_t;
+
+
+/* OCSP stapling context per certificate */
+typedef struct {
+ ngx_str_t staple; /* OCSP response from responder */
+
ngx_addr_t *addrs;
ngx_str_t host;
ngx_str_t uri;
@@ -33,7 +43,6 @@ typedef struct {
time_t valid;
- unsigned verify:1;
unsigned loading:1;
} ngx_ssl_stapling_t;
@@ -53,6 +62,7 @@ struct ngx_ssl_ocsp_ctx_s {
ngx_resolver_t *resolver;
ngx_msec_t resolver_timeout;
+ unsigned verify:1;
ngx_msec_t timeout;
@@ -83,14 +93,15 @@ 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);
+ ngx_str_t *file, ngx_ssl_staple_t *conf);
static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl);
static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *responder);
static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn,
void *data);
-static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple);
+static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple,
+ ngx_ssl_staple_t *conf);
static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx);
static void ngx_ssl_stapling_cleanup(void *data);
@@ -119,23 +130,14 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl
ngx_str_t *responder, ngx_uint_t verify)
{
ngx_int_t rc;
- ngx_pool_cleanup_t *cln;
- ngx_ssl_stapling_t *staple;
+ ngx_ssl_staple_t *conf;
- staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t));
- if (staple == NULL) {
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_staple_t));
+ if (conf == NULL) {
return NGX_ERROR;
}
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->handler = ngx_ssl_stapling_cleanup;
- cln->data = staple;
-
- if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_stapling_index, staple)
+ if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_stapling_index, conf)
== 0)
{
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
@@ -143,14 +145,13 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl
return NGX_ERROR;
}
- staple->ssl_ctx = ssl->ctx;
- staple->timeout = 60000;
- staple->verify = verify;
+ conf->timeout = 60000;
+ conf->verify = verify;
if (file->len) {
/* use OCSP response from the file */
- if (ngx_ssl_stapling_file(cf, ssl, file) != NGX_OK) {
+ if (ngx_ssl_stapling_file(cf, ssl, file, conf) != NGX_OK) {
return NGX_ERROR;
}
@@ -180,22 +181,20 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl
done:
SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback);
- SSL_CTX_set_tlsext_status_arg(ssl->ctx, staple);
+ SSL_CTX_set_tlsext_status_arg(ssl->ctx, conf);
return NGX_OK;
}
static ngx_int_t
-ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
+ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
+ ngx_ssl_staple_t *conf)
{
BIO *bio;
int len;
u_char *p, *buf;
OCSP_RESPONSE *response;
- ngx_ssl_stapling_t *staple;
-
- staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
return NGX_ERROR;
@@ -223,7 +222,8 @@ ngx_ssl_stapling_file(ngx_conf_t *cf, ng
goto failed;
}
- buf = ngx_alloc(len, ssl->log);
+ /* File content buffer allocated from pool to avoid additional cleanup */
+ buf = ngx_palloc(cf->pool, len);
if (buf == NULL) {
goto failed;
}
@@ -240,8 +240,8 @@ ngx_ssl_stapling_file(ngx_conf_t *cf, ng
OCSP_RESPONSE_free(response);
BIO_free(bio);
- staple->staple.data = buf;
- staple->staple.len = len;
+ conf->staple.data = buf;
+ conf->staple.len = len;
return NGX_OK;
@@ -263,9 +263,32 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf,
X509_STORE_CTX *store_ctx;
STACK_OF(X509) *chain;
ngx_ssl_stapling_t *staple;
+ ngx_pool_cleanup_t *cln;
- 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, NGX_SSL_FIRST_CERT);
+
+ staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t));
+ if (staple == NULL) {
+ return NGX_ERROR;
+ }
+
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NGX_ERROR;
+ }
+
+ cln->handler = ngx_ssl_stapling_cleanup;
+ cln->data = staple;
+
+ if (X509_set_ex_data(cert, ngx_ssl_cert_stapling_index, staple)
+ == 0)
+ {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_set_ex_data() failed");
+ return NGX_ERROR;
+ }
+
+ staple->ssl_ctx = ssl->ctx;
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain);
@@ -348,9 +371,11 @@ ngx_ssl_stapling_responder(ngx_conf_t *c
ngx_url_t u;
char *s;
ngx_ssl_stapling_t *staple;
+ X509 *cert;
STACK_OF(OPENSSL_STRING) *aia;
- staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
+ cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_FIRST_CERT);
+ staple = X509_get_ex_data(cert, ngx_ssl_cert_stapling_index);
if (responder->len == 0) {
@@ -435,7 +460,7 @@ ngx_int_t
ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
{
- ngx_ssl_stapling_t *staple;
+ ngx_ssl_staple_t *staple;
staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
@@ -451,41 +476,54 @@ ngx_ssl_certificate_status_callback(ngx_
{
int rc;
u_char *p;
+ ngx_str_t resp;
ngx_connection_t *c;
+ ngx_ssl_staple_t *conf;
ngx_ssl_stapling_t *staple;
+ X509 *cert;
c = ngx_ssl_get_connection(ssl_conn);
+ cert = SSL_get_certificate(ssl_conn);
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL certificate status callback");
- staple = data;
+ staple = X509_get_ex_data(cert, ngx_ssl_cert_stapling_index);
+ conf = data;
rc = SSL_TLSEXT_ERR_NOACK;
+ resp.len = 0;
- if (staple->staple.len) {
- /* we have to copy ocsp response as OpenSSL will free it by itself */
+ if (conf->staple.len) {
+ resp = conf->staple;
+ }
+ else if (staple && staple->staple.len) {
+ resp = staple->staple;
+ }
- p = OPENSSL_malloc(staple->staple.len);
+ if (resp.len) {
+ /* We have to copy ocsp response as OpenSSL will free it by itself */
+ p = OPENSSL_malloc(resp.len);
if (p == NULL) {
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "OPENSSL_malloc() failed");
return SSL_TLSEXT_ERR_NOACK;
}
- ngx_memcpy(p, staple->staple.data, staple->staple.len);
+ ngx_memcpy(p, resp.data, resp.len);
- SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, staple->staple.len);
+ SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, resp.len);
rc = SSL_TLSEXT_ERR_OK;
}
- ngx_ssl_stapling_update(staple);
+ if (staple)
+ ngx_ssl_stapling_update(staple, conf);
return rc;
}
static void
-ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple)
+ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple, ngx_ssl_staple_t *conf)
{
ngx_ssl_ocsp_ctx_t *ctx;
@@ -509,10 +547,10 @@ ngx_ssl_stapling_update(ngx_ssl_stapling
ctx->host = staple->host;
ctx->uri = staple->uri;
ctx->port = staple->port;
- ctx->timeout = staple->timeout;
+ ctx->timeout = conf->timeout;
- ctx->resolver = staple->resolver;
- ctx->resolver_timeout = staple->resolver_timeout;
+ ctx->resolver = conf->resolver;
+ ctx->resolver_timeout = conf->resolver_timeout;
ctx->handler = ngx_ssl_stapling_ocsp_handler;
ctx->data = staple;
@@ -592,7 +630,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc
#endif
if (OCSP_basic_verify(basic, chain, store,
- staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY)
+ ctx->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY)
!= 1)
{
ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
More information about the nginx-devel
mailing list