Changeset 556783e in mod_gnutls
- Timestamp:
- Jul 24, 2019, 2:29:40 AM (18 months ago)
- Branches:
- asyncio, master, proxy-ticket
- Children:
- e376ed8
- Parents:
- 81018a4
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/gnutls_cache.c
r81018a4 r556783e 175 175 #define SOCACHE_FETCH_BUF_SIZE (8 * 1024) 176 176 177 gnutls_datum_t mgs_cache_fetch(mgs_cache_t cache, server_rec *server, 178 gnutls_datum_t key, apr_pool_t *pool) 179 { 180 gnutls_datum_t data = {NULL, 0}; 181 data.data = gnutls_malloc(SOCACHE_FETCH_BUF_SIZE); 182 if (data.data == NULL) 183 return data; 184 data.size = SOCACHE_FETCH_BUF_SIZE; 185 177 apr_status_t mgs_cache_fetch(mgs_cache_t cache, server_rec *server, 178 gnutls_datum_t key, gnutls_datum_t *output, 179 apr_pool_t *pool) 180 { 186 181 apr_pool_t *spool; 187 182 apr_pool_create(&spool, pool); … … 191 186 apr_status_t rv = cache->prov->retrieve(cache->socache, server, 192 187 key.data, key.size, 193 data.data, &data.size,188 output->data, &output->size, 194 189 spool); 195 190 if (cache->prov->flags & AP_SOCACHE_FLAG_NOTMPSAFE) … … 207 202 "error fetching from cache '%s:%s'", 208 203 cache->prov->name, cache->config); 204 } 205 else 206 { 207 ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, server, 208 "fetched %u bytes from cache '%s:%s'", 209 output->size, cache->prov->name, cache->config); 210 } 211 apr_pool_destroy(spool); 212 213 return rv; 214 } 215 216 217 218 /** 219 * Fetch function for the GnuTLS session cache, see 220 * gnutls_db_set_retrieve_function(). 221 * 222 * *Warning*: The `data` element of the returned `gnutls_datum_t` is 223 * allocated using `gnutls_malloc()` for compatibility with the GnuTLS 224 * session caching API, and must be released using `gnutls_free()`. 225 * 226 * @param baton mgs_handle_t for the connection, as set via 227 * gnutls_db_set_ptr() 228 * 229 * @param key object key to fetch 230 * 231 * @return the requested cache entry, or `{NULL, 0}` 232 */ 233 static gnutls_datum_t socache_fetch_session(void *baton, gnutls_datum_t key) 234 { 235 gnutls_datum_t data = {NULL, 0}; 236 gnutls_datum_t dbmkey; 237 mgs_handle_t *ctxt = baton; 238 239 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) 240 return data; 241 242 data.data = gnutls_malloc(SOCACHE_FETCH_BUF_SIZE); 243 if (data.data == NULL) 244 return data; 245 data.size = SOCACHE_FETCH_BUF_SIZE; 246 247 apr_status_t rv = mgs_cache_fetch(ctxt->sc->cache, ctxt->c->base_server, 248 dbmkey, &data, ctxt->c->pool); 249 250 if (rv != APR_SUCCESS) 251 { 209 252 /* free unused buffer */ 210 253 gnutls_free(data.data); … … 214 257 else 215 258 { 216 ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, server,217 "fetched %u bytes from cache '%s:%s'",218 data.size, cache->prov->name, cache->config);219 220 259 /* Realloc buffer to data.size. Data size must be less than or 221 260 * equal to the initial buffer size, so this REALLY should not … … 224 263 if (__builtin_expect(data.data == NULL, 0)) 225 264 { 226 ap_log_ error(APLOG_MARK, APLOG_CRIT, APR_ENOMEM, server,265 ap_log_cerror(APLOG_MARK, APLOG_CRIT, APR_ENOMEM, ctxt->c, 227 266 "%s: Could not realloc fetch buffer to data size!", 228 267 __func__); … … 230 269 } 231 270 } 232 apr_pool_destroy(spool);233 271 234 272 return data; 235 }236 237 238 239 /**240 * Fetch function for the GnuTLS session cache, see241 * gnutls_db_set_retrieve_function().242 *243 * *Warning*: The `data` element of the returned `gnutls_datum_t` is244 * allocated using `gnutls_malloc()` for compatibility with the GnuTLS245 * session caching API, and must be released using `gnutls_free()`.246 *247 * @param baton mgs_handle_t for the connection, as set via248 * gnutls_db_set_ptr()249 *250 * @param key object key to fetch251 *252 * @return the requested cache entry, or `{NULL, 0}`253 */254 static gnutls_datum_t socache_fetch_session(void *baton, gnutls_datum_t key)255 {256 gnutls_datum_t data = {NULL, 0};257 gnutls_datum_t dbmkey;258 mgs_handle_t *ctxt = baton;259 260 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)261 return data;262 263 return mgs_cache_fetch(ctxt->sc->cache, ctxt->c->base_server,264 dbmkey, ctxt->c->pool);265 273 } 266 274 -
src/gnutls_cache.h
r81018a4 r556783e 139 139 * @param key key for the cache entry to be fetched 140 140 * 141 * @param pool pool to allocate the response and other temporary 142 * memory from 141 * @param output pre-allocated buffer to write to and its size 143 142 * 144 * @return the requested cache entry, or `{NULL, 0}` 143 * @param pool pool to allocate temporary memory from 144 * 145 * @return APR status or error value 145 146 */ 146 gnutls_datum_t mgs_cache_fetch(mgs_cache_t cache, server_rec *server, 147 gnutls_datum_t key, apr_pool_t *pool); 147 apr_status_t mgs_cache_fetch(mgs_cache_t cache, server_rec *server, 148 gnutls_datum_t key, gnutls_datum_t *output, 149 apr_pool_t *pool); 148 150 149 151 /** -
src/gnutls_hooks.c
r81018a4 r556783e 409 409 *privkey = ctxt->sc->privkey_x509; 410 410 *flags = 0; 411 412 if (ctxt->sc->ocsp_staple == GNUTLS_ENABLED_TRUE) 413 { 414 gnutls_ocsp_data_st *resp = 415 apr_palloc(ctxt->c->pool, sizeof(gnutls_ocsp_data_st)); 416 resp->version = 0; 417 resp->exptime = 0; 418 419 int ret = mgs_get_ocsp_response(session, NULL, &resp->response); 420 if (ret == GNUTLS_E_SUCCESS) 421 { 422 *ocsp = resp; 423 *ocsp_length = 1; 424 } 425 } 426 411 427 return 0; 412 428 } else { -
src/gnutls_ocsp.c
r81018a4 r556783e 41 41 /** Dummy data for failure cache entries (one byte). */ 42 42 #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)) 43 48 44 49 … … 786 791 } 787 792 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) 793 803 { 794 804 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_EGENERAL, ctxt->c, 795 805 "Fetching OCSP response from cache failed."); 796 806 } 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)) 799 808 { 800 809 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, ctxt->c, … … 807 816 return GNUTLS_E_SUCCESS; 808 817 } 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; 812 820 813 821 /* If the cache had no response or an invalid one, try to update. */ … … 815 823 "No valid OCSP response in cache, trying to update."); 816 824 817 apr_status_trv = apr_global_mutex_trylock(sc->ocsp_mutex);825 rv = apr_global_mutex_trylock(sc->ocsp_mutex); 818 826 if (APR_STATUS_IS_EBUSY(rv)) 819 827 { … … 824 832 * moment there's no good way to integrate that with the 825 833 * Apache Mutex directive. */ 826 *ocsp_response= mgs_cache_fetch(ctxt->sc->ocsp_cache,827 828 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 { 833 841 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; 835 852 } 836 853 else 837 854 { 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; 840 857 } 841 858 } … … 855 872 856 873 /* 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) 862 880 { 863 881 ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, ctxt->c, … … 869 887 } 870 888 871 /* failure, clean up response data */ 889 /* failure, reset struct, buffer will be released with the 890 * connection pool */ 872 891 fail_cleanup: 873 gnutls_free(ocsp_response->data);874 892 ocsp_response->size = 0; 875 893 ocsp_response->data = NULL; … … 1061 1079 if (rv != APR_SUCCESS) 1062 1080 { 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))) 1071 1091 { 1072 1092 ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, server, … … 1075 1095 mgs_cache_ocsp_failure(server, sc->ocsp_failure_timeout * 2); 1076 1096 } 1077 1078 /* Get rid of the response, if any */1079 if (ocsp_response.size != 0)1080 gnutls_free(ocsp_response.data);1081 1097 } 1082 1098 apr_global_mutex_unlock(sc->ocsp_mutex); … … 1196 1212 apr_pool_cleanup_null); 1197 1213 1198 /* enable status request callback */1199 gnutls_certificate_set_ocsp_status_request_function(sc->certs,1200 mgs_get_ocsp_response,1201 sc);1202 1203 1214 /* The watchdog structure may be NULL if mod_watchdog is 1204 1215 * unavailable. */
Note: See TracChangeset
for help on using the changeset viewer.