]> granicus.if.org Git - apache/blob - modules/ssl/mod_ssl_ct.c
mod_cache: Don't add cached/revalidated entity headers to a 304 response.
[apache] / modules / ssl / mod_ssl_ct.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  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 /*
18  * Issues
19  *
20  * + Known low-level code kludges/problems
21  *   . proxy: an httpd child process validates SCTs from a server only on the
22  *     first time the data is received; but it could fail once due to invalid
23  *     timestamp, and not be rechecked later after (potentially) time elapses
24  *     and the timestamp is now in a valid range
25  *   . server: shouldn't have to read file of server SCTs on every handshake
26  *     (shared memory or cached file?)
27  *   . split mod_ssl_ct.c into more pieces
28  *   . research: Is it possible to send an SCT that is outside of the known
29  *     valid interval for the log?
30  */
31
32 #if defined(WIN32)
33 #define HAVE_SCT_DAEMON_THREAD
34 #else
35 #define HAVE_SCT_DAEMON_CHILD
36 #endif
37
38 #include <limits.h>
39
40 #if defined(HAVE_SCT_DAEMON_CHILD)
41 #include <unistd.h>
42 #endif
43
44 #include "apr_version.h"
45 #if !APR_VERSION_AT_LEAST(1,5,0)
46 #error mod_ssl_ct requires APR 1.5.0 or later! (for apr_escape.h)
47 #endif
48
49 #include "apr_escape.h"
50 #include "apr_global_mutex.h"
51 #include "apr_signal.h"
52 #include "apr_strings.h"
53 #include "apr_thread_rwlock.h"
54
55 #include "apr_dbd.h"
56
57 #include "httpd.h"
58 #include "http_config.h"
59 #include "http_core.h"
60 #include "http_log.h"
61 #include "http_main.h"
62 #include "http_protocol.h"
63 #include "mpm_common.h"
64 #include "util_mutex.h"
65 #include "ap_listen.h"
66 #include "ap_mpm.h"
67
68 #if AP_NEED_SET_MUTEX_PERMS
69 #include "unixd.h"
70 #endif
71
72 #include "mod_proxy.h"
73 #include "mod_ssl.h"
74 #include "mod_ssl_openssl.h"
75
76 #include "ssl_ct_util.h"
77 #include "ssl_ct_sct.h"
78
79 #include "openssl/x509v3.h"
80 #include "openssl/ocsp.h"
81
82 #if OPENSSL_VERSION_NUMBER < 0x10002001L
83 #error "mod_ssl_ct requires OpenSSL 1.0.2-beta1 or later"
84 #endif
85
86 #ifdef WIN32
87 #define DOTEXE ".exe"
88 #else
89 #define DOTEXE ""
90 #endif
91
92 #define STATUS_VAR                "SSL_CT_PEER_STATUS"
93 #define STATUS_VAR_AWARE_VAL      "peer-aware"
94 #define STATUS_VAR_UNAWARE_VAL    "peer-unaware"
95
96 #define PROXY_SCT_SOURCES_VAR     "SSL_PROXY_SCT_SOURCES"
97
98 #define DAEMON_NAME         "SCT maintenance daemon"
99 #define DAEMON_THREAD_NAME  DAEMON_NAME " thread"
100 #define SERVICE_THREAD_NAME "service thread"
101
102 /** Limit on size of stored SCTs for a certificate (individual SCTs as well
103  * as size of all.
104  */
105 #define MAX_SCTS_SIZE 10000
106
107 /** Limit on size of log URL list for a certificate
108  */
109 #define MAX_LOGLIST_SIZE 1000
110
111 typedef struct ct_server_config {
112     apr_array_header_t *db_log_config;
113     apr_pool_t *db_log_config_pool;
114     apr_array_header_t *static_log_config;
115     apr_array_header_t *server_cert_info; /* ct_server_cert_info */
116     apr_hash_t *static_cert_sct_dirs;
117     const char *sct_storage;
118     const char *audit_storage;
119     const char *ct_exe;
120     const char *log_config_fname;
121     apr_time_t max_sct_age;
122     int max_sh_sct;
123 #define PROXY_AWARENESS_UNSET -1
124 #define PROXY_OBLIVIOUS        1
125 #define PROXY_AWARE            2 /* default */
126 #define PROXY_REQUIRE          3
127     int proxy_awareness;
128 } ct_server_config;
129
130 typedef struct ct_conn_config {
131     int peer_ct_aware;
132     /* proxy mode only */
133     cert_chain *certs;
134     int server_cert_has_sct_list;
135     void *cert_sct_list;
136     apr_size_t cert_sct_list_size;
137     int serverhello_has_sct_list;
138     void *serverhello_sct_list;
139     apr_size_t serverhello_sct_list_size;
140     int ocsp_has_sct_list;
141     void *ocsp_sct_list;
142     apr_size_t ocsp_sct_list_size;
143     apr_array_header_t *all_scts; /* array of ct_sct_data */
144 } ct_conn_config;
145
146 typedef struct ct_server_cert_info {
147     const char *fingerprint;
148     const char *sct_dir;
149 } ct_server_cert_info;
150
151 typedef struct ct_sct_data {
152     const void *data;
153     apr_uint16_t len;
154 } ct_sct_data;
155
156 typedef struct ct_callback_info {
157     server_rec *s;
158     conn_rec *c;
159     ct_conn_config *conncfg;
160 } ct_callback_info;
161
162 typedef struct ct_cached_server_data {
163     apr_status_t validation_result;
164 } ct_cached_server_data;
165
166 /* the log configuration in use -- either db_log_config or static_log_config */
167 static apr_array_header_t *active_log_config;
168
169 module AP_MODULE_DECLARE_DATA ssl_ct_module;
170
171 #define SSL_CT_MUTEX_TYPE "ssl-ct-sct-update"
172
173 static apr_global_mutex_t *ssl_ct_sct_update;
174
175 static int refresh_all_scts(server_rec *s_main, apr_pool_t *p,
176                             apr_array_header_t *log_config);
177
178 static apr_thread_t *service_thread;
179
180 static apr_hash_t *cached_server_data;
181
182 static const char *audit_fn_perm, *audit_fn_active;
183 static apr_file_t *audit_file;
184 static int audit_file_nonempty;
185 static apr_thread_mutex_t *audit_file_mutex;
186 static apr_thread_mutex_t *cached_server_data_mutex;
187 static apr_thread_rwlock_t *log_config_rwlock;
188
189 #ifdef HAVE_SCT_DAEMON_CHILD
190
191 /* The APR other-child API doesn't tell us how the daemon exited
192  * (SIGSEGV vs. exit(1)).  The other-child maintenance function
193  * needs to decide whether to restart the daemon after a failure
194  * based on whether or not it exited due to a fatal startup error
195  * or something that happened at steady-state.  This exit status
196  * is unlikely to collide with exit signals.
197  */
198 #define DAEMON_STARTUP_ERROR 254
199
200 static int daemon_start(apr_pool_t *p, server_rec *main_server, apr_proc_t *procnew);
201 static server_rec *root_server = NULL;
202 static apr_pool_t *root_pool = NULL;
203 static pid_t daemon_pid;
204 static int daemon_should_exit = 0;
205
206 #endif /* HAVE_SCT_DAEMON_CHILD */
207
208 static apr_pool_t *pdaemon = NULL;
209
210 #ifdef HAVE_SCT_DAEMON_THREAD
211 static apr_thread_t *daemon_thread;
212 #endif /* HAVE_SCT_DAEMON_THREAD */
213
214 static const char *get_cert_fingerprint(apr_pool_t *p, const X509 *x)
215 {
216     const EVP_MD *digest;
217     unsigned char md[EVP_MAX_MD_SIZE];
218     unsigned int n;
219     digest = EVP_get_digestbyname("sha256");
220     X509_digest(x, digest, md, &n);
221
222     return apr_pescape_hex(p, md, n, 0);
223 }
224
225 /* a server's SCT-related storage on disk:
226  *
227  *   <rootdir>/<fingerprint>/servercerts.pem
228  *                  Concatenation of leaf certificate and any
229  *                  configured intermediate certificates
230  *
231  *   <rootdir>/<fingerprint>/logs  
232  *                  List of log URLs, one per line; this is
233  *                  used to recognize when a log URL configuration
234  *                  change makes our current SCT set invalid
235  *
236  *   <rootdir>/<fingerprint>/AUTO_hostname_port_uri.sct
237  *                  SCT for cert with this fingerprint
238  *                  from this log (could be any number
239  *                  of these)
240  *
241  *   <rootdir>/<fingerprint>/<anything>.sct
242  *                  (file is optional; could be any number
243  *                  of these; should not start with "AUTO_")
244  *                  Note that the administrator should store 
245  *                  statically maintained SCTs in a different
246  *                  directory for the server certificate (specified
247  *                  by the CTStaticSCTs directive).  A hypothetical
248  *                  external mechanism for maintaining SCTs following
249  *                  some other model could store them here for use
250  *                  by the server.
251  *
252  *   <rootdir>/<fingerprint>/collated
253  *                  one or more SCTs ready to send
254  *                  (this is all that the web server
255  *                  processes care about)
256  *
257  * Additionally, the CTStaticSCTs directive specifies a certificate-
258  * specific directory of statically-maintained SCTs to be sent.
259  */
260
261 #define SERVERCERTS_BASENAME   "servercerts.pem"
262 #define COLLATED_SCTS_BASENAME "collated"
263 #define LOGLIST_BASENAME       "logs"
264 #define LOG_SCT_PREFIX         "AUTO_" /* to distinguish from admin-created .sct
265                                         * files
266                                         */
267
268 static apr_status_t collate_scts(server_rec *s, apr_pool_t *p,
269                                  const char *cert_sct_dir,
270                                  const char *static_cert_sct_dir,
271                                  int max_sh_sct)
272 {
273     /* Read the various .sct files and stick them together in a single file */
274     apr_array_header_t *arr;
275     apr_status_t rv, tmprv;
276     apr_file_t *tmpfile;
277     apr_size_t bytes_written;
278     apr_uint16_t overall_len = 0;
279     char *tmp_collated_fn, *collated_fn;
280     const char *cur_sct_file;
281     const char * const *elts;
282     int i, scts_written = 0, skipped = 0;
283
284     rv = ctutil_path_join(&collated_fn, cert_sct_dir, COLLATED_SCTS_BASENAME, p, s);
285     if (rv != APR_SUCCESS) {
286         return rv;
287     }
288
289     /* Note: We rebuild the file that combines the SCTs every time this
290      *       code runs, even if no individual SCTs are new (or at least
291      *       re-fetched).
292      *       That allows the admin to see the last processing by looking
293      *       at the timestamp.
294      *       Rechecking even if no SCTs are new allows SCTs which were not
295      *       yet valid originally (just submitted to a log) to be used as
296      *       soon as practical.
297      */
298     tmp_collated_fn = apr_pstrcat(p, collated_fn, ".tmp", NULL);
299
300     rv = apr_file_open(&tmpfile, tmp_collated_fn,
301                        APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE
302                        |APR_FOPEN_BINARY|APR_FOPEN_BUFFERED,
303                        APR_FPROT_OS_DEFAULT, p);
304     if (rv != APR_SUCCESS) {
305         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
306                      "can't create %s", tmp_collated_fn);
307         return rv;
308     }
309
310     /* stick a 0 len (for the list) at the start of the file;
311      * we'll have to patch that later
312      */
313     rv = ctutil_file_write_uint16(s, tmpfile, overall_len);
314     if (rv != APR_SUCCESS) {
315         apr_file_close(tmpfile);
316         return rv;
317     }
318
319     arr = NULL; /* Build list from scratch, creating array */
320     rv = ctutil_read_dir(p, s, cert_sct_dir, "*.sct", &arr);
321     if (rv != APR_SUCCESS) {
322         apr_file_close(tmpfile);
323         return rv;
324     }
325
326     if (static_cert_sct_dir) {
327         /* Add in any SCTs that the administrator has configured */
328         rv = ctutil_read_dir(p, s, static_cert_sct_dir, "*.sct", &arr);
329         if (rv != APR_SUCCESS) {
330             apr_file_close(tmpfile);
331             return rv;
332         }
333     }
334
335     elts = (const char * const *)arr->elts;
336
337     for (i = 0; i < arr->nelts; i++) {
338         char *scts;
339         apr_size_t scts_size_wide;
340         apr_uint16_t scts_size;
341         sct_fields_t fields;
342
343         cur_sct_file = elts[i];
344
345         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
346                      "Adding SCT from file %s", cur_sct_file);
347
348         rv = ctutil_read_file(p, s, cur_sct_file, MAX_SCTS_SIZE, &scts,
349                               &scts_size_wide);
350         if (rv != APR_SUCCESS) {
351             break;
352         }
353         ap_assert(scts_size_wide <= USHRT_MAX);
354         scts_size = (apr_uint16_t)scts_size_wide;
355
356         rv = sct_parse(cur_sct_file,
357                        s, (const unsigned char *)scts, scts_size, NULL, &fields);
358         if (rv != APR_SUCCESS) {
359             sct_release(&fields);
360             break;
361         }
362
363         /* If the SCT has a timestamp in the future, it may have just been
364          * created by the log.
365          */
366         if (fields.time > apr_time_now()) {
367             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
368                          "SCT in file %s has timestamp in future (%s), skipping",
369                          cur_sct_file, fields.timestr);
370             sct_release(&fields);
371             continue;
372         }
373
374         sct_release(&fields);
375
376         /* Only now do we know that the SCT is valid to send, so
377          * see if it has to be skipped by configured limit.
378          */
379         if (scts_written >= max_sh_sct) {
380             skipped++;
381             continue;
382         }
383
384         overall_len += scts_size + 2; /* include size header */
385
386         rv = ctutil_file_write_uint16(s, tmpfile, (apr_uint16_t)scts_size);
387         if (rv != APR_SUCCESS) {
388             break;
389         }
390
391         rv = apr_file_write_full(tmpfile, scts, scts_size, &bytes_written);
392         if (rv != APR_SUCCESS) {
393             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
394                          "can't write %hu bytes to %s",
395                          scts_size, tmp_collated_fn);
396             break;
397         }
398
399         scts_written++;
400     }
401
402     if (rv == APR_SUCCESS && skipped) {
403         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
404                      "SCTs sent in ServerHello are limited to %d by "
405                      "CTServerHelloSCTLimit (ignoring %d)",
406                      max_sh_sct,
407                      skipped);
408     }
409
410     if (rv == APR_SUCCESS) {
411         apr_off_t offset = 0;
412
413         rv = apr_file_seek(tmpfile, APR_SET, &offset);
414         if (rv == APR_SUCCESS) {
415             rv = ctutil_file_write_uint16(s, tmpfile, overall_len);
416         }
417         if (rv != APR_SUCCESS) {
418             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
419                          "could not write the SCT list length at the start of the file");
420         }
421     }
422
423     tmprv = apr_file_close(tmpfile);
424     if (tmprv != APR_SUCCESS) {
425         ap_log_error(APLOG_MARK, APLOG_ERR, tmprv, s,
426                      "error flushing and closing %s", tmp_collated_fn);
427         if (rv == APR_SUCCESS) {
428             rv = tmprv;
429         }
430     }
431
432     if (rv == APR_SUCCESS && scts_written) {
433         int replacing = ctutil_file_exists(p, collated_fn);
434
435         if (replacing) {
436             if ((rv = apr_global_mutex_lock(ssl_ct_sct_update)) != APR_SUCCESS) {
437                 ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
438                              "global mutex lock failed");
439                 return rv;
440             }
441             apr_file_remove(collated_fn, p);
442         }
443         rv = apr_file_rename(tmp_collated_fn, collated_fn, p);
444         if (rv != APR_SUCCESS) {
445             ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
446                          "couldn't rename %s to %s, no SCTs to send for now",
447                          tmp_collated_fn, collated_fn);
448         }
449         if (replacing) {
450             if ((tmprv = apr_global_mutex_unlock(ssl_ct_sct_update)) != APR_SUCCESS) {
451                 ap_log_error(APLOG_MARK, APLOG_ERR, tmprv, s,
452                              "global mutex unlock failed");
453                 if (rv == APR_SUCCESS) {
454                     rv = tmprv;
455                 }
456             }
457         }
458     }
459
460     return rv;
461 }
462
463 static const char *url_to_fn(apr_pool_t *p, const apr_uri_t *log_url)
464 {
465     char *fn = apr_psprintf(p, LOG_SCT_PREFIX "%s_%s_%s.sct",
466                             log_url->hostname, log_url->port_str, log_url->path);
467     char *ch;
468
469     ch = fn;
470     while (*ch) {
471         switch(*ch) {
472         /* chars that shouldn't be used in a filename */
473         case ':':
474         case '/':
475         case '\\':
476         case '*':
477         case '?':
478         case '<':
479         case '>':
480         case '"':
481         case '|':
482             *ch = '-';
483         }
484         ++ch;
485     }
486     return fn;
487 }
488
489 static apr_status_t submission(server_rec *s, apr_pool_t *p, const char *ct_exe,
490                                const apr_uri_t *log_url, const char *cert_file,
491                                const char *sct_fn)
492 {
493     apr_status_t rv;
494     const char *args[8];
495     int i;
496
497     i = 0;
498     args[i++] = ct_exe;
499     args[i++] = apr_pstrcat(p, "--ct_server=", log_url->hostinfo, NULL);
500     args[i++] = "--http_log";
501     args[i++] = "--logtostderr";
502     args[i++] = apr_pstrcat(p, "--ct_server_submission=", cert_file, NULL);
503     args[i++] = apr_pstrcat(p, "--ct_server_response_out=", sct_fn, NULL);
504     args[i++] = "upload";
505     args[i++] = NULL;
506     ap_assert(i == sizeof args / sizeof args[0]);
507
508     rv = ctutil_run_to_log(p, s, args, "log client");
509
510     return rv;
511 }
512
513 static apr_status_t fetch_sct(server_rec *s, apr_pool_t *p,
514                               const char *cert_file,
515                               const char *cert_sct_dir,
516                               const apr_uri_t *log_url,
517                               const char *ct_exe, apr_time_t max_sct_age)
518 {
519     apr_status_t rv;
520     char *sct_fn;
521     apr_finfo_t finfo;
522     const char *log_url_basename;
523
524     log_url_basename = url_to_fn(p, log_url);
525
526     rv = ctutil_path_join(&sct_fn, cert_sct_dir, log_url_basename, p, s);
527     if (rv != APR_SUCCESS) {
528         return rv;
529     }
530
531     rv = apr_stat(&finfo, sct_fn, APR_FINFO_MTIME, p);
532     if (rv == APR_SUCCESS) {
533         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
534                      "Found SCT for %s in %s",
535                      cert_file, sct_fn);
536
537         if (finfo.mtime + max_sct_age < apr_time_now()) {
538             ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
539                          "SCT for %s is older than %d seconds, must refresh",
540                          cert_file,
541                          (int)(apr_time_sec(max_sct_age)));
542         }
543         else {
544             return APR_SUCCESS;
545         }
546     }
547     else {
548         ap_log_error(APLOG_MARK, APLOG_INFO,
549                      /* no need to print error string for file-not-found err */
550                      APR_STATUS_IS_ENOENT(rv) ? 0 : rv,
551                      s,
552                      "Did not find SCT for %s in %s, must fetch",
553                      cert_file, sct_fn);
554     }
555
556     rv = submission(s, p, ct_exe, log_url, cert_file, sct_fn);
557
558     return rv;
559 }
560
561 static apr_status_t record_log_urls(server_rec *s, apr_pool_t *p,
562                                     const char *listfile, apr_array_header_t *log_config)
563 {
564     apr_file_t *f;
565     apr_status_t rv, tmprv;
566     ct_log_config **config_elts;
567     int i;
568
569     rv = apr_file_open(&f, listfile,
570                        APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE
571                        |APR_FOPEN_BUFFERED,
572                        APR_FPROT_OS_DEFAULT, p);
573     if (rv != APR_SUCCESS) {
574         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
575                      "can't create %s", listfile);
576         return rv;
577     }
578
579     config_elts  = (ct_log_config **)log_config->elts;
580
581     for (i = 0; i < log_config->nelts; i++) {
582         if (!config_elts[i]->uri_str) {
583             continue;
584         }
585         if (!log_valid_for_sent_sct(config_elts[i])) {
586             continue;
587         }
588         rv = apr_file_puts(config_elts[i]->uri_str, f);
589         if (rv == APR_SUCCESS) {
590             rv = apr_file_puts("\n", f);
591         }
592         if (rv != APR_SUCCESS) {
593             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
594                          "error writing to %s", listfile);
595             break;
596         }
597     }
598
599     tmprv = apr_file_close(f);
600     if (tmprv != APR_SUCCESS) {
601         ap_log_error(APLOG_MARK, APLOG_ERR, tmprv, s,
602                      "error flushing and closing %s", listfile);
603         if (rv == APR_SUCCESS) {
604             rv = tmprv;
605         }
606     }
607
608     return rv;
609 }
610
611 static int uri_in_config(const char *needle, const apr_array_header_t *haystack)
612 {
613     ct_log_config **elts;
614     int i;
615
616     elts = (ct_log_config **)haystack->elts;
617     for (i = 0; i < haystack->nelts; i++) {
618         if (!elts[i]->uri_str) {
619             continue;
620         }
621         if (!log_valid_for_sent_sct(elts[i])) {
622             continue;
623         }
624         if (!strcmp(needle, elts[i]->uri_str)) {
625             return 1;
626         }
627     }
628
629     return 0;
630 }
631
632 static apr_status_t update_log_list_for_cert(server_rec *s, apr_pool_t *p,
633                                              const char *cert_sct_dir,
634                                              apr_array_header_t *log_config)
635 {
636     apr_array_header_t *old_urls;
637     apr_size_t contents_size;
638     apr_status_t rv;
639     char *contents, *listfile;
640
641     /* The set of logs can change, and we need to remove SCTs retrieved
642      * from logs that we no longer trust.  To track changes we'll use a
643      * file in the directory for the server certificate.
644      *
645      * (When can the set change?  Right now they can only change at [re]start,
646      * but in the future we should be able to find the set of trusted logs
647      * dynamically.)
648      */
649
650     rv = ctutil_path_join(&listfile, cert_sct_dir, LOGLIST_BASENAME, p, s);
651     if (rv != APR_SUCCESS) {
652         return rv;
653     }
654
655     if (ctutil_file_exists(p, listfile)) {
656         char **elts;
657         int i;
658
659         rv = ctutil_read_file(p, s, listfile, MAX_LOGLIST_SIZE, &contents, &contents_size);
660         if (rv != APR_SUCCESS) {
661             return rv;
662         }
663
664         ctutil_buffer_to_array(p, contents, contents_size, &old_urls);
665
666         elts = (char **)old_urls->elts;
667         for (i = 0; i < old_urls->nelts; i++) {
668             if (!uri_in_config(elts[i], log_config)) {
669                 char *sct_for_log;
670                 int exists;
671                 apr_uri_t uri;
672
673                 rv = apr_uri_parse(p, elts[i], &uri);
674                 if (rv != APR_SUCCESS) {
675                     ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
676                                  "unparseable log URL %s in file %s - ignoring",
677                                  elts[i], listfile);
678                     /* some garbage in the file? can't map to an auto-maintained SCT,
679                      * so just skip it
680                      */
681                     continue;
682                 }
683
684                 rv = ctutil_path_join(&sct_for_log, cert_sct_dir, url_to_fn(p, &uri), p, s);
685                 ap_assert(rv == APR_SUCCESS);
686                 exists = ctutil_file_exists(p, sct_for_log);
687
688                 ap_log_error(APLOG_MARK, 
689                              exists ? APLOG_NOTICE : APLOG_DEBUG, 0, s,
690                              "Log %s is no longer enabled%s",
691                              elts[i],
692                              exists ? ", removing SCT" : ", no SCT was present");
693
694                 if (exists) {
695                     rv = apr_file_remove(sct_for_log, p);
696                     if (rv != APR_SUCCESS) {
697                         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
698                                      "can't remove SCT %s from previously trusted log %s",
699                                      sct_for_log, elts[i]);
700                         return rv;
701                     }
702                 }
703             }
704         }
705     }
706     else {
707         /* can't tell what was trusted before; just remove everything
708          * that was created automatically
709          */
710         apr_array_header_t *arr;
711         const char * const *elts;
712         int i;
713
714         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
715                      "List of previous logs doesn't exist (%s), removing previously obtained SCTs",
716                      listfile);
717
718         arr = NULL; /* Build list from scratch, creating array */
719         rv = ctutil_read_dir(p, s, cert_sct_dir, LOG_SCT_PREFIX "*.sct", &arr);
720         if (rv != APR_SUCCESS) {
721             return rv;
722         }
723
724         elts = (const char * const *)arr->elts;
725         for (i = 0; i < arr->nelts; i++) {
726             const char *cur_sct_file = elts[i];
727
728             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
729                          "Removing %s", cur_sct_file);
730
731             rv = apr_file_remove(cur_sct_file, p);
732             if (rv != APR_SUCCESS) {
733                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
734                              "can't remove %s", cur_sct_file);
735             }
736         }
737     }
738
739     if (rv == APR_SUCCESS) {
740         rv = record_log_urls(s, p, listfile, log_config);
741     }
742
743     return rv;
744 }
745
746 static apr_status_t refresh_scts_for_cert(server_rec *s, apr_pool_t *p,
747                                           const char *cert_sct_dir,
748                                           const char *static_cert_sct_dir,
749                                           apr_array_header_t *log_config,
750                                           const char *ct_exe,
751                                           apr_time_t max_sct_age,
752                                           int max_sh_sct)
753 {
754     apr_status_t rv;
755     ct_log_config **config_elts;
756     char *cert_fn;
757     int i;
758
759     rv = ctutil_path_join(&cert_fn, cert_sct_dir, SERVERCERTS_BASENAME, p, s);
760     if (rv != APR_SUCCESS) {
761         return rv;
762     }
763
764     config_elts  = (ct_log_config **)log_config->elts;
765
766     if (ct_exe) {
767         rv = update_log_list_for_cert(s, p, cert_sct_dir, log_config);
768         if (rv != APR_SUCCESS) {
769             return rv;
770         }
771
772         for (i = 0; i < log_config->nelts; i++) {
773             if (!config_elts[i]->url) {
774                 continue;
775             }
776             if (!log_valid_for_sent_sct(config_elts[i])) {
777                 continue;
778             }
779             rv = fetch_sct(s, p, cert_fn,
780                            cert_sct_dir,
781                            &config_elts[i]->uri,
782                            ct_exe,
783                            max_sct_age);
784             if (rv != APR_SUCCESS) {
785                 return rv;
786             }
787         }
788     }
789     else {
790         /* Log client tool (from certificate-transparency open source project)
791          * not configured; we can only use admin-managed SCTs
792          */
793     }
794
795     rv = collate_scts(s, p, cert_sct_dir, static_cert_sct_dir, max_sh_sct);
796     if (rv != APR_SUCCESS) {
797         return rv;
798     }
799
800     return rv;
801 }
802
803 static void *run_service_thread(apr_thread_t *me, void *data)
804 {
805     server_rec *s = data;
806     ct_server_config *sconf = ap_get_module_config(s->module_config,
807                                                    &ssl_ct_module);
808     int mpmq_s;
809     apr_status_t rv;
810     int count = 0;
811
812     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
813                  SERVICE_THREAD_NAME " started");
814
815     while (1) {
816         if ((rv = ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s)) != APR_SUCCESS) {
817             break;
818         }
819         if (mpmq_s == AP_MPMQ_STOPPING) {
820             break;
821         }
822         apr_sleep(apr_time_from_sec(1));
823         if (++count >= 30) {
824             count = 0;
825             if (sconf->db_log_config) {
826                 /* Reload log config DB */
827                 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
828                              SERVICE_THREAD_NAME " - reloading config");
829                 ap_assert(apr_thread_rwlock_wrlock(log_config_rwlock) == 0);
830                 active_log_config = NULL;
831                 apr_pool_clear(sconf->db_log_config_pool);
832                 sconf->db_log_config =
833                     apr_array_make(sconf->db_log_config_pool, 2,
834                                    sizeof(ct_log_config *));
835                 rv = read_config_db(sconf->db_log_config_pool,
836                                     s, sconf->log_config_fname,
837                                     sconf->db_log_config);
838                 ap_assert(apr_thread_rwlock_unlock(log_config_rwlock) == 0);
839                 if (rv != APR_SUCCESS) {
840                     /* specific issue already logged */
841                     ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
842                                  SERVICE_THREAD_NAME " - no active configuration until "
843                                  "log config DB is corrected");
844                 }
845                 else {
846                     active_log_config = sconf->db_log_config;
847                 }
848             }
849         }
850     }
851
852     ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
853                  SERVICE_THREAD_NAME " exiting");
854
855     return NULL;
856 }
857
858 static apr_status_t wait_for_thread(void *data)
859 {
860     apr_thread_t *thd = data;
861     apr_status_t retval;
862
863     apr_thread_join(&retval, thd);
864     return APR_SUCCESS;
865 }
866
867 static void sct_daemon_cycle(ct_server_config *sconf, server_rec *s_main,
868                              apr_pool_t *ptemp, const char *daemon_name)
869 {
870     apr_status_t rv;
871
872     if (sconf->db_log_config) { /* not using static config */
873         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s_main,
874                      "%s - reloading config", daemon_name);
875         apr_pool_clear(sconf->db_log_config_pool);
876         active_log_config = NULL;
877         sconf->db_log_config =
878             apr_array_make(sconf->db_log_config_pool, 2,
879                            sizeof(ct_log_config *));
880         rv = read_config_db(sconf->db_log_config_pool,
881                             s_main, sconf->log_config_fname,
882                             sconf->db_log_config);
883         if (rv != APR_SUCCESS) {
884             ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s_main,
885                          "%s - no active configuration until "
886                          "log config DB is corrected", daemon_name);
887             return;
888         }
889         active_log_config = sconf->db_log_config;
890     }
891     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s_main,
892                  "%s - refreshing SCTs as needed", daemon_name);
893     rv = refresh_all_scts(s_main, ptemp, active_log_config);
894     if (rv != APR_SUCCESS) {
895         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s_main,
896                      "%s - SCT refresh failed; will try again later",
897                      daemon_name);
898     }
899 }
900
901 #ifdef HAVE_SCT_DAEMON_CHILD
902
903 static void daemon_signal_handler(int sig)
904 {
905     if (sig == SIGHUP) {
906         ++daemon_should_exit;
907     }
908 }
909
910 #if APR_HAS_OTHER_CHILD
911 static void daemon_maint(int reason, void *data, apr_wait_t status)
912 {
913     apr_proc_t *proc = data;
914     int mpm_state;
915     int stopping;
916
917     switch (reason) {
918         case APR_OC_REASON_DEATH:
919             apr_proc_other_child_unregister(data);
920             /* If apache is not terminating or restarting,
921              * restart the daemon
922              */
923             stopping = 1; /* if MPM doesn't support query,
924                            * assume we shouldn't restart daemon
925                            */
926             if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state) == APR_SUCCESS &&
927                 mpm_state != AP_MPMQ_STOPPING) {
928                 stopping = 0;
929             }
930             if (!stopping) {
931                 if (status == DAEMON_STARTUP_ERROR) {
932                     ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(01238)
933                                  DAEMON_NAME " failed to initialize");
934                 }
935                 else {
936                     ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(01239)
937                                  DAEMON_NAME " process died, restarting");
938                     daemon_start(root_pool, root_server, proc);
939                 }
940             }
941             break;
942         case APR_OC_REASON_RESTART:
943             /* don't do anything; server is stopping or restarting */
944             apr_proc_other_child_unregister(data);
945             break;
946         case APR_OC_REASON_LOST:
947             /* Restart the child cgid daemon process */
948             apr_proc_other_child_unregister(data);
949             daemon_start(root_pool, root_server, proc);
950             break;
951         case APR_OC_REASON_UNREGISTER:
952             /* we get here when pcgi is cleaned up; pcgi gets cleaned
953              * up when pconf gets cleaned up
954              */
955             kill(proc->pid, SIGHUP); /* send signal to daemon telling it to die */
956             break;
957     }
958 }
959 #endif
960
961 static int sct_daemon(server_rec *s_main)
962 {
963     apr_status_t rv;
964     apr_pool_t *ptemp;
965     ct_server_config *sconf = ap_get_module_config(s_main->module_config,
966                                                    &ssl_ct_module);
967     int rc;
968
969     /* Ignoring SIGCHLD results in errno ECHILD returned from apr_proc_wait().
970      * apr_signal(SIGCHLD, SIG_IGN);
971      */
972     apr_signal(SIGHUP, daemon_signal_handler);
973
974     /* Close our copy of the listening sockets */
975     ap_close_listeners();
976
977     rv = apr_global_mutex_child_init(&ssl_ct_sct_update,
978                                      apr_global_mutex_lockfile(ssl_ct_sct_update), pdaemon);
979     if (rv != APR_SUCCESS) {
980         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, root_server,
981                      "could not initialize " SSL_CT_MUTEX_TYPE
982                      " mutex in " DAEMON_NAME);
983         return DAEMON_STARTUP_ERROR;
984     }
985
986     if (!geteuid()) {
987         /* Fix up permissions of the directories written to by the daemon
988          */
989         int i;
990         apr_array_header_t *subdirs = apr_array_make(pdaemon, 5, sizeof(char *));
991
992         *(const char **)apr_array_push(subdirs) = sconf->sct_storage;
993         if (sconf->audit_storage) {
994             *(const char **)apr_array_push(subdirs) = sconf->audit_storage;
995         }
996
997         rv = ctutil_read_dir(pdaemon, root_server, sconf->sct_storage, "*",
998                              &subdirs);
999         if (rv == APR_SUCCESS && subdirs->nelts > 0) {
1000             const char * const *elts = (const char * const *)subdirs->elts;
1001
1002             for (i = 0; i < subdirs->nelts; i++) {
1003                 if (elts[i] && chown(elts[i], ap_unixd_config.user_id,
1004                                      ap_unixd_config.group_id) < 0) {
1005                     ap_log_error(APLOG_MARK, APLOG_ERR, errno, root_server,
1006                                  "Couldn't change owner or group of directory %s",
1007                                  elts[i]);
1008                     return errno;
1009                 }
1010             }
1011         }
1012         else {
1013             ap_log_error(APLOG_MARK, APLOG_WARNING, rv, root_server,
1014                          "Did not read any entries from %s (no server certificate?)",
1015                          sconf->sct_storage);
1016         }
1017     }
1018
1019     /* if running as root, switch to configured user/group */
1020     if ((rc = ap_run_drop_privileges(pdaemon, ap_server_conf)) != 0) {
1021         return rc;
1022     }
1023
1024     /* ptemp - temporary pool for refresh cycles */
1025     apr_pool_create(&ptemp, pdaemon);
1026
1027     while (!daemon_should_exit) {
1028         sct_daemon_cycle(sconf, s_main, ptemp, DAEMON_NAME);
1029         apr_sleep(apr_time_from_sec(30)); /* SIGHUP at restart/stop will break out */
1030     }
1031
1032     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s_main,
1033                  DAEMON_NAME " - exiting");
1034
1035     return 0;
1036 }
1037
1038 static int daemon_start(apr_pool_t *p, server_rec *main_server,
1039                         apr_proc_t *procnew)
1040 {
1041     daemon_should_exit = 0; /* clear setting from previous generation */
1042     if ((daemon_pid = fork()) < 0) {
1043         ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
1044                      "Couldn't create " DAEMON_NAME " process");
1045         return DECLINED;
1046     }
1047     else if (daemon_pid == 0) {
1048         if (pdaemon == NULL) {
1049             apr_pool_create(&pdaemon, p);
1050         }
1051         exit(sct_daemon(main_server) > 0 ? DAEMON_STARTUP_ERROR : -1);
1052     }
1053     procnew->pid = daemon_pid;
1054     procnew->err = procnew->in = procnew->out = NULL;
1055     apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);
1056 #if APR_HAS_OTHER_CHILD
1057     apr_proc_other_child_register(procnew, daemon_maint, procnew, NULL, p);
1058 #endif
1059     return OK;
1060 }
1061 #endif /* HAVE_SCT_DAEMON_CHILD */
1062
1063 #ifdef HAVE_SCT_DAEMON_THREAD
1064 static void *sct_daemon_thread(apr_thread_t *me, void *data)
1065 {
1066     server_rec *s = data;
1067     ct_server_config *sconf = ap_get_module_config(s->module_config,
1068                                                    &ssl_ct_module);
1069     int mpmq_s;
1070     apr_pool_t *ptemp;
1071     apr_status_t rv;
1072     int count = 0;
1073
1074     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
1075                  DAEMON_THREAD_NAME " started");
1076
1077     /* ptemp - temporary pool for refresh cycles */
1078     apr_pool_create(&ptemp, pdaemon);
1079
1080     while (1) {
1081         if ((rv = ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s)) != APR_SUCCESS) {
1082             break;
1083         }
1084         if (mpmq_s == AP_MPMQ_STOPPING) {
1085             break;
1086         }
1087         apr_sleep(apr_time_from_sec(1));
1088         if (++count >= 30) {
1089             count = 0;
1090             sct_daemon_cycle(sconf, s, ptemp, DAEMON_THREAD_NAME);
1091         }
1092     }
1093
1094     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
1095                  DAEMON_THREAD_NAME " - exiting");
1096
1097     return NULL;
1098 }
1099
1100 static int daemon_thread_start(apr_pool_t *pconf, server_rec *s_main)
1101 {
1102     apr_status_t rv;
1103
1104     apr_pool_create(&pdaemon, pconf);
1105     rv = apr_thread_create(&daemon_thread, NULL, sct_daemon_thread, s_main,
1106                            pconf);
1107     if (rv != APR_SUCCESS) {
1108         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s_main,
1109                      "could not create " DAEMON_THREAD_NAME " in parent");
1110         return HTTP_INTERNAL_SERVER_ERROR;
1111     }
1112
1113     apr_pool_cleanup_register(pconf, daemon_thread, wait_for_thread,
1114                               apr_pool_cleanup_null);
1115
1116     return OK;
1117 }
1118 #endif /* HAVE_SCT_DAEMON_THREAD */
1119
1120 static apr_status_t ssl_ct_mutex_remove(void *data)
1121 {
1122     apr_global_mutex_destroy(ssl_ct_sct_update);
1123     ssl_ct_sct_update = NULL;
1124     return APR_SUCCESS;
1125 }
1126
1127 static int refresh_all_scts(server_rec *s_main, apr_pool_t *p,
1128                             apr_array_header_t *log_config)
1129 {
1130     apr_hash_t *already_processed;
1131     apr_status_t rv = APR_SUCCESS;
1132     server_rec *s;
1133
1134     already_processed = apr_hash_make(p);
1135
1136     s = s_main;
1137     while (s) {
1138         ct_server_config *sconf = ap_get_module_config(s->module_config,
1139                                                        &ssl_ct_module);
1140         int i;
1141         const ct_server_cert_info *cert_info_elts;
1142
1143         if (sconf && sconf->server_cert_info) {
1144             cert_info_elts =
1145                 (const ct_server_cert_info *)sconf->server_cert_info->elts;
1146             for (i = 0; i < sconf->server_cert_info->nelts; i++) {
1147                 /* we may have already processed this cert for another
1148                  * server_rec
1149                  */
1150                 if (!apr_hash_get(already_processed, cert_info_elts[i].sct_dir,
1151                                   APR_HASH_KEY_STRING)) {
1152                     const char *static_cert_sct_dir = 
1153                         apr_hash_get(sconf->static_cert_sct_dirs,
1154                                      cert_info_elts[i].fingerprint,
1155                                      APR_HASH_KEY_STRING);
1156
1157                     apr_hash_set(already_processed, cert_info_elts[i].sct_dir,
1158                                  APR_HASH_KEY_STRING, "done");
1159                     rv = refresh_scts_for_cert(s_main, p,
1160                                                cert_info_elts[i].sct_dir,
1161                                                static_cert_sct_dir,
1162                                                log_config,
1163                                                sconf->ct_exe,
1164                                                sconf->max_sct_age,
1165                                                sconf->max_sh_sct);
1166                     if (rv != APR_SUCCESS) {
1167                         return rv;
1168                     }
1169                 }
1170             }
1171         }
1172
1173         s = s->next;
1174     }
1175
1176     return rv;
1177 }
1178
1179 static int num_server_certs(server_rec *s_main)
1180 {
1181     int num = 0;
1182     server_rec *s;
1183
1184     s = s_main;
1185     while (s) {
1186         ct_server_config *sconf = ap_get_module_config(s->module_config,
1187                                                        &ssl_ct_module);
1188
1189         if (sconf && sconf->server_cert_info) {
1190             num += sconf->server_cert_info->nelts;
1191         }
1192         s = s->next;
1193     }
1194
1195     return num;
1196 }
1197
1198 static int ssl_ct_post_config(apr_pool_t *pconf, apr_pool_t *plog,
1199                               apr_pool_t *ptemp, server_rec *s_main)
1200 {
1201     ct_server_config *sconf = ap_get_module_config(s_main->module_config,
1202                                                    &ssl_ct_module);
1203     apr_status_t rv;
1204 #ifdef HAVE_SCT_DAEMON_CHILD
1205     apr_proc_t *procnew = NULL;
1206     const char *userdata_key = "sct_daemon_init";
1207
1208     root_server = s_main;
1209     root_pool = pconf;
1210
1211     procnew = ap_retained_data_get(userdata_key);
1212     if (!procnew) {
1213         procnew = ap_retained_data_create(userdata_key, sizeof(*procnew));
1214         procnew->pid = -1;
1215         procnew->err = procnew->in = procnew->out = NULL;
1216     }
1217 #endif /* HAVE_SCT_DAEMON_CHILD */
1218
1219     if (num_server_certs(s_main) == 0) {
1220         /* Theoretically this module could operate in a proxy-only
1221          * configuration, where httpd does not act as a TLS server but proxy is
1222          * configured as a TLS client.  That isn't currently implemented.
1223          */
1224         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s_main,
1225                      "No server certificates were found.");
1226         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s_main,
1227                      "mod_ssl_ct only supports configurations with a TLS server.");
1228         return HTTP_INTERNAL_SERVER_ERROR;
1229     }
1230
1231     rv = ap_global_mutex_create(&ssl_ct_sct_update, NULL,
1232                                 SSL_CT_MUTEX_TYPE, NULL, s_main, pconf, 0);
1233     if (rv != APR_SUCCESS) {
1234         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s_main,
1235                      "could not create global mutex");
1236         return HTTP_INTERNAL_SERVER_ERROR;
1237     }
1238
1239     apr_pool_cleanup_register(pconf, (void *)s_main, ssl_ct_mutex_remove,
1240                               apr_pool_cleanup_null);
1241
1242     if (sconf->log_config_fname) {
1243         if (!sconf->db_log_config) {
1244             /* log config db in separate pool that can be cleared */
1245             apr_pool_create(&sconf->db_log_config_pool, pconf);
1246             sconf->db_log_config =
1247                 apr_array_make(sconf->db_log_config_pool, 2,
1248                                sizeof(ct_log_config *));
1249         }
1250         rv = read_config_db(sconf->db_log_config_pool,
1251                             s_main, sconf->log_config_fname,
1252                             sconf->db_log_config);
1253         if (rv != APR_SUCCESS) {
1254             return HTTP_INTERNAL_SERVER_ERROR;
1255         }
1256     }
1257
1258     if (sconf->static_log_config && sconf->db_log_config) {
1259         if (sconf->static_log_config->nelts > 0
1260             && sconf->db_log_config->nelts > 0) {
1261             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s_main,
1262                          "Either the static log configuration or the db log "
1263                          "configuration must be empty");
1264             return HTTP_INTERNAL_SERVER_ERROR;
1265         }
1266     }
1267
1268     if (sconf->static_log_config && sconf->static_log_config->nelts > 0) {
1269         active_log_config = sconf->static_log_config;
1270     }
1271     else if (sconf->db_log_config && sconf->db_log_config->nelts > 0) {
1272         active_log_config = sconf->db_log_config;
1273     }
1274     else {
1275         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s_main,
1276                      "No log URLs were configured; only admin-managed SCTs can be sent");
1277         /* if a db is configured, it could be updated later */
1278         if (!sconf->db_log_config) { /* no DB configured, need permanently
1279                                       * empty array */
1280             active_log_config = apr_array_make(pconf, 1,
1281                                                sizeof(ct_log_config *));
1282         }
1283     }
1284
1285     /* Ensure that we already have, or can fetch, fresh SCTs for each 
1286      * certificate.  If so, start the daemon to maintain these and let
1287      * startup continue.  (Otherwise abort startup.)
1288      *
1289      * Except when we start up as root.  We don't want to run external
1290      * certificate-transparency tools as root, and we don't want to have
1291      * to fix up the permissions of everything we created so that the
1292      * SCT maintenance daemon can continue to maintain the SCTs as the
1293      * configured User/Group.
1294      */
1295
1296 #if AP_NEED_SET_MUTEX_PERMS /* Unix :) */
1297     if (!geteuid()) { /* root */
1298         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s_main,
1299                      "SCTs will be fetched from configured logs as needed "
1300                      "and may not be available immediately");
1301     }
1302     else {
1303 #endif
1304     rv = refresh_all_scts(s_main, pconf, active_log_config);
1305     if (rv != APR_SUCCESS) {
1306         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s_main,
1307                      "refresh_all_scts() failed");
1308         return HTTP_INTERNAL_SERVER_ERROR;
1309     }
1310 #if AP_NEED_SET_MUTEX_PERMS
1311     }
1312 #endif
1313
1314 #ifdef HAVE_SCT_DAEMON_CHILD
1315     if (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG) {
1316         int ret = daemon_start(pconf, s_main, procnew);
1317         if (ret != OK) {
1318             return ret;
1319         }
1320     }
1321 #endif /* HAVE_SCT_DAEMON_CHILD */
1322
1323 #ifdef HAVE_SCT_DAEMON_THREAD
1324     /* WIN32-ism: ensure this is the parent by checking AP_PARENT_PID,
1325      * which is only set in WinNT children.
1326      */
1327     if (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG
1328         && !getenv("AP_PARENT_PID")) {
1329         int ret = daemon_thread_start(pconf, s_main);
1330         if (ret != OK) {
1331             return ret;
1332         }
1333     }
1334 #endif /* HAVE_SCT_DAEMON_THREAD */
1335
1336     return OK;
1337 }
1338
1339 static int ssl_ct_check_config(apr_pool_t *pconf, apr_pool_t *plog,
1340                               apr_pool_t *ptemp, server_rec *s_main)
1341 {
1342     ct_server_config *sconf = ap_get_module_config(s_main->module_config,
1343                                                    &ssl_ct_module);
1344
1345     if (!sconf->sct_storage) {
1346         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s_main,
1347                      "Directive CTSCTStorage is required");
1348         return HTTP_INTERNAL_SERVER_ERROR;
1349     }
1350
1351     if (!sconf->audit_storage) {
1352         /* umm, hard to tell if needed...  must have server with
1353          * SSL proxy enabled and server-specific-sconf->proxy_awareness
1354          * != PROXY_OBLIVIOUS...
1355          */
1356         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s_main,
1357                      "Directive CTAuditStorage isn't set; proxy will not save "
1358                      "data for off-line audit");
1359     }
1360
1361     if (!sconf->ct_exe) {
1362         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s_main,
1363                      "Directive CTLogClient isn't set; server certificates "
1364                      "can't be submitted to configured logs; only admin-"
1365                      "managed SCTs can be provided to clients");
1366     }
1367
1368     if (sconf->log_config_fname) {
1369         const char *msg = NULL;
1370         if (!log_config_readable(pconf, sconf->log_config_fname, &msg)) {
1371             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s_main,
1372                          "Log config file %s cannot be read",
1373                          sconf->log_config_fname);
1374             if (msg) {
1375                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s_main,
1376                             "%s", msg);
1377             }
1378             return HTTP_INTERNAL_SERVER_ERROR;
1379         }
1380     }
1381
1382     return OK;
1383 }
1384
1385 static apr_status_t read_scts(apr_pool_t *p, const char *fingerprint,
1386                               const char *sct_dir,
1387                               server_rec *s,
1388                               char **scts, apr_size_t *scts_len)
1389 {
1390     apr_status_t rv, tmprv;
1391     char *cert_dir, *sct_fn;
1392
1393     rv = ctutil_path_join(&cert_dir, sct_dir, fingerprint, p, s);
1394     if (rv != APR_SUCCESS) {
1395         return rv;
1396     }
1397
1398     rv = ctutil_path_join(&sct_fn, cert_dir, COLLATED_SCTS_BASENAME, p, s);
1399     if (rv != APR_SUCCESS) {
1400         return rv;
1401     }
1402
1403     if ((rv = apr_global_mutex_lock(ssl_ct_sct_update)) != APR_SUCCESS) {
1404         ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
1405                      "global mutex lock failed");
1406         return rv;
1407     }
1408
1409     rv = ctutil_read_file(p, s, sct_fn, MAX_SCTS_SIZE, scts, scts_len);
1410
1411     if ((tmprv = apr_global_mutex_unlock(ssl_ct_sct_update)) != APR_SUCCESS) {
1412         ap_log_error(APLOG_MARK, APLOG_ERR, tmprv, s,
1413                      "global mutex unlock failed");
1414     }
1415
1416     return rv;
1417 }
1418
1419 static void look_for_server_certs(server_rec *s, SSL_CTX *ctx, const char *sct_dir)
1420 {
1421     ct_server_config *sconf = ap_get_module_config(s->module_config,
1422                                                    &ssl_ct_module);
1423     apr_pool_t *p = s->process->pool;
1424     apr_status_t rv;
1425     FILE *concat;
1426     X509 *x;
1427     STACK_OF(X509) *chain;
1428     int i, rc;
1429     char *cert_sct_dir, *servercerts_pem;
1430     const char *fingerprint;
1431     ct_server_cert_info *cert_info;
1432
1433     sconf->server_cert_info = apr_array_make(p, 2, sizeof(ct_server_cert_info));
1434
1435     rc = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST);
1436     while (rc) {
1437         x = SSL_CTX_get0_certificate(ctx); /* UNDOC */
1438         if (x) {
1439             fingerprint = get_cert_fingerprint(s->process->pool, x);
1440             rv = ctutil_path_join(&cert_sct_dir, sct_dir, fingerprint, p, s);
1441             ap_assert(rv == APR_SUCCESS);
1442
1443             if (!ctutil_dir_exists(p, cert_sct_dir)) {
1444                 rv = apr_dir_make(cert_sct_dir, APR_FPROT_OS_DEFAULT, p);
1445                 if (rv != APR_SUCCESS) {
1446                     ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
1447                                  "can't create directory %s",
1448                                  cert_sct_dir);
1449                     ap_assert(rv == APR_SUCCESS);
1450                 }
1451             }
1452
1453             rv = ctutil_path_join(&servercerts_pem, cert_sct_dir,
1454                                   SERVERCERTS_BASENAME, p, s);
1455             ap_assert(rv == APR_SUCCESS);
1456
1457             rv = ctutil_fopen(servercerts_pem, "wb", &concat);
1458             ap_assert(rv == APR_SUCCESS);
1459
1460             ap_assert(1 == PEM_write_X509(concat, x)); /* leaf */
1461
1462             chain = NULL;
1463
1464             /* Not this: SSL_CTX_get0_chain_certs(ctx, &chain);
1465              *
1466              * See this thread:
1467              *   http://mail-archives.apache.org/mod_mbox/httpd-dev/
1468              *   201402.mbox/%3CCAKUrXK5-2_Sg8FokxBP8nW7tmSuTZZWL-%3
1469              *   DBDhNnwyK-Z4dmQiQ%40mail.gmail.com%3E
1470              */
1471             SSL_CTX_get_extra_chain_certs(ctx, &chain); /* UNDOC */
1472
1473             if (chain) {
1474                 for (i = 0; i < sk_X509_num(chain); i++) { /* UNDOC */
1475                     X509 *x = sk_X509_value(chain, i); /* UNDOC */
1476                     ap_assert(1 == PEM_write_X509(concat, x));
1477                 }
1478             }
1479             ap_assert(0 == fclose(concat));
1480
1481             ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
1482                          "wrote server cert and chain to %s", servercerts_pem);
1483
1484             cert_info = (ct_server_cert_info *)apr_array_push(sconf->server_cert_info);
1485             cert_info->sct_dir = cert_sct_dir;
1486             cert_info->fingerprint = fingerprint;
1487         }
1488         else {
1489             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
1490                          "could not find leaf certificate");
1491         }
1492         rc = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT);
1493     }
1494 }
1495
1496 static ct_conn_config *get_conn_config(conn_rec *c)
1497 {
1498     ct_conn_config *conncfg =
1499       ap_get_module_config(c->conn_config, &ssl_ct_module);
1500
1501     if (!conncfg) {
1502         conncfg = apr_pcalloc(c->pool, sizeof *conncfg);
1503         ap_set_module_config(c->conn_config, &ssl_ct_module, conncfg);
1504     }
1505
1506     return conncfg;
1507 }
1508
1509 static void client_is_ct_aware(conn_rec *c)
1510 {
1511     ct_conn_config *conncfg = get_conn_config(c);
1512     conncfg->peer_ct_aware = 1;
1513 }
1514
1515 static int is_client_ct_aware(conn_rec *c)
1516 {
1517     ct_conn_config *conncfg = get_conn_config(c);
1518
1519     return conncfg->peer_ct_aware;
1520 }
1521
1522 static void server_cert_has_sct_list(conn_rec *c)
1523 {
1524     ct_conn_config *conncfg = get_conn_config(c);
1525     conncfg->server_cert_has_sct_list = 1;
1526     conncfg->peer_ct_aware = 1;
1527 }
1528
1529 /* Look at SSLClient::VerifyCallback() and WriteSSLClientCTData()
1530  * for validation and saving of data for auditing in a form that
1531  * the c-t tools can use.
1532  */
1533
1534 static cert_chain *cert_chain_init(apr_pool_t *p, STACK_OF(X509) *chain)
1535 {
1536     cert_chain *cc = apr_pcalloc(p, sizeof(cert_chain));
1537     int i;
1538
1539     cc->cert_arr = apr_array_make(p, 4, sizeof(X509 *));
1540
1541     for (i = 0; i < sk_X509_num(chain); i++) {
1542         X509 **spot = apr_array_push(cc->cert_arr);
1543         *spot = X509_dup(sk_X509_value(chain, i)); /* UNDOC */
1544         if (i == 0) {
1545             cc->leaf = *spot;
1546         }
1547     }
1548
1549     return cc;
1550 }
1551
1552 static void cert_chain_free(cert_chain *cc) {
1553     X509 **elts = (X509 **)cc->cert_arr->elts;
1554     int i;
1555
1556     for (i = 0; i < cc->cert_arr->nelts; i++) {
1557         X509_free(elts[i]);
1558     }
1559 }
1560
1561 /* Create hash of leaf certificate and any SCTs so that
1562  * we can determine whether or not we've seen this exact
1563  * info from the server before.
1564  */
1565 static const char *gen_key(conn_rec *c, cert_chain *cc,
1566                            ct_conn_config *conncfg)
1567 {
1568     const char *fp;
1569     SHA256_CTX sha256ctx;
1570     unsigned char digest[SHA256_DIGEST_LENGTH];
1571
1572     fp = get_cert_fingerprint(c->pool, cc->leaf);
1573
1574     SHA256_Init(&sha256ctx); /* UNDOC */
1575     SHA256_Update(&sha256ctx, (unsigned char *)fp, strlen(fp)); /* UNDOC */
1576     if (conncfg->cert_sct_list) {
1577         SHA256_Update(&sha256ctx, conncfg->cert_sct_list, 
1578                       conncfg->cert_sct_list_size);
1579     }
1580     if (conncfg->serverhello_sct_list) {
1581         SHA256_Update(&sha256ctx, conncfg->serverhello_sct_list,
1582                       conncfg->serverhello_sct_list_size);
1583     }
1584     if (conncfg->ocsp_sct_list) {
1585         SHA256_Update(&sha256ctx, conncfg->ocsp_sct_list,
1586                       conncfg->ocsp_sct_list_size);
1587     }
1588     SHA256_Final(digest, &sha256ctx); /* UNDOC */
1589     return apr_pescape_hex(c->pool, digest, sizeof digest, 0);
1590 }
1591
1592 static apr_status_t deserialize_SCTs(apr_pool_t *p,
1593                                      ct_conn_config *conncfg,
1594                                      void *sct_list,
1595                                      apr_size_t sct_list_size)
1596 {
1597     apr_size_t avail, len_of_data;
1598     apr_status_t rv;
1599     const unsigned char *mem, *start_of_data;
1600
1601     mem = sct_list;
1602     avail = sct_list_size;
1603
1604     /* Make sure the overall length is correct */
1605
1606     rv = ctutil_read_var_bytes((const unsigned char **)&mem,
1607                                &avail, &start_of_data, &len_of_data);
1608     if (rv != APR_SUCCESS) {
1609         return rv;
1610     }
1611
1612     if (len_of_data + sizeof(apr_uint16_t) != sct_list_size) {
1613         return APR_EINVAL;
1614     }
1615
1616     /* add each SCT in the list to the all_scts array */
1617
1618     mem = (unsigned char *)sct_list + sizeof(apr_uint16_t);
1619     avail = sct_list_size - sizeof(apr_uint16_t);
1620
1621     while (rv == APR_SUCCESS && avail > 0) {
1622         rv = ctutil_read_var_bytes((const unsigned char **)&mem, &avail, 
1623                                    &start_of_data, &len_of_data);
1624         if (rv == APR_SUCCESS) {
1625             ct_sct_data *sct = (ct_sct_data *)apr_array_push(conncfg->all_scts);
1626
1627             sct->data = start_of_data;
1628             ap_assert(len_of_data <= USHRT_MAX);
1629             sct->len = (apr_uint16_t)len_of_data;
1630         }
1631     }
1632
1633     if (rv == APR_SUCCESS && avail != 0) {
1634         return APR_EINVAL;
1635     }
1636
1637     return APR_SUCCESS;
1638 }
1639
1640 /* perform quick sanity check of server SCT(s) during handshake;
1641  * errors should result in fatal alert
1642  */
1643 static apr_status_t validate_server_data(apr_pool_t *p, conn_rec *c,
1644                                          cert_chain *cc, ct_conn_config *conncfg,
1645                                          ct_server_config *sconf)
1646 {
1647     apr_status_t rv = APR_SUCCESS;
1648
1649 #if AP_MODULE_MAGIC_AT_LEAST(20130702,2)
1650     if (conncfg->serverhello_sct_list) {
1651         ap_log_cdata(APLOG_MARK, APLOG_TRACE6, c, "SCT(s) from ServerHello",
1652                      conncfg->serverhello_sct_list,
1653                      conncfg->serverhello_sct_list_size,
1654                      AP_LOG_DATA_SHOW_OFFSET);
1655     }
1656
1657     if (conncfg->cert_sct_list) {
1658         ap_log_cdata(APLOG_MARK, APLOG_TRACE6, c, "SCT(s) from certificate",
1659                      conncfg->cert_sct_list,
1660                      conncfg->cert_sct_list_size,
1661                      AP_LOG_DATA_SHOW_OFFSET);
1662     }
1663
1664     if (conncfg->ocsp_sct_list) {
1665         ap_log_cdata(APLOG_MARK, APLOG_TRACE6, c, "SCT(s) from stapled OCSP response",
1666                      conncfg->ocsp_sct_list,
1667                      conncfg->ocsp_sct_list_size,
1668                      AP_LOG_DATA_SHOW_OFFSET);
1669     }
1670 #endif /* httpd has ap_log_*data() */
1671
1672     if (!conncfg->all_scts) {
1673         conncfg->all_scts = apr_array_make(p, 4, sizeof(ct_sct_data));
1674     }
1675
1676     /* deserialize all the SCTs */
1677     if (conncfg->cert_sct_list) {
1678         rv = deserialize_SCTs(p, conncfg, conncfg->cert_sct_list,
1679                               conncfg->cert_sct_list_size);
1680         if (rv != APR_SUCCESS) {
1681             ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c,
1682                           "couldn't deserialize SCT list from certificate");
1683         }
1684     }
1685     if (rv == APR_SUCCESS && conncfg->serverhello_sct_list) {
1686         rv = deserialize_SCTs(p, conncfg, conncfg->serverhello_sct_list,
1687                               conncfg->serverhello_sct_list_size);
1688         if (rv != APR_SUCCESS) {
1689             ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c,
1690                           "couldn't deserialize SCT list from ServerHello");
1691         }
1692     }
1693     if (rv == APR_SUCCESS && conncfg->ocsp_sct_list) {
1694         rv = deserialize_SCTs(p, conncfg, conncfg->ocsp_sct_list,
1695                               conncfg->ocsp_sct_list_size);
1696         if (rv != APR_SUCCESS) {
1697             ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c,
1698                           "couldn't deserialize SCT list from stapled OCSP response");
1699         }
1700     }
1701
1702     if (rv == APR_SUCCESS) {
1703         if (conncfg->all_scts->nelts < 1) {
1704             /* How did we get here without at least one SCT? */
1705             ap_log_cerror(APLOG_MARK, APLOG_CRIT, 0, c,
1706                           "SNAFU: No deserialized SCTs found in validate_server_data()");
1707             rv = APR_EINVAL;
1708         }
1709         else {
1710             apr_status_t tmprv;
1711             int i, verification_failures, verification_successes, unknown_log_ids;
1712             ct_sct_data *sct_elts;
1713             ct_sct_data sct;
1714             sct_fields_t fields;
1715
1716             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
1717                           "%d SCTs received total", conncfg->all_scts->nelts);
1718
1719             verification_failures = verification_successes = unknown_log_ids = 0;
1720             sct_elts = (ct_sct_data *)conncfg->all_scts->elts;
1721             for (i = 0; i < conncfg->all_scts->nelts; i++) {
1722                 sct = sct_elts[i];
1723                 tmprv = sct_parse("backend server", c->base_server, 
1724                                   sct.data, sct.len, cc,
1725                                   &fields);
1726                 if (tmprv != APR_SUCCESS) {
1727                     rv = tmprv;
1728                 }
1729                 else {
1730                     tmprv = sct_verify_timestamp(c, &fields);
1731                     if (tmprv != APR_SUCCESS) {
1732                         verification_failures++;
1733                     }
1734
1735                     if (active_log_config) {
1736                         /* will only block if we have a DB-based log
1737                          * configuration which is currently being refreshed
1738                          */
1739                         ap_assert(apr_thread_rwlock_rdlock(log_config_rwlock)
1740                                   == APR_SUCCESS);
1741                         tmprv = sct_verify_signature(c, &fields,
1742                                                      active_log_config);
1743                         ap_assert(apr_thread_rwlock_unlock(log_config_rwlock)
1744                                   == APR_SUCCESS);
1745                         if (tmprv == APR_NOTFOUND) {
1746                             ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c,
1747                                           "Server sent SCT from unrecognized log");
1748                             unknown_log_ids++;
1749                         }
1750                         else if (tmprv != APR_SUCCESS) {
1751                             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
1752                                           "Server sent SCT with invalid signature");
1753                             tmprv = APR_EINVAL;
1754                             verification_failures++;
1755                         }
1756                         else {
1757                             verification_successes++;
1758                         }
1759                     }
1760                     else {
1761                         unknown_log_ids++;
1762                         ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c,
1763                                       "Signature of SCT from server could not be "
1764                                       "verified (no configured log public keys)");
1765                     }
1766                 }
1767                 sct_release(&fields);
1768             }
1769             if (verification_failures && !verification_successes) {
1770                 /* If no SCTs are valid, don't communicate. */
1771                 rv = APR_EINVAL;
1772             }
1773             ap_log_cerror(APLOG_MARK,
1774                           rv != APR_SUCCESS ? APLOG_ERR : APLOG_INFO, 0, c,
1775                           "Signature/timestamp validation for %d SCTs: %d successes, "
1776                           "%d failures, %d from unknown logs",
1777                           conncfg->all_scts->nelts, verification_successes,
1778                           verification_failures, unknown_log_ids);
1779         }
1780     }
1781
1782     return rv;
1783 }
1784
1785 /* Enqueue data from server for off-line audit (cert, SCT(s))
1786  * We already filtered out duplicate data being saved from this
1787  * process.  (With reverse proxy it will be the same data over
1788  * and over.)
1789  */
1790 #define SERVER_START 0x0001
1791 #define KEY_START    0x0002
1792 #define CERT_START   0x0003
1793 #define SCT_START    0x0004
1794
1795 static void save_server_data(conn_rec *c, cert_chain *cc,
1796                              ct_conn_config *conncfg,
1797                              const char *key)
1798 {
1799     if (audit_file_mutex && audit_file) { /* child init successful, no
1800                                            * subsequent error
1801                                            */
1802         apr_size_t bytes_written;
1803         apr_status_t rv;
1804         int i;
1805         ct_sct_data *sct_elts;
1806         X509 **x509elts;
1807         server_rec *s = c->base_server;
1808
1809         /* Any error in this function is a file I/O error;
1810          * if such an error occurs, the audit file will be closed
1811          * and removed, and this child won't be able to queue
1812          * anything for audit.  (It is likely that other child
1813          * processes will have the same problem.)
1814          */
1815
1816         ctutil_thread_mutex_lock(audit_file_mutex);
1817
1818         if (audit_file) { /* no error just occurred... */
1819             audit_file_nonempty = 1;
1820
1821             rv = ctutil_file_write_uint16(s, audit_file,
1822                                           SERVER_START);
1823
1824             if (rv == APR_SUCCESS) {
1825                 rv = ctutil_file_write_uint16(s, audit_file, KEY_START);
1826             }
1827
1828             if (rv == APR_SUCCESS) {
1829                 ap_assert(strlen(key) <= USHRT_MAX);
1830                 rv = ctutil_file_write_uint16(s, audit_file,
1831                                               (apr_uint16_t)strlen(key));
1832             }
1833
1834             if (rv == APR_SUCCESS) {
1835                 rv = apr_file_write_full(audit_file, key, strlen(key),
1836                                          &bytes_written);
1837             }
1838
1839             /* Write each certificate, starting with leaf */
1840             x509elts = (X509 **)cc->cert_arr->elts;
1841             for (i = 0; rv == APR_SUCCESS && i < cc->cert_arr->nelts; i++) {
1842                 unsigned char *der_buf = NULL;
1843                 int der_length;
1844
1845                 rv = ctutil_file_write_uint16(s, audit_file, CERT_START);
1846
1847                 /* now write the cert!!! */
1848
1849                 if (rv == APR_SUCCESS) {
1850                     der_length = i2d_X509(x509elts[i], &der_buf);
1851                     ap_assert(der_length > 0);
1852
1853                     rv = ctutil_file_write_uint24(s, audit_file, der_length);
1854                 }
1855
1856                 if (rv == APR_SUCCESS) {
1857                     rv = apr_file_write_full(audit_file, der_buf, der_length,
1858                                              &bytes_written);
1859                 }
1860
1861                 OPENSSL_free(der_buf);
1862             }
1863
1864             /* Write each SCT */
1865             sct_elts = (ct_sct_data *)conncfg->all_scts->elts;
1866             for (i = 0; rv == APR_SUCCESS && i < conncfg->all_scts->nelts; i++) {
1867                 ct_sct_data sct;
1868
1869                 rv = ctutil_file_write_uint16(s, audit_file, SCT_START);
1870
1871                 sct = sct_elts[i];
1872
1873                 if (rv == APR_SUCCESS) {
1874                     rv = ctutil_file_write_uint16(s, audit_file, sct.len);
1875                 }
1876
1877                 if (rv == APR_SUCCESS) {
1878                     rv = apr_file_write_full(audit_file, sct.data, sct.len,
1879                                              &bytes_written);
1880                 }
1881             }
1882
1883             if (rv != APR_SUCCESS) {
1884                 /* an I/O error occurred; file is not usable */
1885                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1886                              "Failed to write to %s, disabling audit for this "
1887                              "child", audit_fn_active);
1888                 apr_file_close(audit_file);
1889                 audit_file = NULL;
1890                 apr_file_remove(audit_fn_active,
1891                                 /* not used in current implementations */
1892                                 c->pool);
1893             }
1894         }
1895
1896         ctutil_thread_mutex_unlock(audit_file_mutex);
1897     }
1898 }
1899
1900 /* signed_certificate_timestamp */
1901 static const unsigned short CT_EXTENSION_TYPE = 18;
1902
1903 /* See function of this name in openssl/apps/s_client.c */
1904 static int ocsp_resp_cb(SSL *ssl, void *arg)
1905 {
1906     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
1907     ct_conn_config *conncfg = get_conn_config(c);
1908     const unsigned char *p;
1909     int i, len;
1910     OCSP_RESPONSE *rsp;
1911     OCSP_BASICRESP *br;
1912     OCSP_RESPDATA *rd;
1913     OCSP_SINGLERESP *single;
1914     STACK_OF(X509_EXTENSION) *exts;
1915
1916     len = SSL_get_tlsext_status_ocsp_resp(ssl, &p); /* UNDOC */
1917     if (!p) {
1918         /* normal case */
1919         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
1920                       "OCSP response callback called but no stapled response from server");
1921         return 1;
1922     }
1923
1924     rsp = d2i_OCSP_RESPONSE(NULL, &p, len); /* UNDOC */
1925     if (!rsp) {
1926         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
1927                       "Error parsing OCSP response");
1928         return 0;
1929     }
1930
1931     br = OCSP_response_get1_basic(rsp); /* UNDOC */
1932     if (!br) {
1933         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
1934                       "no OCSP basic response");
1935         return 0;
1936     }
1937
1938     rd = br->tbsResponseData;
1939
1940     for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { /* UNDOC */
1941         X509_EXTENSION *ext;
1942         int idx;
1943         ASN1_OCTET_STRING *oct;
1944
1945         single = sk_OCSP_SINGLERESP_value(rd->responses, i); /* UNDOC */
1946         if (!single) {
1947             continue;
1948         }
1949
1950         idx = OCSP_SINGLERESP_get_ext_by_NID(single,
1951                                              NID_ct_cert_scts, -1); /* UNDOC */
1952
1953         if (idx == -1) {
1954             continue;
1955         }
1956
1957         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
1958                       "index of NID_ct_cert_scts: %d", idx);
1959
1960         exts = single->singleExtensions;
1961
1962         ext = sk_X509_EXTENSION_value(exts, idx); /* UNDOC */
1963         oct = X509_EXTENSION_get_data(ext); /* UNDOC */
1964
1965         conncfg->ocsp_has_sct_list = 1;
1966         conncfg->peer_ct_aware = 1;
1967         conncfg->ocsp_sct_list_size = oct->length - 2;
1968         conncfg->ocsp_sct_list = apr_pmemdup(c->pool, oct->data + 2,
1969                                              conncfg->ocsp_sct_list_size);
1970     }
1971
1972     OCSP_RESPONSE_free(rsp); /* UNDOC */
1973
1974     return 1;
1975 }
1976
1977 /* Callbacks and structures for handling custom TLS Extensions:
1978  *   cli_ext_first_cb  - sends data for ClientHello TLS Extension
1979  *   cli_ext_second_cb - receives data from ServerHello TLS Extension
1980  */
1981 static int client_extension_callback_1(SSL *ssl, unsigned short ext_type,
1982                                        const unsigned char **out,
1983                                        unsigned short *outlen, int *al,
1984                                        void *arg)
1985 {
1986     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
1987
1988     /* nothing to send in ClientHello */
1989
1990     ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
1991                   "client_extension_callback_1 called, "
1992                   "ext %hu will be in ClientHello",
1993                   ext_type);
1994
1995     return 1;
1996 }
1997
1998 /* Get SCT(s) from ServerHello */
1999 static int client_extension_callback_2(SSL *ssl, unsigned short ext_type,
2000                                        const unsigned char *in, unsigned short inlen,
2001                                        int *al, void *arg)
2002 {
2003     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
2004     ct_conn_config *conncfg = get_conn_config(c);
2005
2006     ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
2007                   "client_extension_callback_2 called, "
2008                   "ext %hu was in ServerHello (len %hu)",
2009                   ext_type, inlen);
2010
2011     /* Note: Peer certificate is not available in this callback via
2012      *       SSL_get_peer_certificate(ssl)
2013      */
2014
2015     conncfg->serverhello_has_sct_list = 1;
2016     conncfg->peer_ct_aware = 1;
2017     conncfg->serverhello_sct_list = apr_pmemdup(c->pool, in, inlen);
2018     conncfg->serverhello_sct_list_size = inlen;
2019     return 1;
2020 }
2021
2022 /* See SSLClient::VerifyCallback() in c-t/src/client/ssl_client.cc
2023  * (That's a beast and hard to duplicate in depth when you consider
2024  * all the support classes it relies on; mod_ssl_ct needs to be a
2025  * C++ module so that the bugs are fixed in one place.)
2026  *
2027  * . This code should care about stapled SCTs but doesn't.
2028  * . This code, unlike SSLClient::VerifyCallback(), doesn't look
2029  *   at the OpenSSL "input" chain.
2030  */
2031 static int ssl_ct_ssl_proxy_verify(server_rec *s, conn_rec *c,
2032                                    STACK_OF(X509) *chain)
2033 {
2034     apr_pool_t *p = c->pool;
2035     ct_conn_config *conncfg = get_conn_config(c);
2036     ct_server_config *sconf = ap_get_module_config(s->module_config,
2037                                                    &ssl_ct_module);
2038     int chain_size = sk_X509_num(chain);
2039     int extension_index;
2040     cert_chain *certs;
2041
2042     if (sconf->proxy_awareness == PROXY_OBLIVIOUS) {
2043         return OK;
2044     }
2045
2046     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
2047                   "ssl_ct_ssl_proxy_verify() - get server certificate info");
2048
2049     if (chain_size < 1) {
2050         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
2051                       "odd chain size %d -- cannot proceed", chain_size);
2052         return APR_EINVAL;
2053     }
2054
2055     /* Note: SSLClient::Verify looks in both the input chain and the
2056      *       verified chain.
2057      */
2058
2059     certs = cert_chain_init(p, chain);
2060     conncfg->certs = certs;
2061
2062     extension_index = 
2063         X509_get_ext_by_NID(certs->leaf,
2064                             NID_ct_precert_scts,
2065                             -1);
2066     /* use X509_get_ext(certs->leaf, extension_index) to obtain X509_EXTENSION * */
2067
2068     if (extension_index >= 0) {
2069         void *ext_struct;
2070
2071         server_cert_has_sct_list(c);
2072         /* as in Cert::ExtensionStructure() */
2073         ext_struct = X509_get_ext_d2i(certs->leaf,
2074                                       NID_ct_precert_scts,
2075                                       NULL, /* ignore criticality of extension */
2076                                       NULL); /* UNDOC */
2077
2078         if (ext_struct == NULL) {
2079             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
2080                           "Could not retrieve SCT list from certificate (unexpected)");
2081         }
2082         else {
2083             /* as in Cert::OctetStringExtensionData */
2084             ASN1_OCTET_STRING *octet = (ASN1_OCTET_STRING *)ext_struct;
2085             conncfg->cert_sct_list = apr_pmemdup(p,
2086                                                  octet->data,
2087                                                  octet->length);
2088             conncfg->cert_sct_list_size = octet->length;
2089             ASN1_OCTET_STRING_free(octet); /* UNDOC */
2090         }
2091     }
2092
2093     return OK;
2094 }
2095
2096 static int ssl_ct_proxy_post_handshake(conn_rec *c, SSL *ssl)
2097 {
2098     apr_pool_t *p = c->pool;
2099     apr_status_t rv = APR_SUCCESS;
2100     const char *key;
2101     ct_cached_server_data *cached;
2102     ct_conn_config *conncfg = get_conn_config(c);
2103     server_rec *s = c->base_server;
2104     ct_server_config *sconf = ap_get_module_config(s->module_config,
2105                                                    &ssl_ct_module);
2106     int validation_error = 0, missing_sct_error = 0;
2107     STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl);
2108
2109     if (sconf->proxy_awareness == PROXY_OBLIVIOUS) {
2110         return OK;
2111     }
2112
2113     ssl_ct_ssl_proxy_verify(s, c, chain);
2114
2115     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
2116                   "finally at the point where we can see where SCTs came from"
2117                   " %pp/%pp/%pp (c %pp)",
2118                   conncfg->cert_sct_list, conncfg->serverhello_sct_list,
2119                   conncfg->ocsp_sct_list, c);
2120
2121     /* At this point we have the SCTs from the cert (if any) and the
2122      * SCTs from the TLS extension (if any) in ct_conn_config.
2123      */
2124
2125     if (conncfg->cert_sct_list || conncfg->serverhello_sct_list
2126         || conncfg->ocsp_sct_list) {
2127
2128         /* The key is critical to avoiding validating and queueing of
2129          * the same stuff over and over.
2130          *
2131          * Is there any cheaper check than server cert and SCTs all exactly
2132          * the same as before?
2133          */
2134         
2135         key = gen_key(c, conncfg->certs, conncfg);
2136
2137         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
2138                       "key for server data: %s", key);
2139
2140         ctutil_thread_mutex_lock(cached_server_data_mutex);
2141
2142         cached = apr_hash_get(cached_server_data, key, APR_HASH_KEY_STRING);
2143
2144         ctutil_thread_mutex_unlock(cached_server_data_mutex);
2145
2146         if (!cached) {
2147             ct_cached_server_data *new_server_data =
2148                 (ct_cached_server_data *)calloc(1, sizeof(ct_cached_server_data));
2149
2150             new_server_data->validation_result = 
2151                 rv = validate_server_data(p, c, conncfg->certs, conncfg, sconf);
2152
2153             if (rv != APR_SUCCESS) {
2154                 validation_error = 1;
2155             }
2156
2157             ctutil_thread_mutex_lock(cached_server_data_mutex);
2158
2159             if ((cached = apr_hash_get(cached_server_data, key, APR_HASH_KEY_STRING))) {
2160                 /* some other thread snuck in
2161                  * we assume that the other thread got the same validation
2162                  * result that we did
2163                  */
2164                 free(new_server_data);
2165                 new_server_data = NULL;
2166             }
2167             else {
2168                 /* no other thread snuck in */
2169                 apr_hash_set(cached_server_data, key, APR_HASH_KEY_STRING,
2170                              new_server_data);
2171                 new_server_data = NULL;
2172             }
2173
2174             ctutil_thread_mutex_unlock(cached_server_data_mutex);
2175
2176             if (rv == APR_SUCCESS && !cached) {
2177                 save_server_data(c, conncfg->certs, conncfg, key);
2178             }
2179         }
2180         else {
2181             /* cached */
2182             rv = cached->validation_result;
2183             if (rv != APR_SUCCESS) {
2184                 validation_error = 1;
2185                 ap_log_cerror(APLOG_MARK, APLOG_INFO, rv, c, "bad cached validation result");
2186             }
2187         }
2188     }
2189     else {
2190         /* No SCTs at all; consult configuration to know what to do. */
2191         missing_sct_error = 1;
2192     }
2193
2194     if (conncfg->certs) {
2195         cert_chain_free(conncfg->certs);
2196         conncfg->certs = NULL;
2197     }
2198
2199     ap_log_cerror(APLOG_MARK,
2200                   rv == APR_SUCCESS ? APLOG_DEBUG : APLOG_ERR, rv, c,
2201                   "SCT list received in: %s%s%s(%s) (c %pp)",
2202                   conncfg->serverhello_has_sct_list ? "ServerHello " : "",
2203                   conncfg->server_cert_has_sct_list ? "certificate-extension " : "",
2204                   conncfg->ocsp_has_sct_list ? "OCSP " : "",
2205                   cached ? "already saved" : "seen for the first time",
2206                   c);
2207
2208     if (sconf->proxy_awareness == PROXY_REQUIRE) {
2209         if (missing_sct_error || validation_error) {
2210             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
2211                           "Forbidding access to backend server; no valid SCTs");
2212             return HTTP_FORBIDDEN;
2213         }
2214     }
2215
2216     return OK;
2217 }
2218
2219 static int server_extension_callback_1(SSL *ssl, unsigned short ext_type,
2220                                        const unsigned char *in,
2221                                        unsigned short inlen, int *al,
2222                                        void *arg)
2223 {
2224     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
2225
2226     /* this callback tells us that client is CT-aware;
2227      * there's nothing of interest in the extension data
2228      */
2229     client_is_ct_aware(c);
2230
2231     ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
2232                   "server_extension_callback_1 called, "
2233                   "ext %hu was in ClientHello (len %hu)",
2234                   ext_type, inlen);
2235
2236     return 1;
2237 }
2238
2239 static int server_extension_callback_2(SSL *ssl, unsigned short ext_type,
2240                                        const unsigned char **out,
2241                                        unsigned short *outlen, int *al,
2242                                        void *arg)
2243 {
2244     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
2245     ct_server_config *sconf = ap_get_module_config(c->base_server->module_config,
2246                                                    &ssl_ct_module);
2247     X509 *server_cert;
2248     const char *fingerprint;
2249     const unsigned char *scts;
2250     apr_size_t scts_len;
2251     apr_status_t rv;
2252
2253     if (!is_client_ct_aware(c)) {
2254         /* Hmmm...  Is this actually called if the client doesn't include
2255          * the extension in the ClientHello?  I don't think so.
2256          */
2257         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
2258                       "server_extension_callback_2: client isn't CT-aware");
2259         /* Skip this extension for ServerHello */
2260         return -1;
2261     }
2262
2263     /* need to reply with SCT */
2264
2265     server_cert = SSL_get_certificate(ssl); /* no need to free! */
2266     fingerprint = get_cert_fingerprint(c->pool, server_cert);
2267
2268     ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
2269                   "server_extension_callback_2 called, "
2270                   "ext %hu will be in ServerHello",
2271                   ext_type);
2272
2273     rv = read_scts(c->pool, fingerprint,
2274                    sconf->sct_storage,
2275                    c->base_server, (char **)&scts, &scts_len);
2276     if (rv == APR_SUCCESS) {
2277         *out = scts;
2278         ap_assert(scts_len <= USHRT_MAX);
2279         *outlen = (unsigned short)scts_len;
2280     }
2281     else {
2282         /* Skip this extension for ServerHello */
2283         return -1;
2284     }
2285
2286     return 1;
2287 }
2288
2289 static void tlsext_cb(SSL *ssl, int client_server, int type,
2290                       unsigned char *data, int len,
2291                       void *arg)
2292 {
2293     conn_rec *c = arg;
2294
2295     if (type == CT_EXTENSION_TYPE) {
2296         ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
2297                       "tlsext_cb called, got CT TLS extension");
2298
2299         client_is_ct_aware(c);
2300     }
2301 }
2302
2303 static int ssl_ct_pre_handshake(conn_rec *c, SSL *ssl)
2304 {
2305     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "client connected (pre-handshake)");
2306
2307     SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp); /* UNDOC */
2308
2309     /* This callback is needed only to determine that the peer is CT-aware
2310      * when resuming a session.  For an initial handshake, the callbacks
2311      * registered via SSL_CTX_set_custom_srv_ext() are sufficient.
2312      */
2313     SSL_set_tlsext_debug_callback(ssl, tlsext_cb); /* UNDOC */
2314     SSL_set_tlsext_debug_arg(ssl, c); /* UNDOC */
2315
2316     return OK;
2317 }
2318
2319 static int ssl_ct_init_server(server_rec *s, apr_pool_t *p, int is_proxy,
2320                               SSL_CTX *ssl_ctx)
2321 {
2322     ct_callback_info *cbi = apr_pcalloc(p, sizeof *cbi);
2323     ct_server_config *sconf = ap_get_module_config(s->module_config,
2324                                                    &ssl_ct_module);
2325
2326     cbi->s = s;
2327
2328     if (is_proxy && sconf->proxy_awareness != PROXY_OBLIVIOUS) {
2329         /* _cli_ = "client" */
2330         if (!SSL_CTX_set_custom_cli_ext(ssl_ctx, CT_EXTENSION_TYPE,
2331                                         client_extension_callback_1,
2332                                         client_extension_callback_2, cbi)) { /* UNDOC */
2333             ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
2334                          "Unable to initalize Certificate Transparency client "
2335                          "extension callbacks (callback for %d already registered?)",
2336                          CT_EXTENSION_TYPE);
2337             return HTTP_INTERNAL_SERVER_ERROR;
2338         }
2339
2340         /* Uhh, hopefully this doesn't collide with anybody else.  mod_ssl
2341          * currently only sets this on the server SSL_CTX, when OCSP is
2342          * enabled.
2343          */
2344         SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb); /* UNDOC */
2345         SSL_CTX_set_tlsext_status_arg(ssl_ctx, cbi); /* UNDOC */
2346     }
2347     else if (!is_proxy) {
2348         look_for_server_certs(s, ssl_ctx, sconf->sct_storage);
2349
2350         /* _srv_ = "server" */
2351         if (!SSL_CTX_set_custom_srv_ext(ssl_ctx, CT_EXTENSION_TYPE,
2352                                         server_extension_callback_1,
2353                                         server_extension_callback_2, cbi)) { /* UNDOC */
2354             ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
2355                          "Unable to initalize Certificate Transparency server "
2356                          "extension callback (callbacks for %d already registered?)",
2357                          CT_EXTENSION_TYPE);
2358             return HTTP_INTERNAL_SERVER_ERROR;
2359         }
2360     }
2361
2362     return OK;
2363 }
2364
2365 static int ssl_ct_post_read_request(request_rec *r)
2366 {
2367     ct_conn_config *conncfg =
2368       ap_get_module_config(r->connection->conn_config, &ssl_ct_module);
2369
2370     if (conncfg && conncfg->peer_ct_aware) {
2371         apr_table_set(r->subprocess_env, STATUS_VAR, STATUS_VAR_AWARE_VAL);
2372     }
2373     else {
2374         apr_table_set(r->subprocess_env, STATUS_VAR, STATUS_VAR_UNAWARE_VAL);
2375     }
2376
2377     return DECLINED;
2378 }
2379
2380 static int ssl_ct_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
2381                              apr_pool_t *ptemp)
2382 {
2383     apr_status_t rv = ap_mutex_register(pconf, SSL_CT_MUTEX_TYPE, NULL,
2384                                         APR_LOCK_DEFAULT, 0);
2385     if (rv != APR_SUCCESS) {
2386         return rv;
2387     }
2388
2389     apr_dbd_init(pconf);
2390
2391     ctutil_run_internal_tests(ptemp);
2392
2393     return OK;
2394 }
2395
2396 static apr_status_t inactivate_audit_file(void *data)
2397 {
2398     apr_status_t rv;
2399     server_rec *s = data;
2400
2401     if (!audit_file) { /* something bad happened after child init */
2402         return APR_SUCCESS;
2403     }
2404
2405     /* the normal cleanup was disabled in the call to apr_file_open */
2406     rv = apr_file_close(audit_file);
2407     audit_file = NULL;
2408     if (rv == APR_SUCCESS) {
2409         if (audit_file_nonempty) {
2410             rv = apr_file_rename(audit_fn_active, audit_fn_perm,
2411                                  /* not used in current implementations */
2412                                  s->process->pool);
2413         }
2414         else {
2415             /* No data written; just remove the file */
2416             apr_file_remove(audit_fn_active,
2417                             /* not used in current implementations */
2418                             s->process->pool);
2419         }
2420     }
2421     if (rv != APR_SUCCESS) {
2422         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
2423                      "error flushing/closing %s or renaming it to %s",
2424                      audit_fn_active, audit_fn_perm);
2425     }
2426
2427     return APR_SUCCESS; /* what, you think anybody cares? */
2428 }
2429
2430 static void ssl_ct_child_init(apr_pool_t *p, server_rec *s)
2431 {
2432     apr_status_t rv;
2433     const char *audit_basename;
2434     ct_server_config *sconf = ap_get_module_config(s->module_config,
2435                                                    &ssl_ct_module);
2436
2437     cached_server_data = apr_hash_make(p);
2438
2439     rv = apr_global_mutex_child_init(&ssl_ct_sct_update,
2440                                      apr_global_mutex_lockfile(ssl_ct_sct_update), p);
2441     if (rv != APR_SUCCESS) {
2442         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
2443                      "could not initialize " SSL_CT_MUTEX_TYPE
2444                      " mutex in child");
2445         /* might crash otherwise due to lack of checking for initialized data
2446          * in all the right places, but this is going to skip pchild cleanup
2447          */
2448         exit(APEXIT_CHILDSICK);
2449     }
2450
2451     rv = apr_thread_rwlock_create(&log_config_rwlock, p);
2452     if (rv != APR_SUCCESS) {
2453         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
2454                      "could not create rwlock in child");
2455         exit(APEXIT_CHILDSICK);
2456     }
2457
2458     rv = apr_thread_create(&service_thread, NULL, run_service_thread, s, p);
2459     if (rv != APR_SUCCESS) {
2460         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
2461                      "could not create " SERVICE_THREAD_NAME " in child");
2462         /* might crash otherwise due to lack of checking for initialized data
2463          * in all the right places, but this is going to skip pchild cleanup
2464          */
2465         exit(APEXIT_CHILDSICK);
2466     }
2467
2468     apr_pool_cleanup_register(p, service_thread, wait_for_thread,
2469                               apr_pool_cleanup_null);
2470
2471     if (sconf->proxy_awareness != PROXY_OBLIVIOUS) {
2472         rv = apr_thread_mutex_create(&cached_server_data_mutex,
2473                                      APR_THREAD_MUTEX_DEFAULT,
2474                                      p);
2475         if (rv != APR_SUCCESS) {
2476             ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
2477                          "could not allocate a thread mutex");
2478             /* might crash otherwise due to lack of checking for initialized data
2479              * in all the right places, but this is going to skip pchild cleanup
2480              */
2481             exit(APEXIT_CHILDSICK);
2482         }
2483     }
2484
2485     if (sconf->proxy_awareness != PROXY_OBLIVIOUS && sconf->audit_storage) {
2486         rv = apr_thread_mutex_create(&audit_file_mutex,
2487                                      APR_THREAD_MUTEX_DEFAULT, p);
2488         if (rv != APR_SUCCESS) {
2489             ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
2490                          "could not allocate a thread mutex");
2491             /* might crash otherwise due to lack of checking for initialized data
2492              * in all the right places, but this is going to skip pchild cleanup
2493              */
2494             exit(APEXIT_CHILDSICK);
2495         }
2496
2497         audit_basename = apr_psprintf(p, "audit_%" APR_PID_T_FMT,
2498                                       getpid());
2499         rv = ctutil_path_join((char **)&audit_fn_perm, sconf->audit_storage,
2500                               audit_basename, p, s);
2501         if (rv != APR_SUCCESS) {
2502             /* might crash otherwise due to lack of checking for initialized data
2503              * in all the right places, but this is going to skip pchild cleanup
2504              */
2505             exit(APEXIT_CHILDSICK);
2506         }
2507
2508         audit_fn_active = apr_pstrcat(p, audit_fn_perm, ".tmp", NULL);
2509         audit_fn_perm = apr_pstrcat(p, audit_fn_perm, ".out", NULL);
2510
2511         if (ctutil_file_exists(p, audit_fn_active)) {
2512             ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
2513                          "ummm, pid-specific file %s was reused before audit grabbed it! (removing)",
2514                          audit_fn_active);
2515             apr_file_remove(audit_fn_active, p);
2516         }
2517
2518         if (ctutil_file_exists(p, audit_fn_perm)) {
2519             ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
2520                          "ummm, pid-specific file %s was reused before audit grabbed it! (removing)",
2521                          audit_fn_perm);
2522             apr_file_remove(audit_fn_perm, p);
2523         }
2524
2525         rv = apr_file_open(&audit_file, audit_fn_active,
2526                            APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE
2527                            |APR_FOPEN_BINARY|APR_FOPEN_BUFFERED|APR_FOPEN_NOCLEANUP,
2528                            APR_FPROT_OS_DEFAULT, p);
2529         if (rv != APR_SUCCESS) {
2530             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
2531                          "can't create %s", audit_fn_active);
2532             audit_file = NULL;
2533         }
2534
2535         if (audit_file) {
2536             apr_pool_cleanup_register(p, s, inactivate_audit_file, apr_pool_cleanup_null);
2537         }
2538     } /* !PROXY_OBLIVIOUS */
2539 }
2540
2541 static void *create_ct_server_config(apr_pool_t *p, server_rec *s)
2542 {
2543     ct_server_config *conf =
2544         (ct_server_config *)apr_pcalloc(p, sizeof(ct_server_config));
2545
2546     conf->max_sct_age = apr_time_from_sec(3600 * 24);
2547     conf->proxy_awareness = PROXY_AWARENESS_UNSET;
2548     conf->max_sh_sct = 100;
2549     conf->static_cert_sct_dirs = apr_hash_make(p);
2550     
2551     return conf;
2552 }
2553
2554 static void *merge_ct_server_config(apr_pool_t *p, void *basev, void *virtv)
2555 {
2556     ct_server_config *base = (ct_server_config *)basev;
2557     ct_server_config *virt = (ct_server_config *)virtv;
2558     ct_server_config *conf;
2559
2560     conf = (ct_server_config *)apr_pmemdup(p, virt, sizeof(ct_server_config));
2561
2562     conf->sct_storage = base->sct_storage;
2563     conf->audit_storage = base->audit_storage;
2564     conf->ct_exe = base->ct_exe;
2565     conf->max_sct_age = base->max_sct_age;
2566     conf->log_config_fname = base->log_config_fname;
2567     conf->db_log_config = base->db_log_config;
2568     conf->static_log_config = base->static_log_config;
2569     conf->max_sh_sct = base->max_sh_sct;
2570     conf->static_cert_sct_dirs = base->static_cert_sct_dirs;
2571
2572     conf->proxy_awareness = (virt->proxy_awareness != PROXY_AWARENESS_UNSET)
2573         ? virt->proxy_awareness
2574         : base->proxy_awareness;
2575
2576     return conf;
2577 }
2578
2579 static int ssl_ct_detach_backend(request_rec *r,
2580                                  proxy_conn_rec *backend)
2581 {
2582     conn_rec *origin = backend->connection;
2583
2584     if (origin) {
2585         ct_conn_config *conncfg = get_conn_config(origin);
2586         char *list, *last;
2587
2588         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
2589                       "ssl_ct_detach_backend, %d%d%d",
2590                       conncfg->server_cert_has_sct_list,
2591                       conncfg->serverhello_has_sct_list,
2592                       conncfg->ocsp_has_sct_list);
2593
2594         apr_table_set(r->subprocess_env, STATUS_VAR,
2595                       conncfg->peer_ct_aware ? STATUS_VAR_AWARE_VAL : STATUS_VAR_UNAWARE_VAL);
2596
2597         list = apr_pstrcat(r->pool,
2598                            conncfg->server_cert_has_sct_list ? "certext," : "",
2599                            conncfg->serverhello_has_sct_list ? "tlsext," : "",
2600                            conncfg->ocsp_has_sct_list ? "ocsp" : "",
2601                            NULL);
2602         if (*list) {
2603             last = list + strlen(list) - 1;
2604             if (*last == ',') {
2605                 *last = '\0';
2606             }
2607         }
2608
2609         apr_table_set(r->subprocess_env, PROXY_SCT_SOURCES_VAR, list);
2610     }
2611     else {
2612         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
2613                       "No backend connection available in "
2614                       "ssl_ct_detach_backend(); assuming peer unaware");
2615         apr_table_set(r->subprocess_env, STATUS_VAR,
2616                       STATUS_VAR_UNAWARE_VAL);
2617     }
2618
2619     return OK;
2620 }
2621
2622 static void ct_register_hooks(apr_pool_t *p)
2623 {
2624     static const char * const run_after_mod_ssl[] = {"mod_ssl.c", NULL};
2625
2626     ap_hook_pre_config(ssl_ct_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
2627     ap_hook_check_config(ssl_ct_check_config, NULL, NULL, APR_HOOK_MIDDLE);
2628     ap_hook_post_config(ssl_ct_post_config, run_after_mod_ssl, NULL,
2629                         APR_HOOK_MIDDLE);
2630     ap_hook_post_read_request(ssl_ct_post_read_request, NULL, NULL, APR_HOOK_MIDDLE);
2631     ap_hook_child_init(ssl_ct_child_init, NULL, NULL, APR_HOOK_MIDDLE);
2632     APR_OPTIONAL_HOOK(proxy, detach_backend, ssl_ct_detach_backend, NULL, NULL,
2633                       APR_HOOK_MIDDLE);
2634     APR_OPTIONAL_HOOK(ssl, init_server, ssl_ct_init_server, NULL, NULL,
2635                       APR_HOOK_MIDDLE);
2636     APR_OPTIONAL_HOOK(ssl, pre_handshake,
2637                       ssl_ct_pre_handshake,
2638                       NULL, NULL, APR_HOOK_MIDDLE);
2639     APR_OPTIONAL_HOOK(ssl, proxy_post_handshake, ssl_ct_proxy_post_handshake,
2640                       NULL, NULL, APR_HOOK_MIDDLE);
2641 }
2642
2643 static const char *parse_num(apr_pool_t *p,
2644                              const char *arg, long min_val,
2645                              long max_val, long *val,
2646                              const char *cmd_name)
2647 {
2648     char *endptr;
2649
2650     errno = 0;
2651     *val = strtol(arg, &endptr, 10);
2652     if (errno != 0
2653         || *endptr != '\0'
2654         || *val < min_val
2655         || *val > max_val) {
2656         return apr_psprintf(p, "%s must be between %ld "
2657                             "and %ld (was '%s')", cmd_name, min_val,
2658                             max_val, arg);
2659     }
2660
2661     return NULL;
2662 }
2663                              
2664 static const char *ct_audit_storage(cmd_parms *cmd, void *x, const char *arg)
2665 {
2666     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2667                                                    &ssl_ct_module);
2668     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2669
2670     if (err) {
2671         return err;
2672     }
2673
2674     sconf->audit_storage = ap_runtime_dir_relative(cmd->pool, arg);
2675
2676     if (!ctutil_dir_exists(cmd->pool, sconf->audit_storage)) {
2677         return apr_pstrcat(cmd->pool, "CTAuditStorage: Directory ",
2678                            sconf->audit_storage,
2679                            " does not exist", NULL);
2680     }
2681
2682     return NULL;
2683 }
2684
2685 static const char *ct_log_config_db(cmd_parms *cmd, void *x, const char *arg)
2686 {
2687     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2688                                                    &ssl_ct_module);
2689     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2690
2691     if (err) {
2692         return err;
2693     }
2694
2695     sconf->log_config_fname = ap_server_root_relative(cmd->pool, arg);
2696
2697     return NULL;
2698 }
2699
2700 static const char *ct_max_sct_age(cmd_parms *cmd, void *x, const char *arg)
2701 {
2702     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2703                                                    &ssl_ct_module);
2704     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2705     long val;
2706
2707     if (err) {
2708         return err;
2709     }
2710
2711     err = parse_num(cmd->pool, arg, 10, 3600 * 12, &val, "CTMaxSCTAge");
2712     if (err) {
2713         return err;
2714     }
2715
2716     sconf->max_sct_age = apr_time_from_sec(val);
2717     return NULL;
2718 }    
2719
2720 static const char *ct_proxy_awareness(cmd_parms *cmd, void *x, const char *arg)
2721 {
2722     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2723                                                    &ssl_ct_module);
2724
2725     if (!strcasecmp(arg, "oblivious")) {
2726         sconf->proxy_awareness = PROXY_OBLIVIOUS;
2727     }
2728     else if (!strcasecmp(arg, "aware")) {
2729         sconf->proxy_awareness = PROXY_AWARE;
2730     }
2731     else if (!strcasecmp(arg, "require")) {
2732         sconf->proxy_awareness = PROXY_REQUIRE;
2733     }
2734     else {
2735         return apr_pstrcat(cmd->pool, "CTProxyAwareness: Invalid argument \"",
2736                            arg, "\"", NULL);
2737     }
2738
2739     return NULL;
2740 }
2741
2742 static const char *ct_sct_storage(cmd_parms *cmd, void *x, const char *arg)
2743 {
2744     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2745                                                    &ssl_ct_module);
2746     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2747
2748     if (err) {
2749         return err;
2750     }
2751
2752     sconf->sct_storage = ap_runtime_dir_relative(cmd->pool, arg);
2753
2754     if (!ctutil_dir_exists(cmd->pool, sconf->sct_storage)) {
2755         return apr_pstrcat(cmd->pool, "CTSCTStorage: Directory ",
2756                            sconf->sct_storage,
2757                            " does not exist", NULL);
2758     }
2759
2760     return NULL;
2761 }
2762
2763 static const char *ct_sct_limit(cmd_parms *cmd, void *x, const char *arg)
2764 {
2765     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2766                                                    &ssl_ct_module);
2767     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2768     long val;
2769
2770     if (err) {
2771         return err;
2772     }
2773
2774     err = parse_num(cmd->pool, arg, 1, 100, &val,
2775                     "CTServerHelloSCTLimit");
2776     if (err) {
2777         return err;
2778     }
2779
2780     sconf->max_sh_sct = val;
2781     return NULL;
2782 }
2783
2784 static const char *ct_static_log_config(cmd_parms *cmd, void *x, int argc,
2785                                         char *const argv[])
2786 {
2787     apr_status_t rv;
2788     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2789     const char *log_id, *public_key, *distrusted, *min_valid_time,
2790         *max_valid_time, *url;
2791     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2792                                                    &ssl_ct_module);
2793     int cur_arg;
2794
2795     if (err) {
2796         return err;
2797     }
2798
2799     if (argc != 6) {
2800         return "CTStaticLogConfig: 6 arguments are required";
2801     }
2802
2803     cur_arg = 0;
2804     log_id = argv[cur_arg++];
2805     if (!strcmp(log_id, "-")) {
2806         log_id = NULL;
2807     }
2808
2809     public_key = argv[cur_arg++];
2810     if (!strcmp(public_key, "-")) {
2811         public_key = NULL;
2812     }
2813     else {
2814         public_key = ap_server_root_relative(cmd->pool, public_key);
2815     }
2816
2817     distrusted = argv[cur_arg++];
2818     if (!strcmp(distrusted, "-")) {
2819         distrusted = NULL;
2820     }
2821
2822     min_valid_time = argv[cur_arg++];
2823     if (!strcmp(min_valid_time, "-")) {
2824         min_valid_time = NULL;
2825     }
2826
2827     max_valid_time = argv[cur_arg++];
2828     if (!strcmp(max_valid_time, "-")) {
2829         max_valid_time = NULL;
2830     }
2831
2832     url = argv[cur_arg++];
2833     if (!strcmp(url, "-")) {
2834         url = NULL;
2835     }
2836
2837     if (!sconf->static_log_config) {
2838         sconf->static_log_config =
2839             apr_array_make(cmd->pool, 2, sizeof(ct_log_config *));
2840     }
2841     rv = save_log_config_entry(sconf->static_log_config, cmd->pool,
2842                                log_id, public_key, distrusted, 
2843                                min_valid_time, max_valid_time, url);
2844     if (rv != APR_SUCCESS) {
2845         return "Error processing static log configuration";
2846     }
2847
2848     return NULL;
2849 }
2850
2851 static const char *ct_static_scts(cmd_parms *cmd, void *x, const char *cert_fn,
2852                                   const char *sct_dn)
2853 {
2854     apr_pool_t *p = cmd->pool;
2855     apr_status_t rv;
2856     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2857                                                    &ssl_ct_module);
2858     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2859     const char *fingerprint;
2860     FILE *pemfile;
2861     X509 *cert;
2862
2863     if (err) {
2864         return err;
2865     }
2866
2867     cert_fn = ap_server_root_relative(cmd->pool, cert_fn);
2868     sct_dn = ap_server_root_relative(cmd->pool, sct_dn);
2869
2870     rv = ctutil_fopen(cert_fn, "r", &pemfile);
2871     if (rv != APR_SUCCESS) {
2872         return apr_psprintf(p, "could not open certificate file %s (%pm)",
2873                             cert_fn, &rv);
2874     }
2875     
2876     cert = PEM_read_X509(pemfile, NULL, NULL, NULL);
2877     if (!cert) {
2878         return apr_psprintf(p, "could not read certificate from file %s",
2879                             cert_fn);
2880     }
2881
2882     fclose(pemfile);
2883
2884     fingerprint = get_cert_fingerprint(cmd->pool, cert);
2885     X509_free(cert);
2886
2887     if (!ctutil_dir_exists(p, sct_dn)) {
2888         return apr_pstrcat(p, "CTStaticSCTs: Directory ", sct_dn,
2889                            " does not exist", NULL);
2890     }
2891
2892     apr_hash_set(sconf->static_cert_sct_dirs, fingerprint,
2893                  APR_HASH_KEY_STRING, sct_dn);
2894
2895     return NULL;
2896 }
2897
2898 static const char *ct_log_client(cmd_parms *cmd, void *x, const char *arg)
2899 {
2900     ct_server_config *sconf = ap_get_module_config(cmd->server->module_config,
2901                                                    &ssl_ct_module);
2902     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2903
2904     if (err) {
2905         return err;
2906     }
2907
2908     if (strcmp(DOTEXE, "")) {
2909         if (!ctutil_file_exists(cmd->pool, arg)) {
2910             arg = apr_pstrcat(cmd->pool, arg, DOTEXE, NULL);
2911         }
2912     }
2913
2914     if (!ctutil_file_exists(cmd->pool, arg)) {
2915         return apr_pstrcat(cmd->pool,
2916                            "CTLogClient: File ",
2917                            arg,
2918                            " does not exist",
2919                            NULL);
2920     }
2921
2922     sconf->ct_exe = arg;
2923
2924     return NULL;
2925 }
2926
2927 static const command_rec ct_cmds[] =
2928 {
2929     AP_INIT_TAKE1("CTAuditStorage", ct_audit_storage, NULL,
2930                   RSRC_CONF, /* GLOBAL_ONLY - audit data spans servers */
2931                   "Location to store files of audit data"),
2932     AP_INIT_TAKE1("CTLogConfigDB", ct_log_config_db, NULL,
2933                   RSRC_CONF, /* GLOBAL_ONLY - otherwise, you couldn't share
2934                               * the same SCT list for a cert used by two
2935                               * different vhosts (and the SCT maintenance daemon
2936                               * would be more complex)
2937                               */
2938                   "Log configuration database"),
2939     AP_INIT_TAKE1("CTMaxSCTAge", ct_max_sct_age, NULL,
2940                   RSRC_CONF, /* GLOBAL_ONLY - otherwise, you couldn't share
2941                               * the same SCT list for a cert used by two
2942                               * different vhosts
2943                               */
2944                   "Max age of SCT obtained from log before refresh"),
2945     AP_INIT_TAKE1("CTProxyAwareness", ct_proxy_awareness, NULL,
2946                   RSRC_CONF, /* per-server */
2947                   "\"oblivious\" to neither ask for nor check SCTs, "
2948                   "\"aware\" to ask for and process SCTs but allow all connections, "
2949                   "or \"require\" to abort backend connections if an acceptable "
2950                   "SCT is not provided"),
2951     AP_INIT_TAKE1("CTServerHelloSCTLimit", ct_sct_limit, NULL,
2952                   RSRC_CONF, /* GLOBAL_ONLY - otherwise, you couldn't share
2953                               * the same SCT list for a cert used by two
2954                               * different vhosts
2955                               */
2956                   "Limit on number of SCTs sent in ServerHello"),
2957     AP_INIT_TAKE1("CTSCTStorage", ct_sct_storage, NULL,
2958                   RSRC_CONF, /* GLOBAL_ONLY - otherwise, you couldn't share
2959                               * the same SCT list for a cert used by two
2960                               * different vhosts (and the SCT maintenance daemon
2961                               * would be more complex)
2962                               */
2963                   "Location to store SCTs obtained from logs"),
2964     AP_INIT_TAKE_ARGV("CTStaticLogConfig", ct_static_log_config, NULL,
2965                       RSRC_CONF, /* GLOBAL_ONLY */
2966                       "Static log configuration record"),
2967     AP_INIT_TAKE2("CTStaticSCTs", ct_static_scts, NULL,
2968                   RSRC_CONF, /* GLOBAL_ONLY  - otherwise, you couldn't share
2969                               * the same SCT list for a cert used by two
2970                               * different vhosts (and the SCT maintenance daemon
2971                               * would be more complex)
2972                               */
2973                   "Point to directory with static SCTs corresponding to the "
2974                   "specified certificate"),
2975     AP_INIT_TAKE1("CTLogClient", ct_log_client, NULL,
2976                   RSRC_CONF, /* GLOBAL_ONLY - otherwise, you couldn't share
2977                               * the same SCTs for a cert used by two
2978                               * different vhosts (and it would be just plain
2979                               * silly :) )
2980                               */
2981                   "Location of certificate-transparency.org (or compatible) log client tool"),
2982     {NULL}
2983 };
2984
2985 AP_DECLARE_MODULE(ssl_ct) =
2986 {
2987     STANDARD20_MODULE_STUFF,
2988     NULL,
2989     NULL,
2990     create_ct_server_config,
2991     merge_ct_server_config,
2992     ct_cmds,
2993     ct_register_hooks,
2994 };