Changeset 6181:6893a1007a7c in nginx


Ignore:
Timestamp:
06/11/15 17:42:39 (5 years ago)
Author:
Maxim Dounin <mdounin@…>
Branch:
default
Phase:
public
Message:

OCSP stapling: avoid sending expired responses (ticket #425).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/event/ngx_event_openssl_stapling.c

    r6064 r6181  
    3333
    3434    time_t                       valid;
     35    time_t                       refresh;
    3536
    3637    unsigned                     verify:1;
     
    9394static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple);
    9495static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx);
     96
     97static time_t ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time);
    9598
    9699static void ngx_ssl_stapling_cleanup(void *data);
     
    463466    rc = SSL_TLSEXT_ERR_NOACK;
    464467
    465     if (staple->staple.len) {
     468    if (staple->staple.len
     469        && staple->valid >= ngx_time())
     470    {
    466471        /* we have to copy ocsp response as OpenSSL will free it by itself */
    467472
     
    491496
    492497    if (staple->host.len == 0
    493         || staple->loading || staple->valid >= ngx_time())
     498        || staple->loading || staple->refresh >= ngx_time())
    494499    {
    495500        return;
     
    533538    int                    n;
    534539    size_t                 len;
     540    time_t                 now, valid;
    535541    ngx_str_t              response;
    536542    X509_STORE            *store;
     
    543549
    544550    staple = ctx->data;
     551    now = ngx_time();
    545552    ocsp = NULL;
    546553    basic = NULL;
     
    630637    }
    631638
     639    valid = ngx_ssl_stapling_time(nextupdate);
     640    if (valid == (time_t) NGX_ERROR) {
     641        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
     642                      "invalid nextUpdate time in certificate status");
     643        goto error;
     644    }
     645
    632646    OCSP_CERTID_free(id);
    633647    OCSP_BASICRESP_free(basic);
    634648    OCSP_RESPONSE_free(ocsp);
    635649
     650    id = NULL;
     651    basic = NULL;
     652    ocsp = NULL;
     653
    636654    /* copy the response to memory not in ctx->pool */
    637655
     
    640658
    641659    if (response.data == NULL) {
    642         goto done;
     660        goto error;
    643661    }
    644662
     
    654672
    655673    staple->staple = response;
    656 
    657 done:
     674    staple->valid = valid;
     675
     676    /*
     677     * refresh before the response expires,
     678     * but not earlier than in 5 minutes, and at least in an hour
     679     */
    658680
    659681    staple->loading = 0;
    660     staple->valid = ngx_time() + 3600; /* ssl_stapling_valid */
     682    staple->refresh = ngx_max(ngx_min(valid - 300, now + 3600), now + 300);
    661683
    662684    ngx_ssl_ocsp_done(ctx);
     
    666688
    667689    staple->loading = 0;
    668     staple->valid = ngx_time() + 300; /* ssl_stapling_err_valid */
     690    staple->refresh = now + 300;
    669691
    670692    if (id) {
     
    681703
    682704    ngx_ssl_ocsp_done(ctx);
     705}
     706
     707
     708static time_t
     709ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time)
     710{
     711    u_char  *value;
     712    size_t   len;
     713    time_t   time;
     714    BIO     *bio;
     715
     716    /*
     717     * OpenSSL doesn't provide a way to convert ASN1_GENERALIZEDTIME
     718     * into time_t.  To do this, we use ASN1_GENERALIZEDTIME_print(),
     719     * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g.,
     720     * "Feb  3 00:55:52 2015 GMT"), and parse the result.
     721     */
     722
     723    bio = BIO_new(BIO_s_mem());
     724    if (bio == NULL) {
     725        return NGX_ERROR;
     726    }
     727
     728    /* fake weekday prepended to match C asctime() format */
     729
     730    BIO_write(bio, "Tue ", sizeof("Tue ") - 1);
     731    ASN1_GENERALIZEDTIME_print(bio, asn1time);
     732    len = BIO_get_mem_data(bio, &value);
     733
     734    time = ngx_parse_http_time(value, len);
     735
     736    BIO_free(bio);
     737
     738    return time;
    683739}
    684740
Note: See TracChangeset for help on using the changeset viewer.