mirror of
https://github.com/nginx/nginx.git
synced 2024-12-18 21:23:36 -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;
|
||||
|
||||
time_t valid;
|
||||
time_t refresh;
|
||||
|
||||
unsigned verify: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_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 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;
|
||||
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 */
|
||||
|
||||
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;
|
||||
|
||||
if (staple->host.len == 0
|
||||
|| staple->loading || staple->valid >= ngx_time())
|
||||
|| staple->loading || staple->refresh >= ngx_time())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -532,6 +537,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
||||
u_char *p;
|
||||
int n;
|
||||
size_t len;
|
||||
time_t now, valid;
|
||||
ngx_str_t response;
|
||||
X509_STORE *store;
|
||||
STACK_OF(X509) *chain;
|
||||
@ -542,6 +548,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
||||
ASN1_GENERALIZEDTIME *thisupdate, *nextupdate;
|
||||
|
||||
staple = ctx->data;
|
||||
now = ngx_time();
|
||||
ocsp = NULL;
|
||||
basic = NULL;
|
||||
id = NULL;
|
||||
@ -629,17 +636,28 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
||||
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_BASICRESP_free(basic);
|
||||
OCSP_RESPONSE_free(ocsp);
|
||||
|
||||
id = NULL;
|
||||
basic = NULL;
|
||||
ocsp = NULL;
|
||||
|
||||
/* copy the response to memory not in ctx->pool */
|
||||
|
||||
response.len = len;
|
||||
response.data = ngx_alloc(response.len, ctx->log);
|
||||
|
||||
if (response.data == NULL) {
|
||||
goto done;
|
||||
goto error;
|
||||
}
|
||||
|
||||
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->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->valid = ngx_time() + 3600; /* ssl_stapling_valid */
|
||||
staple->refresh = ngx_max(ngx_min(valid - 300, now + 3600), now + 300);
|
||||
|
||||
ngx_ssl_ocsp_done(ctx);
|
||||
return;
|
||||
@ -665,7 +687,7 @@ done:
|
||||
error:
|
||||
|
||||
staple->loading = 0;
|
||||
staple->valid = ngx_time() + 300; /* ssl_stapling_err_valid */
|
||||
staple->refresh = now + 300;
|
||||
|
||||
if (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
|
||||
ngx_ssl_stapling_cleanup(void *data)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user