1 /*
2  *  Copyright 2016 Fiona Klute
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 #include "gnutls_ocsp.h"
18 #include "mod_gnutls.h"
19 #include "gnutls_cache.h"
20 #include "gnutls_config.h"
21 #include "gnutls_util.h"
22 
23 #include <apr_escape.h>
24 #include <apr_lib.h>
25 #include <apr_time.h>
26 #include <gnutls/ocsp.h>
27 #include <time.h>
28 
29 #ifdef APLOG_USE_MODULE
30 APLOG_USE_MODULE(gnutls);
31 #endif
32 
33 /** maximum supported OCSP response size, 8K should be plenty */
34 #define OCSP_RESP_SIZE_MAX (8 * 1024)
35 #define OCSP_REQ_TYPE "application/ocsp-request"
36 #define OCSP_RESP_TYPE "application/ocsp-response"
37 
38 /** Dummy data for failure cache entries (one byte). */
39 #define OCSP_FAILURE_CACHE_DATA 0x0f
40 
41 
42 #define _log_one_ocsp_fail(str, srv)                                    \
43     ap_log_error(APLOG_MARK, APLOG_INFO, APR_EGENERAL, (srv),           \
44                  "Reason for failed OCSP response verification: %s", (str))
45 /**
46  * Log all matching reasons for verification failure
47  */
_log_verify_fail_reason(const unsigned int verify,server_rec * s)48 static void _log_verify_fail_reason(const unsigned int verify, server_rec *s)
49 {
50     if (verify & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
51         _log_one_ocsp_fail("Signer cert not found", s);
52 
53     if (verify & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
54         _log_one_ocsp_fail("Signer cert keyusage error", s);
55 
56     if (verify & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
57         _log_one_ocsp_fail("Signer cert is not trusted", s);
58 
59     if (verify & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
60         _log_one_ocsp_fail("Insecure algorithm", s);
61 
62     if (verify & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
63         _log_one_ocsp_fail("Signature failure", s);
64 
65     if (verify & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
66         _log_one_ocsp_fail("Signer cert not yet activated", s);
67 
68     if (verify & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
69         _log_one_ocsp_fail("Signer cert expired", s);
70 }
71 
72 
73 
mgs_ocsp_stapling_enable(cmd_parms * parms,void * dummy,const int arg)74 const char *mgs_ocsp_stapling_enable(cmd_parms *parms,
75                                      void *dummy __attribute__((unused)),
76                                      const int arg)
77 {
78     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
79         ap_get_module_config(parms->server->module_config, &gnutls_module);
80 
81     if (arg)
82         sc->ocsp_staple = GNUTLS_ENABLED_TRUE;
83     else
84         sc->ocsp_staple = GNUTLS_ENABLED_FALSE;
85 
86     return NULL;
87 }
88 
89 
90 
mgs_set_ocsp_check_nonce(cmd_parms * parms,void * dummy,const int arg)91 const char *mgs_set_ocsp_check_nonce(cmd_parms *parms,
92                                      void *dummy __attribute__((unused)),
93                                      const int arg)
94 {
95     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
96         ap_get_module_config(parms->server->module_config, &gnutls_module);
97 
98     if (arg)
99         sc->ocsp_check_nonce = GNUTLS_ENABLED_TRUE;
100     else
101         sc->ocsp_check_nonce = GNUTLS_ENABLED_FALSE;
102 
103     return NULL;
104 }
105 
106 
107 
mgs_store_ocsp_response_path(cmd_parms * parms,void * dummy,const char * arg)108 const char *mgs_store_ocsp_response_path(cmd_parms *parms,
109                                          void *dummy __attribute__((unused)),
110                                          const char *arg)
111 {
112     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
113         ap_get_module_config(parms->server->module_config, &gnutls_module);
114 
115     sc->ocsp_response_file = ap_server_root_relative(parms->pool, arg);
116     return NULL;
117 }
118 
119 
120 
121 /**
122  * Create an OCSP request for the certificate of the given server. The
123  * DER encoded request is stored in 'req' (must be released with
124  * gnutls_free() when no longer needed), its nonce in 'nonce' (same,
125  * if not NULL).
126  *
127  * Returns GNUTLS_E_SUCCESS, or a GnuTLS error code.
128  */
129 static int mgs_create_ocsp_request(server_rec *s, gnutls_datum_t *req,
130                             gnutls_datum_t *nonce)
131     __attribute__((nonnull(1, 2)));
mgs_create_ocsp_request(server_rec * s,gnutls_datum_t * req,gnutls_datum_t * nonce)132 static int mgs_create_ocsp_request(server_rec *s, gnutls_datum_t *req,
133                             gnutls_datum_t *nonce)
134 {
135     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
136         ap_get_module_config(s->module_config, &gnutls_module);
137 
138     gnutls_ocsp_req_t r;
139     int ret = gnutls_ocsp_req_init(&r);
140     if (ret != GNUTLS_E_SUCCESS)
141     {
142         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
143                      "Could not initialize OCSP request structure: %s (%d)",
144                      gnutls_strerror(ret), ret);
145         return ret;
146     }
147 
148     /* GnuTLS doc says that the digest is "normally"
149      * GNUTLS_DIG_SHA1. */
150     ret = gnutls_ocsp_req_add_cert(r, GNUTLS_DIG_SHA256,
151                                    sc->certs_x509_crt_chain[1],
152                                    sc->certs_x509_crt_chain[0]);
153 
154     if (ret != GNUTLS_E_SUCCESS)
155     {
156         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
157                      "Adding certificate to OCSP request for %s:%d "
158                      "failed: %s (%d)",
159                      s->server_hostname, s->addrs->host_port,
160                      gnutls_strerror(ret), ret);
161         gnutls_ocsp_req_deinit(r);
162         return ret;
163     }
164 
165     ret = gnutls_ocsp_req_randomize_nonce(r);
166     if (ret != GNUTLS_E_SUCCESS)
167     {
168         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
169                      "OCSP nonce creation failed: %s (%d)",
170                      gnutls_strerror(ret), ret);
171         gnutls_ocsp_req_deinit(r);
172         return ret;
173     }
174 
175     if (nonce != NULL)
176     {
177         ret = gnutls_ocsp_req_get_nonce(r, NULL, nonce);
178         if (ret != GNUTLS_E_SUCCESS)
179         {
180             ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
181                          "Could not get nonce: %s (%d)",
182                          gnutls_strerror(ret), ret);
183             gnutls_free(nonce->data);
184             nonce->data = NULL;
185             nonce->size = 0;
186             gnutls_ocsp_req_deinit(r);
187             return ret;
188         }
189     }
190 
191     ret = gnutls_ocsp_req_export(r, req);
192     if (ret != GNUTLS_E_SUCCESS)
193     {
194         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
195                      "OCSP request export failed: %s (%d)",
196                      gnutls_strerror(ret), ret);
197         gnutls_free(req->data);
198         req->data = NULL;
199         req->size = 0;
200         if (nonce != NULL)
201         {
202             gnutls_free(nonce->data);
203             nonce->data = NULL;
204             nonce->size = 0;
205         }
206         gnutls_ocsp_req_deinit(r);
207         return ret;
208     }
209 
210     gnutls_ocsp_req_deinit(r);
211     return ret;
212 }
213 
214 
215 
216 /**
217  * Check if the provided OCSP response is usable for stapling in
218  * connections to this server. Returns GNUTLS_E_SUCCESS if yes.
219  *
220  * Supports only one certificate status per response.
221  *
222  * If expiry is not NULL, it will be set to the nextUpdate time
223  * contained in the response, or zero if the response does not contain
224  * a nextUpdate field.
225  *
226  * If nonce is not NULL, the response must contain a matching nonce.
227  */
228 int check_ocsp_response(server_rec *s, const gnutls_datum_t *ocsp_response,
229                         apr_time_t* expiry, const gnutls_datum_t *nonce)
230     __attribute__((nonnull(1, 2)));
check_ocsp_response(server_rec * s,const gnutls_datum_t * ocsp_response,apr_time_t * expiry,const gnutls_datum_t * nonce)231 int check_ocsp_response(server_rec *s, const gnutls_datum_t *ocsp_response,
232                         apr_time_t* expiry, const gnutls_datum_t *nonce)
233 {
234     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
235         ap_get_module_config(s->module_config, &gnutls_module);
236 
237     if (sc->ocsp->trust == NULL)
238     {
239         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
240                      "No OCSP trust list available for server \"%s\"!",
241                      s->server_hostname);
242         return GNUTLS_E_NO_CERTIFICATE_FOUND;
243     }
244 
245     gnutls_ocsp_resp_t resp;
246     int ret = gnutls_ocsp_resp_init(&resp);
247     if (ret != GNUTLS_E_SUCCESS)
248     {
249         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
250                      "Could not initialize OCSP response structure: %s (%d)",
251                      gnutls_strerror(ret), ret);
252         goto resp_cleanup;
253     }
254     ret = gnutls_ocsp_resp_import(resp, ocsp_response);
255     if (ret != GNUTLS_E_SUCCESS)
256     {
257         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
258                      "Importing OCSP response failed: %s (%d)",
259                      gnutls_strerror(ret), ret);
260         goto resp_cleanup;
261     }
262 
263     ret = gnutls_ocsp_resp_check_crt(resp, 0, sc->certs_x509_crt_chain[0]);
264     if (ret != GNUTLS_E_SUCCESS)
265     {
266         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
267                      "OCSP response is not for server certificate: %s (%d)",
268                      gnutls_strerror(ret), ret);
269         goto resp_cleanup;
270     }
271 
272     unsigned int verify;
273     ret = gnutls_ocsp_resp_verify(resp, *(sc->ocsp->trust), &verify, 0);
274     if (ret != GNUTLS_E_SUCCESS)
275     {
276         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
277                      "OCSP response verification failed: %s (%d)",
278                      gnutls_strerror(ret), ret);
279         goto resp_cleanup;
280     }
281     else
282     {
283         /* verification worked, check the result */
284         if (verify != 0)
285         {
286             _log_verify_fail_reason(verify, s);
287             ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
288             goto resp_cleanup;
289         }
290         else
291             ap_log_error(APLOG_MARK, APLOG_TRACE1, APR_SUCCESS, s,
292                          "OCSP response signature is valid.");
293     }
294 
295     /* Even some large CAs do not support nonces, probably because
296      * that way they can cache responses. :-/ */
297     if (nonce != NULL && sc->ocsp_check_nonce)
298     {
299         gnutls_datum_t resp_nonce;
300         ret = gnutls_ocsp_resp_get_nonce(resp, 0, &resp_nonce);
301         if (ret != GNUTLS_E_SUCCESS)
302         {
303             ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
304                          "Could not get OCSP response nonce: %s (%d)",
305                          gnutls_strerror(ret), ret);
306             goto resp_cleanup;
307         }
308         if (resp_nonce.size != nonce->size
309             || memcmp(resp_nonce.data, nonce->data, nonce->size))
310         {
311             ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
312             ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
313                          "OCSP response invalid: nonce mismatch");
314             gnutls_free(resp_nonce.data);
315             goto resp_cleanup;
316         }
317         ap_log_error(APLOG_MARK, APLOG_TRACE2, APR_SUCCESS, s,
318                      "OCSP response: nonce match");
319         gnutls_free(resp_nonce.data);
320     }
321 
322     /* OK, response is for our certificate and valid, let's get the
323      * actual response data. */
324     unsigned int cert_status;
325     time_t this_update;
326     time_t next_update;
327     ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
328                                       &cert_status, &this_update,
329                                       &next_update, NULL, NULL);
330     if (ret != GNUTLS_E_SUCCESS)
331     {
332         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
333                      "Could not get OCSP response data: %s (%d)",
334                      gnutls_strerror(ret), ret);
335         goto resp_cleanup;
336     }
337 
338     apr_time_t now = apr_time_now();
339     apr_time_t valid_at;
340     apr_time_ansi_put(&valid_at, this_update);
341     /* Buffer for human-readable times produced by apr_rfc822_date,
342      * see apr_time.h */
343     char date_str[APR_RFC822_DATE_LEN];
344     apr_rfc822_date(date_str, valid_at);
345 
346     if (now < valid_at)
347     {
348         /* We don't know if our clock or that of the OCSP responder is
349          * out of sync, so warn but continue. */
350         ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EGENERAL, s,
351                      "OSCP response claims to be from future (%s), check "
352                      "time synchronization!", date_str);
353     }
354 
355     if (next_update == (time_t) -1)
356     {
357         ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, s,
358                      "OSCP response does not contain nextUpdate info.");
359         if (expiry != NULL)
360             *expiry = 0;
361     }
362     else
363     {
364         apr_time_t valid_to;
365         apr_time_ansi_put(&valid_to, next_update);
366         if (expiry != NULL)
367             *expiry = valid_to;
368         if (now > valid_to)
369         {
370             apr_rfc822_date(date_str, valid_to);
371             ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
372                          "OCSP response has expired at %s!", date_str);
373             /* Do not send a stale response */
374             ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
375             goto resp_cleanup;
376         }
377     }
378 
379     /* What's the actual status? Will be one of
380      * gnutls_ocsp_cert_status_t as defined in gnutls/ocsp.h. */
381     if (cert_status == GNUTLS_OCSP_CERT_GOOD)
382     {
383         /* Yay, everything's good! */
384         ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, s,
385                      "CA flagged certificate as valid at %s.", date_str);
386     }
387     else
388     {
389         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
390                      "CA flagged certificate as %s at %s.",
391                      cert_status == GNUTLS_OCSP_CERT_REVOKED ?
392                      "revoked" : "unknown", date_str);
393         ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
394     }
395 
396  resp_cleanup:
397     gnutls_ocsp_resp_deinit(resp);
398     return ret;
399 }
400 
401 
402 
403 /*
404  * Returns the certificate fingerprint, memory is allocated from p.
405  */
mgs_get_cert_fingerprint(apr_pool_t * p,gnutls_x509_crt_t cert)406 static gnutls_datum_t mgs_get_cert_fingerprint(apr_pool_t *p,
407                                                gnutls_x509_crt_t cert)
408 {
409     gnutls_datum_t fingerprint = {NULL, 0};
410     size_t fplen = 0;
411     gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, NULL, &fplen);
412     unsigned char * fp = apr_palloc(p, fplen);
413     gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, fp, &fplen);
414     /* Safe integer type conversion: The types of fingerprint.size
415      * (unsigned int) and fplen (size_t) may have different
416      * lengths. */
417 #if defined(__GNUC__) && __GNUC__ < 5 && \
418     !(defined(__clang__) && __has_builtin(__builtin_add_overflow))
419     if (__builtin_expect(fplen <= UINT_MAX, 1))
420     {
421         fingerprint.size = (unsigned int) fplen;
422         fingerprint.data = fp;
423     }
424 #else
425     if (__builtin_add_overflow(fplen, 0, &fingerprint.size))
426         fingerprint.size = 0;
427     else
428         fingerprint.data = fp;
429 #endif
430     return fingerprint;
431 }
432 
433 
434 
435 static apr_status_t do_ocsp_request(apr_pool_t *p, server_rec *s,
436                                     gnutls_datum_t *request,
437                                     gnutls_datum_t *response)
438     __attribute__((nonnull));
do_ocsp_request(apr_pool_t * p,server_rec * s,gnutls_datum_t * request,gnutls_datum_t * response)439 static apr_status_t do_ocsp_request(apr_pool_t *p, server_rec *s,
440                                     gnutls_datum_t *request,
441                                     gnutls_datum_t *response)
442 {
443     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
444         ap_get_module_config(s->module_config, &gnutls_module);
445 
446     if (apr_strnatcmp(sc->ocsp->uri->scheme, "http"))
447     {
448         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
449                      "Scheme \"%s\" is not supported for OCSP requests!",
450                      sc->ocsp->uri->scheme);
451         return APR_EINVAL;
452     }
453 
454     const char* header = http_post_header(p, sc->ocsp->uri,
455                                           OCSP_REQ_TYPE, OCSP_RESP_TYPE,
456                                           request->size);
457     ap_log_error(APLOG_MARK, APLOG_TRACE2, APR_SUCCESS, s,
458                  "OCSP POST header: %s", header);
459 
460     /* Find correct port */
461     apr_port_t port = sc->ocsp->uri->port ?
462         sc->ocsp->uri->port : apr_uri_port_of_scheme(sc->ocsp->uri->scheme);
463 
464     apr_sockaddr_t *sa;
465     apr_status_t rv = apr_sockaddr_info_get(&sa, sc->ocsp->uri->hostname,
466                                             APR_UNSPEC, port, 0, p);
467     if (rv != APR_SUCCESS)
468     {
469         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
470                      "Address resolution for OCSP responder %s failed.",
471                      sc->ocsp->uri->hostinfo);
472     }
473 
474     /* There may be multiple answers, try them in order until one
475      * works. */
476     apr_socket_t *sock;
477     while (sa)
478     {
479         rv = apr_socket_create(&sock, sa->family, SOCK_STREAM,
480                                APR_PROTO_TCP, p);
481         if (rv == APR_SUCCESS)
482         {
483             apr_socket_timeout_set(sock, sc->ocsp_socket_timeout);
484             rv = apr_socket_connect(sock, sa);
485             if (rv == APR_SUCCESS)
486                 /* Connected! */
487                 break;
488             apr_socket_close(sock);
489         }
490         sa = sa->next;
491     }
492     /* If the socket is connected, 'sa' points at the matching
493      * address. */
494     if (sa == NULL)
495     {
496         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
497                      "Connecting to OCSP responder %s failed.",
498                      sc->ocsp->uri->hostinfo);
499         return rv;
500     }
501 
502     /* Header is generated locally, so strlen() is safe. */
503     rv = sock_send_buf(sock, header, strlen(header));
504     if (rv == APR_SUCCESS)
505         rv = sock_send_buf(sock, (char*) request->data, request->size);
506     /* catches errors from both header and request */
507     if (rv != APR_SUCCESS)
508     {
509         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
510                      "Sending OCSP request failed.");
511         goto exit;
512     }
513 
514     /* Prepare bucket brigades to read the response header. BBs make
515      * it easy to split the header into lines. */
516     apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p);
517     apr_bucket_brigade *bb = apr_brigade_create(p, ba);
518     /* will carry split response headers */
519     apr_bucket_brigade *rh = apr_brigade_create(p, ba);
520 
521     APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_socket_create(sock, ba));
522     /* The first line in the response header must be the status, check
523      * for OK status code. Line looks similar to "HTTP/1.0 200 OK". */
524     const char *h = read_line(p, bb, rh);
525     const char *code = 0;
526     if (h == NULL
527         || strncmp(h, "HTTP/", 5)
528         || (code = ap_strchr(h, ' ')) == NULL
529         || apr_atoi64(code + 1) != HTTP_OK)
530     {
531         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
532                      "Invalid HTTP response status from %s: %s",
533                      sc->ocsp->uri->hostinfo, h);
534         rv = APR_ECONNRESET;
535         goto exit;
536     }
537     /* Read remaining header lines */
538     for (h = read_line(p, bb, rh); h != NULL && apr_strnatcmp(h, "") != 0;
539          h = read_line(p, bb, rh))
540     {
541         ap_log_error(APLOG_MARK, APLOG_TRACE2, APR_SUCCESS, s,
542                      "Received header: %s", h);
543     }
544     /* The last header line should be empty (""), NULL indicates an
545      * error. */
546     if (h == NULL)
547     {
548         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
549                      "Error while reading HTTP response header from %s",
550                      sc->ocsp->uri->hostinfo);
551         rv = APR_ECONNRESET;
552         goto exit;
553     }
554 
555     /* Headers have been consumed, the rest of the available data
556      * should be the actual response. */
557     apr_size_t len = OCSP_RESP_SIZE_MAX;
558     char buf[OCSP_RESP_SIZE_MAX];
559     /* apr_brigade_pflatten() can allocate directly from the pool, but
560      * the documentation does not describe a way to limit the size of
561      * the buffer, which is necessary here to prevent DoS by endless
562      * response. Use apr_brigade_flatten() to read to a stack pool,
563      * then create a copy to return. */
564     rv = apr_brigade_flatten(bb, buf, &len);
565     if (rv != APR_SUCCESS)
566     {
567         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
568                      "Failed to read OCSP response.");
569         goto exit;
570     }
571 
572     /* With the length restriction this really should not overflow. */
573 #if defined(__GNUC__) && __GNUC__ < 5 && \
574     !(defined(__clang__) && __has_builtin(__builtin_add_overflow))
575     if (__builtin_expect(len > UINT_MAX, 0))
576 #else
577     if (__builtin_add_overflow(len, 0, &response->size))
578 #endif
579     {
580         response->data = NULL;
581         rv = APR_ENOMEM;
582     }
583     else
584     {
585 #if defined(__GNUC__) && __GNUC__ < 5 && \
586     !(defined(__clang__) && __has_builtin(__builtin_add_overflow))
587         response->size = (unsigned int) len;
588 #endif
589         response->data = apr_pmemdup(p, buf, len);
590     }
591 
592  exit:
593     apr_socket_close(sock);
594     return rv;
595 }
596 
597 
598 
mgs_cache_ocsp_response(server_rec * s)599 apr_status_t mgs_cache_ocsp_response(server_rec *s)
600 {
601     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
602         ap_get_module_config(s->module_config, &gnutls_module);
603 
604     if (sc->cache == NULL)
605     {
606         /* OCSP caching requires a cache. */
607         return APR_ENOTIMPL;
608     }
609 
610     apr_pool_t *tmp;
611     apr_status_t rv = apr_pool_create(&tmp, NULL);
612     if (rv != APR_SUCCESS)
613     {
614         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
615                      "could not create temporary pool for %s",
616                      __func__);
617         return rv;
618     }
619 
620     gnutls_datum_t resp;
621     gnutls_datum_t nonce = { NULL, 0 };
622 
623     if (sc->ocsp_response_file != NULL)
624     {
625         ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, s,
626                      "Loading OCSP response from %s",
627                      sc->ocsp_response_file);
628         rv = datum_from_file(tmp, sc->ocsp_response_file, &resp);
629         if (rv != APR_SUCCESS)
630         {
631             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
632                          "Loading OCSP response from %s failed!",
633                          sc->ocsp_response_file);
634             apr_pool_destroy(tmp);
635             return rv;
636         }
637     }
638     else
639     {
640         gnutls_datum_t req;
641         int ret = mgs_create_ocsp_request(s, &req, &nonce);
642         if (ret == GNUTLS_E_SUCCESS)
643         {
644             ap_log_error(APLOG_MARK, APLOG_TRACE2, APR_SUCCESS, s,
645                          "created OCSP request for %s:%d: %s",
646                          s->server_hostname, s->addrs->host_port,
647                          apr_pescape_hex(tmp, req.data, req.size, 0));
648         }
649         else
650         {
651             gnutls_free(req.data);
652             gnutls_free(nonce.data);
653             apr_pool_destroy(tmp);
654             return APR_EGENERAL;
655         }
656 
657         rv = do_ocsp_request(tmp, s, &req, &resp);
658         gnutls_free(req.data);
659         if (rv != APR_SUCCESS)
660         {
661             /* do_ocsp_request() does its own error logging. */
662             gnutls_free(nonce.data);
663             apr_pool_destroy(tmp);
664             return rv;
665         }
666     }
667 
668     apr_time_t next_update;
669     if (check_ocsp_response(s, &resp, &next_update, nonce.size ? &nonce : NULL)
670         != GNUTLS_E_SUCCESS)
671     {
672         ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, s,
673                      "OCSP response validation failed, cannot "
674                      "update cache.");
675         apr_pool_destroy(tmp);
676         gnutls_free(nonce.data);
677         return APR_EGENERAL;
678     }
679     gnutls_free(nonce.data);
680 
681     apr_time_t expiry = apr_time_now() + sc->ocsp_cache_time;
682     /* Make sure that a response is not cached beyond its nextUpdate
683      * time. If the variable next_update is zero, the response does
684      * not contain a nextUpdate field. */
685     if (next_update != 0 && next_update < expiry)
686     {
687         char date_str[APR_RFC822_DATE_LEN];
688         apr_rfc822_date(date_str, next_update);
689         ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EGENERAL, s,
690                      "OCSP response timeout restricted to nextUpdate time %s. "
691                      "Check if GnuTLSOCSPCacheTimeout is appropriate.",
692                      date_str);
693         expiry = next_update;
694     }
695 
696     int r = sc->cache->store(s, sc->ocsp->fingerprint, resp, expiry);
697     /* destroy pool, and original copy of the OCSP response with it */
698     apr_pool_destroy(tmp);
699     if (r != 0)
700     {
701         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
702                       "Storing OCSP response in cache failed.");
703         return APR_EGENERAL;
704     }
705     return APR_SUCCESS;
706 }
707 
708 
709 
710 /*
711  * Retries after failed OCSP requests must be rate limited. If the
712  * responder is overloaded or buggy we don't want to add too much more
713  * load, and if a MITM is messing with requests a repetition loop
714  * might end up being a self-inflicted denial of service.
715  */
mgs_cache_ocsp_failure(server_rec * s)716 void mgs_cache_ocsp_failure(server_rec *s)
717 {
718     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
719         ap_get_module_config(s->module_config, &gnutls_module);
720 
721     unsigned char c = OCSP_FAILURE_CACHE_DATA;
722     gnutls_datum_t dummy = {
723         .data = &c,
724         .size = sizeof(c)
725     };
726     apr_time_t expiry = apr_time_now() + sc->ocsp_failure_timeout;
727 
728     char date_str[APR_RFC822_DATE_LEN];
729     apr_rfc822_date(date_str, expiry);
730     ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
731                  "OCSP request for %s failed, next try after %s.",
732                  s->server_hostname, date_str);
733 
734     int r = sc->cache->store(s, sc->ocsp->fingerprint, dummy, expiry);
735     if (r != 0)
736         ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, s,
737                      "Caching OCSP failure failed.");
738 }
739 
740 
741 
mgs_get_ocsp_response(gnutls_session_t session,void * ptr,gnutls_datum_t * ocsp_response)742 int mgs_get_ocsp_response(gnutls_session_t session,
743                           void *ptr __attribute__((unused)),
744                           gnutls_datum_t *ocsp_response)
745 {
746     mgs_handle_t *ctxt = gnutls_session_get_ptr(session);
747     mgs_srvconf_rec *sc = ctxt->sc;
748 
749     if (!sc->ocsp_staple || sc->cache == NULL)
750     {
751         /* OCSP must be enabled and caching requires a cache. */
752         return GNUTLS_E_NO_CERTIFICATE_STATUS;
753     }
754 
755     *ocsp_response = sc->cache->fetch(ctxt,
756                                       sc->ocsp->fingerprint);
757     if (ocsp_response->size == 0)
758     {
759         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_EGENERAL, ctxt->c,
760                       "Fetching OCSP response from cache failed.");
761     }
762     else if ((ocsp_response->size == sizeof(unsigned char)) &&
763              (*((unsigned char *) ocsp_response->data) == OCSP_FAILURE_CACHE_DATA))
764     {
765         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, ctxt->c,
766                       "Cached OCSP failure found for %s.",
767                       ctxt->c->base_server->server_hostname);
768         goto fail_cleanup;
769     }
770     else
771     {
772         return GNUTLS_E_SUCCESS;
773     }
774     /* get rid of invalid response (if any) */
775     gnutls_free(ocsp_response->data);
776     ocsp_response->data = NULL;
777 
778     /* If the cache had no response or an invalid one, try to update. */
779     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ctxt->c,
780                   "No valid OCSP response in cache, trying to update.");
781 
782     apr_status_t rv = apr_global_mutex_trylock(sc->ocsp_mutex);
783     if (APR_STATUS_IS_EBUSY(rv))
784     {
785         /* Another thread is currently holding the mutex, wait. */
786         apr_global_mutex_lock(sc->ocsp_mutex);
787         /* Check if this other thread updated the response we need. It
788          * would be better to have a vhost specific mutex, but at the
789          * moment there's no good way to integrate that with the
790          * Apache Mutex directive. */
791         *ocsp_response = sc->cache->fetch(ctxt,
792                                           sc->ocsp->fingerprint);
793         if (ocsp_response->size > 0)
794         {
795             /* Got a valid response now, unlock mutex and return. */
796             apr_global_mutex_unlock(sc->ocsp_mutex);
797             return GNUTLS_E_SUCCESS;
798         }
799         else
800         {
801             gnutls_free(ocsp_response->data);
802             ocsp_response->data = NULL;
803         }
804     }
805 
806     rv = mgs_cache_ocsp_response(ctxt->c->base_server);
807     if (rv != APR_SUCCESS)
808     {
809         ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, ctxt->c,
810                       "Caching a fresh OCSP response failed");
811         /* cache failure to rate limit retries */
812         mgs_cache_ocsp_failure(ctxt->c->base_server);
813         apr_global_mutex_unlock(sc->ocsp_mutex);
814         goto fail_cleanup;
815     }
816     apr_global_mutex_unlock(sc->ocsp_mutex);
817 
818     /* retry reading from cache */
819     *ocsp_response = sc->cache->fetch(ctxt,
820                                       sc->ocsp->fingerprint);
821     if (ocsp_response->size == 0)
822     {
823         ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, ctxt->c,
824                       "Fetching OCSP response from cache failed on retry.");
825     }
826     else
827     {
828         return GNUTLS_E_SUCCESS;
829     }
830 
831     /* failure, clean up response data */
832  fail_cleanup:
833     gnutls_free(ocsp_response->data);
834     ocsp_response->size = 0;
835     ocsp_response->data = NULL;
836     return GNUTLS_E_NO_CERTIFICATE_STATUS;
837 }
838 
839 
840 
mgs_create_ocsp_trust_list(gnutls_x509_trust_list_t * tl,const gnutls_x509_crt_t * chain,const int num)841 int mgs_create_ocsp_trust_list(gnutls_x509_trust_list_t *tl,
842                                const gnutls_x509_crt_t *chain,
843                                const int num)
844 {
845     int added = 0;
846     int ret = gnutls_x509_trust_list_init(tl, num);
847 
848     if (ret == GNUTLS_E_SUCCESS)
849         added = gnutls_x509_trust_list_add_cas(*tl, chain, num, 0);
850 
851     if (added != num)
852         ret = GNUTLS_E_CERTIFICATE_ERROR;
853 
854     /* Clean up trust list in case of error */
855     if (ret != GNUTLS_E_SUCCESS)
856         gnutls_x509_trust_list_deinit(*tl, 0);
857 
858     return ret;
859 }
860 
861 
862 
mgs_cleanup_trust_list(void * data)863 apr_status_t mgs_cleanup_trust_list(void *data)
864 {
865     gnutls_x509_trust_list_t *tl = (gnutls_x509_trust_list_t *) data;
866     gnutls_x509_trust_list_deinit(*tl, 0);
867     return APR_SUCCESS;
868 }
869 
870 
871 
mgs_cert_get_ocsp_uri(apr_pool_t * p,gnutls_x509_crt_t cert)872 apr_uri_t * mgs_cert_get_ocsp_uri(apr_pool_t *p, gnutls_x509_crt_t cert)
873 {
874     apr_pool_t *tmp;
875     apr_status_t rv = apr_pool_create(&tmp, p);
876     if (rv != APR_SUCCESS)
877         return NULL;
878 
879     apr_uri_t *ocsp_uri = NULL;
880 
881     int ret = GNUTLS_E_SUCCESS;
882     /* search authority info access for OCSP URI */
883     for (int seq = 0; ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; seq++)
884     {
885         gnutls_datum_t ocsp_access_data;
886         ret = gnutls_x509_crt_get_authority_info_access(cert, seq,
887                                                         GNUTLS_IA_OCSP_URI,
888                                                         &ocsp_access_data,
889                                                         NULL);
890         if (ret == GNUTLS_E_SUCCESS)
891         {
892             /* create NULL terminated string */
893             char *ocsp_str =
894                 apr_pstrndup(tmp, (const char*) ocsp_access_data.data,
895                              ocsp_access_data.size);
896             gnutls_free(ocsp_access_data.data);
897 
898             ocsp_uri = apr_palloc(p, sizeof(apr_uri_t));
899             rv = apr_uri_parse(p, ocsp_str, ocsp_uri);
900             if (rv == APR_SUCCESS)
901                 break;
902             else
903                 ocsp_uri = NULL;
904         }
905     }
906 
907     apr_pool_destroy(tmp);
908     return ocsp_uri;
909 }
910 
911 
912 
913 /*
914  * Like in the general post_config hook the HTTP status codes for
915  * errors are just for fun. What matters is "neither OK nor DECLINED"
916  * to denote an error.
917  */
mgs_ocsp_post_config_server(apr_pool_t * pconf,apr_pool_t * ptemp,server_rec * server)918 int mgs_ocsp_post_config_server(apr_pool_t *pconf,
919                                 apr_pool_t *ptemp __attribute__((unused)),
920                                 server_rec *server)
921 {
922     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
923         ap_get_module_config(server->module_config, &gnutls_module);
924 
925     if (sc->certs_x509_chain_num < 2)
926     {
927         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, server,
928                      "OCSP stapling is enabled but no CA certificate "
929                      "available for %s:%d, make sure it is included in "
930                      "GnuTLSCertificateFile!",
931                      server->server_hostname, server->addrs->host_port);
932         return HTTP_NOT_FOUND;
933     }
934 
935     /* set default values for unset parameters */
936     if (sc->ocsp_check_nonce == GNUTLS_ENABLED_UNSET)
937         sc->ocsp_check_nonce = GNUTLS_ENABLED_TRUE;
938     if (sc->ocsp_cache_time == MGS_TIMEOUT_UNSET)
939         sc->ocsp_cache_time = apr_time_from_sec(MGS_OCSP_CACHE_TIMEOUT);
940     if (sc->ocsp_failure_timeout == MGS_TIMEOUT_UNSET)
941         sc->ocsp_failure_timeout = apr_time_from_sec(MGS_OCSP_FAILURE_TIMEOUT);
942     if (sc->ocsp_socket_timeout == MGS_TIMEOUT_UNSET)
943         sc->ocsp_socket_timeout = apr_time_from_sec(MGS_OCSP_SOCKET_TIMEOUT);
944 
945     sc->ocsp = apr_palloc(pconf, sizeof(struct mgs_ocsp_data));
946 
947     sc->ocsp->fingerprint =
948         mgs_get_cert_fingerprint(pconf, sc->certs_x509_crt_chain[0]);
949     if (sc->ocsp->fingerprint.data == NULL)
950         return HTTP_INTERNAL_SERVER_ERROR;
951 
952     sc->ocsp->uri = mgs_cert_get_ocsp_uri(pconf,
953                                           sc->certs_x509_crt_chain[0]);
954     if (sc->ocsp->uri == NULL && sc->ocsp_response_file == NULL)
955     {
956         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, server,
957                      "OCSP stapling is enabled for for %s:%d, but there is "
958                      "neither an OCSP URI in the certificate nor a "
959                      "GnuTLSOCSPResponseFile setting for this host!",
960                      server->server_hostname, server->addrs->host_port);
961         return HTTP_NOT_FOUND;
962     }
963 
964     sc->ocsp->trust = apr_palloc(pconf,
965                                  sizeof(gnutls_x509_trust_list_t));
966      /* Only the direct issuer may sign the OCSP response or an OCSP
967       * signer. */
968     int ret = mgs_create_ocsp_trust_list(sc->ocsp->trust,
969                                          &(sc->certs_x509_crt_chain[1]),
970                                          1);
971     if (ret != GNUTLS_E_SUCCESS)
972     {
973         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, server,
974                      "Could not create OCSP trust list: %s (%d)",
975                      gnutls_strerror(ret), ret);
976         return HTTP_INTERNAL_SERVER_ERROR;
977     }
978     /* deinit trust list when the config pool is destroyed */
979     apr_pool_cleanup_register(pconf, sc->ocsp->trust,
980                               mgs_cleanup_trust_list,
981                               apr_pool_cleanup_null);
982 
983     /* enable status request callback */
984     gnutls_certificate_set_ocsp_status_request_function(sc->certs,
985                                                         mgs_get_ocsp_response,
986                                                         sc);
987 
988     return OK;
989 }
990