Changeset 556783e in mod_gnutls for src/gnutls_ocsp.c


Ignore:
Timestamp:
Jul 24, 2019, 2:29:40 AM (19 months ago)
Author:
Fiona Klute <fiona.klute@…>
Branches:
asyncio, master, proxy-ticket
Children:
e376ed8
Parents:
81018a4
Message:

Provide OCSP response via gnutls_certificate_retrieve_function3 callback

This replaces the old OCSP callback function, which is still used
internally.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_ocsp.c

    r81018a4 r556783e  
    4141/** Dummy data for failure cache entries (one byte). */
    4242#define OCSP_FAILURE_CACHE_DATA 0x0f
     43/** Macro to check if an OCSP reponse pointer contains a cached
     44 * failure */
     45#define IS_FAILURE_RESPONSE(resp) \
     46    (((resp)->size == sizeof(unsigned char)) &&                     \
     47     (*((unsigned char *) (resp)->data) == OCSP_FAILURE_CACHE_DATA))
    4348
    4449
     
    786791    }
    787792
    788     *ocsp_response = mgs_cache_fetch(ctxt->sc->ocsp_cache,
    789                                      ctxt->c->base_server,
    790                                      ctxt->sc->ocsp->fingerprint,
    791                                      ctxt->c->pool);
    792     if (ocsp_response->size == 0)
     793    // TODO: Large allocation, and the pool system doesn't offer realloc
     794    ocsp_response->data = apr_palloc(ctxt->c->pool, OCSP_RESP_SIZE_MAX);
     795    ocsp_response->size = OCSP_RESP_SIZE_MAX;
     796
     797    apr_status_t rv = mgs_cache_fetch(ctxt->sc->ocsp_cache,
     798                                      ctxt->c->base_server,
     799                                      ctxt->sc->ocsp->fingerprint,
     800                                      ocsp_response,
     801                                      ctxt->c->pool);
     802    if (rv != APR_SUCCESS)
    793803    {
    794804        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_EGENERAL, ctxt->c,
    795805                      "Fetching OCSP response from cache failed.");
    796806    }
    797     else if ((ocsp_response->size == sizeof(unsigned char)) &&
    798              (*((unsigned char *) ocsp_response->data) == OCSP_FAILURE_CACHE_DATA))
     807    else if (IS_FAILURE_RESPONSE(ocsp_response))
    799808    {
    800809        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, ctxt->c,
     
    807816        return GNUTLS_E_SUCCESS;
    808817    }
    809     /* get rid of invalid response (if any) */
    810     gnutls_free(ocsp_response->data);
    811     ocsp_response->data = NULL;
     818    /* keep response buffer, reset size for reuse */
     819    ocsp_response->size = OCSP_RESP_SIZE_MAX;
    812820
    813821    /* If the cache had no response or an invalid one, try to update. */
     
    815823                  "No valid OCSP response in cache, trying to update.");
    816824
    817     apr_status_t rv = apr_global_mutex_trylock(sc->ocsp_mutex);
     825    rv = apr_global_mutex_trylock(sc->ocsp_mutex);
    818826    if (APR_STATUS_IS_EBUSY(rv))
    819827    {
     
    824832         * moment there's no good way to integrate that with the
    825833         * Apache Mutex directive. */
    826         *ocsp_response = mgs_cache_fetch(ctxt->sc->ocsp_cache,
    827                                          ctxt->c->base_server,
    828                                          ctxt->sc->ocsp->fingerprint,
    829                                          ctxt->c->pool);
    830         if (ocsp_response->size > 0)
    831         {
    832             /* Got a valid response now, unlock mutex and return. */
     834        rv = mgs_cache_fetch(ctxt->sc->ocsp_cache,
     835                             ctxt->c->base_server,
     836                             ctxt->sc->ocsp->fingerprint,
     837                             ocsp_response,
     838                             ctxt->c->pool);
     839        if (rv == APR_SUCCESS)
     840        {
    833841            apr_global_mutex_unlock(sc->ocsp_mutex);
    834             return GNUTLS_E_SUCCESS;
     842            /* Check if the response is valid. */
     843            if (IS_FAILURE_RESPONSE(ocsp_response))
     844            {
     845                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, ctxt->c,
     846                              "Cached OCSP failure found for %s.",
     847                              ctxt->c->base_server->server_hostname);
     848                goto fail_cleanup;
     849            }
     850            else
     851                return GNUTLS_E_SUCCESS;
    835852        }
    836853        else
    837854        {
    838             gnutls_free(ocsp_response->data);
    839             ocsp_response->data = NULL;
     855            /* keep response buffer, reset size for reuse */
     856            ocsp_response->size = OCSP_RESP_SIZE_MAX;
    840857        }
    841858    }
     
    855872
    856873    /* retry reading from cache */
    857     *ocsp_response = mgs_cache_fetch(ctxt->sc->ocsp_cache,
    858                                      ctxt->c->base_server,
    859                                      ctxt->sc->ocsp->fingerprint,
    860                                      ctxt->c->pool);
    861     if (ocsp_response->size == 0)
     874    rv = mgs_cache_fetch(ctxt->sc->ocsp_cache,
     875                         ctxt->c->base_server,
     876                         ctxt->sc->ocsp->fingerprint,
     877                         ocsp_response,
     878                         ctxt->c->pool);
     879    if (rv != APR_SUCCESS)
    862880    {
    863881        ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, ctxt->c,
     
    869887    }
    870888
    871     /* failure, clean up response data */
     889    /* failure, reset struct, buffer will be released with the
     890     * connection pool */
    872891 fail_cleanup:
    873     gnutls_free(ocsp_response->data);
    874892    ocsp_response->size = 0;
    875893    ocsp_response->data = NULL;
     
    10611079    if (rv != APR_SUCCESS)
    10621080    {
    1063         const gnutls_datum_t ocsp_response =
    1064             mgs_cache_fetch(sc->ocsp_cache, server,
    1065                             sc->ocsp->fingerprint, pool);
    1066 
    1067         if (ocsp_response.size == 0 ||
    1068             ((ocsp_response.size == sizeof(unsigned char)) &&
    1069              (*((unsigned char *) ocsp_response.data) ==
    1070               OCSP_FAILURE_CACHE_DATA)))
     1081        gnutls_datum_t ocsp_response;
     1082        ocsp_response.data = apr_palloc(pool, OCSP_RESP_SIZE_MAX);
     1083        ocsp_response.size = OCSP_RESP_SIZE_MAX;
     1084
     1085        apr_status_t rv = mgs_cache_fetch(sc->ocsp_cache, server,
     1086                                          sc->ocsp->fingerprint,
     1087                                          &ocsp_response,
     1088                                          pool);
     1089
     1090        if (rv != APR_SUCCESS || (IS_FAILURE_RESPONSE(&ocsp_response)))
    10711091        {
    10721092            ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, server,
     
    10751095            mgs_cache_ocsp_failure(server, sc->ocsp_failure_timeout * 2);
    10761096        }
    1077 
    1078         /* Get rid of the response, if any */
    1079         if (ocsp_response.size != 0)
    1080             gnutls_free(ocsp_response.data);
    10811097    }
    10821098    apr_global_mutex_unlock(sc->ocsp_mutex);
     
    11961212                              apr_pool_cleanup_null);
    11971213
    1198     /* enable status request callback */
    1199     gnutls_certificate_set_ocsp_status_request_function(sc->certs,
    1200                                                         mgs_get_ocsp_response,
    1201                                                         sc);
    1202 
    12031214    /* The watchdog structure may be NULL if mod_watchdog is
    12041215     * unavailable. */
Note: See TracChangeset for help on using the changeset viewer.