mirror of
https://github.com/nginx/nginx.git
synced 2024-12-22 07:03:27 -06:00
OCSP stapling: avoid sending expired responses (ticket #425).
This commit is contained in:
parent
9984f3053f
commit
cb3dcbb81e
@ -32,6 +32,7 @@ typedef struct {
|
|||||||
X509 *issuer;
|
X509 *issuer;
|
||||||
|
|
||||||
time_t valid;
|
time_t valid;
|
||||||
|
time_t refresh;
|
||||||
|
|
||||||
unsigned verify:1;
|
unsigned verify:1;
|
||||||
unsigned loading:1;
|
unsigned loading:1;
|
||||||
@ -93,6 +94,8 @@ static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn,
|
|||||||
static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple);
|
static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple);
|
||||||
static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx);
|
static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx);
|
||||||
|
|
||||||
|
static time_t ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time);
|
||||||
|
|
||||||
static void ngx_ssl_stapling_cleanup(void *data);
|
static void ngx_ssl_stapling_cleanup(void *data);
|
||||||
|
|
||||||
static ngx_ssl_ocsp_ctx_t *ngx_ssl_ocsp_start(void);
|
static ngx_ssl_ocsp_ctx_t *ngx_ssl_ocsp_start(void);
|
||||||
@ -462,7 +465,9 @@ ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data)
|
|||||||
staple = data;
|
staple = data;
|
||||||
rc = SSL_TLSEXT_ERR_NOACK;
|
rc = SSL_TLSEXT_ERR_NOACK;
|
||||||
|
|
||||||
if (staple->staple.len) {
|
if (staple->staple.len
|
||||||
|
&& staple->valid >= ngx_time())
|
||||||
|
{
|
||||||
/* we have to copy ocsp response as OpenSSL will free it by itself */
|
/* we have to copy ocsp response as OpenSSL will free it by itself */
|
||||||
|
|
||||||
p = OPENSSL_malloc(staple->staple.len);
|
p = OPENSSL_malloc(staple->staple.len);
|
||||||
@ -490,7 +495,7 @@ ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple)
|
|||||||
ngx_ssl_ocsp_ctx_t *ctx;
|
ngx_ssl_ocsp_ctx_t *ctx;
|
||||||
|
|
||||||
if (staple->host.len == 0
|
if (staple->host.len == 0
|
||||||
|| staple->loading || staple->valid >= ngx_time())
|
|| staple->loading || staple->refresh >= ngx_time())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -532,6 +537,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
|||||||
u_char *p;
|
u_char *p;
|
||||||
int n;
|
int n;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
time_t now, valid;
|
||||||
ngx_str_t response;
|
ngx_str_t response;
|
||||||
X509_STORE *store;
|
X509_STORE *store;
|
||||||
STACK_OF(X509) *chain;
|
STACK_OF(X509) *chain;
|
||||||
@ -542,6 +548,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
|||||||
ASN1_GENERALIZEDTIME *thisupdate, *nextupdate;
|
ASN1_GENERALIZEDTIME *thisupdate, *nextupdate;
|
||||||
|
|
||||||
staple = ctx->data;
|
staple = ctx->data;
|
||||||
|
now = ngx_time();
|
||||||
ocsp = NULL;
|
ocsp = NULL;
|
||||||
basic = NULL;
|
basic = NULL;
|
||||||
id = NULL;
|
id = NULL;
|
||||||
@ -629,17 +636,28 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
OCSP_CERTID_free(id);
|
OCSP_CERTID_free(id);
|
||||||
OCSP_BASICRESP_free(basic);
|
OCSP_BASICRESP_free(basic);
|
||||||
OCSP_RESPONSE_free(ocsp);
|
OCSP_RESPONSE_free(ocsp);
|
||||||
|
|
||||||
|
id = NULL;
|
||||||
|
basic = NULL;
|
||||||
|
ocsp = NULL;
|
||||||
|
|
||||||
/* copy the response to memory not in ctx->pool */
|
/* copy the response to memory not in ctx->pool */
|
||||||
|
|
||||||
response.len = len;
|
response.len = len;
|
||||||
response.data = ngx_alloc(response.len, ctx->log);
|
response.data = ngx_alloc(response.len, ctx->log);
|
||||||
|
|
||||||
if (response.data == NULL) {
|
if (response.data == NULL) {
|
||||||
goto done;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_memcpy(response.data, ctx->response->pos, response.len);
|
ngx_memcpy(response.data, ctx->response->pos, response.len);
|
||||||
@ -653,11 +671,15 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
staple->staple = response;
|
staple->staple = response;
|
||||||
|
staple->valid = valid;
|
||||||
|
|
||||||
done:
|
/*
|
||||||
|
* refresh before the response expires,
|
||||||
|
* but not earlier than in 5 minutes, and at least in an hour
|
||||||
|
*/
|
||||||
|
|
||||||
staple->loading = 0;
|
staple->loading = 0;
|
||||||
staple->valid = ngx_time() + 3600; /* ssl_stapling_valid */
|
staple->refresh = ngx_max(ngx_min(valid - 300, now + 3600), now + 300);
|
||||||
|
|
||||||
ngx_ssl_ocsp_done(ctx);
|
ngx_ssl_ocsp_done(ctx);
|
||||||
return;
|
return;
|
||||||
@ -665,7 +687,7 @@ done:
|
|||||||
error:
|
error:
|
||||||
|
|
||||||
staple->loading = 0;
|
staple->loading = 0;
|
||||||
staple->valid = ngx_time() + 300; /* ssl_stapling_err_valid */
|
staple->refresh = now + 300;
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
OCSP_CERTID_free(id);
|
OCSP_CERTID_free(id);
|
||||||
@ -683,6 +705,40 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static time_t
|
||||||
|
ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time)
|
||||||
|
{
|
||||||
|
u_char *value;
|
||||||
|
size_t len;
|
||||||
|
time_t time;
|
||||||
|
BIO *bio;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OpenSSL doesn't provide a way to convert ASN1_GENERALIZEDTIME
|
||||||
|
* into time_t. To do this, we use ASN1_GENERALIZEDTIME_print(),
|
||||||
|
* which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g.,
|
||||||
|
* "Feb 3 00:55:52 2015 GMT"), and parse the result.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bio = BIO_new(BIO_s_mem());
|
||||||
|
if (bio == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fake weekday prepended to match C asctime() format */
|
||||||
|
|
||||||
|
BIO_write(bio, "Tue ", sizeof("Tue ") - 1);
|
||||||
|
ASN1_GENERALIZEDTIME_print(bio, asn1time);
|
||||||
|
len = BIO_get_mem_data(bio, &value);
|
||||||
|
|
||||||
|
time = ngx_parse_http_time(value, len);
|
||||||
|
|
||||||
|
BIO_free(bio);
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ngx_ssl_stapling_cleanup(void *data)
|
ngx_ssl_stapling_cleanup(void *data)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user