Since I just added ticket support to libtls here is a diff to enable it
in httpd.
Cheers
--
:wq Claudio
Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/config.c,v
retrieving revision 1.50
diff -u -p -r1.50 config.c
--- config.c 6 Nov 2016 10:49:38 -0000 1.50
+++ config.c 22 Jan 2017 02:02:03 -0000
@@ -146,6 +146,7 @@ config_getcfg(struct httpd *env, struct
memcpy(&cf, imsg->data, sizeof(cf));
env->sc_opts = cf.cf_opts;
env->sc_flags = cf.cf_flags;
+ memcpy(env->sc_tls_sid, cf.cf_tls_sid, sizeof(env->sc_tls_sid));
what = ps->ps_what[privsep_process];
Index: httpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.c,v
retrieving revision 1.63
diff -u -p -r1.63 httpd.c
--- httpd.c 9 Jan 2017 14:49:22 -0000 1.63
+++ httpd.c 23 Jan 2017 04:18:44 -0000
@@ -57,6 +57,7 @@ int parent_dispatch_server(int, struct
struct imsg *);
int parent_dispatch_logger(int, struct privsep_proc *,
struct imsg *);
+void parent_tls_ticket_rekey(int, short, void *);
struct httpd *httpd_env;
@@ -253,6 +254,11 @@ main(int argc, char *argv[])
exit(0);
}
+ /* rekey the TLS tickets before pushing the config */
+ parent_tls_ticket_rekey(0, 0, env);
+ /* initialize the TLS session id to a random key for all procs */
+ arc4random_buf(env->sc_tls_sid, sizeof(env->sc_tls_sid));
+
if (parent_configure(env) == -1)
fatalx("configuration failed");
@@ -307,6 +313,7 @@ parent_configure(struct httpd *env)
continue;
cf.cf_opts = env->sc_opts;
cf.cf_flags = env->sc_flags;
+ memcpy(cf.cf_tls_sid, env->sc_tls_sid, sizeof(cf.cf_tls_sid));
proc_compose(env->sc_ps, id, IMSG_CFG_DONE, &cf, sizeof(cf));
}
@@ -450,6 +457,26 @@ parent_dispatch_logger(int fd, struct pr
}
return (0);
+}
+
+void
+parent_tls_ticket_rekey(int fd, short events, void *arg)
+{
+ static struct event rekeyev;
+ struct httpd *env = arg;
+ struct timeval tv;
+ struct httpd_tls_ticket key;
+
+ key.tt_keyrev = arc4random();
+ arc4random_buf(key.tt_key, sizeof(key.tt_key));
+
+ proc_compose_imsg(env->sc_ps, PROC_SERVER, -1, IMSG_TLSTICKET_REKEY,
+ -1, -1, &key, sizeof(key));
+
+ evtimer_set(&rekeyev, parent_tls_ticket_rekey, env);
+ timerclear(&tv);
+ tv.tv_sec = SERVER_TLS_LIFE_TIME / 4;
+ evtimer_add(&rekeyev, &tv);
}
/*
Index: httpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.76
diff -u -p -r1.76 httpd.conf.5
--- httpd.conf.5 14 Nov 2016 10:28:31 -0000 1.76
+++ httpd.conf.5 24 Jan 2017 01:52:34 -0000
@@ -556,6 +556,8 @@ will be used (secure protocols; TLSv1.2-
Refer to the
.Xr tls_config_parse_protocols 3
function for other valid protocol string values.
+.It Oo Ic no Oc Ic tickets
+Enable or disable TLS session tickets.
.El
.El
.Sh TYPES
Index: httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.125
diff -u -p -r1.125 httpd.h
--- httpd.h 9 Jan 2017 14:49:22 -0000 1.125
+++ httpd.h 23 Jan 2017 04:17:52 -0000
@@ -73,6 +73,8 @@
#define SERVER_MAX_PREFETCH 256
#define SERVER_MIN_PREFETCHED 32
#define SERVER_HSTS_DEFAULT_AGE 31536000
+//#define SERVER_TLS_LIFE_TIME (4 * 3600)
+#define SERVER_TLS_LIFE_TIME (4 * 60)
#define MEDIATYPE_NAMEMAX 128 /* file name extension */
#define MEDIATYPE_TYPEMAX 64 /* length of type/subtype */
@@ -105,6 +107,7 @@ enum httpchunk {
struct ctl_flags {
uint8_t cf_opts;
uint32_t cf_flags;
+ uint8_t cf_tls_sid[TLS_MAX_SESSION_ID_LENGTH];
};
enum key_type {
@@ -215,7 +218,8 @@ enum imsg_type {
IMSG_CFG_DONE,
IMSG_LOG_ACCESS,
IMSG_LOG_ERROR,
- IMSG_LOG_OPEN
+ IMSG_LOG_OPEN,
+ IMSG_TLSTICKET_REKEY
};
enum privsep_procid {
@@ -452,6 +456,7 @@ struct server_config {
uint8_t *tls_ocsp_staple;
size_t tls_ocsp_staple_len;
char *tls_ocsp_staple_file;
+ int tls_ticket_enabled;
uint32_t flags;
int strip;
@@ -504,6 +509,11 @@ struct server {
};
TAILQ_HEAD(serverlist, server);
+struct httpd_tls_ticket {
+ uint32_t tt_keyrev;
+ unsigned char tt_key[TLS_TICKET_KEY_SIZE];
+};
+
struct httpd {
uint8_t sc_opts;
uint32_t sc_flags;
@@ -514,6 +524,9 @@ struct httpd {
int sc_paused;
char *sc_chroot;
char *sc_logdir;
+
+ uint8_t sc_tls_sid[TLS_MAX_SESSION_ID_LENGTH];
+ struct httpd_tls_ticket sc_tls_ticket;
struct serverlist *sc_servers;
struct mediatypes *sc_mediatypes;
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.87
diff -u -p -r1.87 parse.y
--- parse.y 5 Jan 2017 13:53:09 -0000 1.87
+++ parse.y 22 Jan 2017 01:50:53 -0000
@@ -132,8 +132,8 @@ typedef struct {
%token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON
%token COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LISTEN
%token LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK
-%token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP
TIMEOUT
-%token TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
+%token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET
+%token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS
%token <v.string> STRING
%token <v.number> NUMBER
@@ -760,6 +760,12 @@ tlsopts : CERTIFICATE STRING {
}
free($2);
}
+ | TICKET {
+ srv_conf->tls_ticket_enabled = 1;
+ }
+ | NO TICKET {
+ srv_conf->tls_ticket_enabled = 0;
+ }
;
root : ROOT rootflags
@@ -1240,6 +1246,7 @@ lookup(char *s)
{ "subdomains", SUBDOMAINS },
{ "syslog", SYSLOG },
{ "tcp", TCP },
+ { "ticket", TICKET },
{ "timeout", TIMEOUT },
{ "tls", TLS },
{ "type", TYPE },
Index: server.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server.c,v
retrieving revision 1.101
diff -u -p -r1.101 server.c
--- server.c 9 Jan 2017 14:49:22 -0000 1.101
+++ server.c 23 Jan 2017 07:17:38 -0000
@@ -281,6 +281,24 @@ server_tls_init(struct server *srv)
}
}
+ /* set common session ID among all processes */
+ if (tls_config_set_session_id(srv->srv_tls_config,
+ httpd_env->sc_tls_sid, sizeof(httpd_env->sc_tls_sid)) == -1) {
+ log_warnx("%s: could not set the TLS session ID: %s",
+ __func__, tls_config_error(srv->srv_tls_config));
+ return (-1);
+ }
+
+ /* ticket support */
+ if (srv->srv_conf.tls_ticket_enabled) {
+ tls_config_set_session_lifetime(srv->srv_tls_config,
+ SERVER_TLS_LIFE_TIME);
+ tls_config_add_ticket_key(srv->srv_tls_config,
+ httpd_env->sc_tls_ticket.tt_keyrev,
+ httpd_env->sc_tls_ticket.tt_key,
+ sizeof(httpd_env->sc_tls_ticket.tt_key));
+ }
+
if (tls_configure(srv->srv_tls_ctx, srv->srv_tls_config) != 0) {
log_warnx("%s: failed to configure tls - %s", __func__,
tls_error(srv->srv_tls_ctx));
@@ -1239,6 +1257,8 @@ server_close(struct client *clt, const c
int
server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
{
+ struct server *srv;
+
switch (imsg->hdr.type) {
case IMSG_CFG_MEDIA:
config_getmedia(httpd_env, imsg);
@@ -1260,6 +1280,21 @@ server_dispatch_parent(int fd, struct pr
break;
case IMSG_CTL_RESET:
config_getreset(httpd_env, imsg);
+ break;
+ case IMSG_TLSTICKET_REKEY:
+ IMSG_SIZE_CHECK(imsg, (&httpd_env->sc_tls_ticket));
+ memcpy(&httpd_env->sc_tls_ticket, imsg->data,
+ sizeof(httpd_env->sc_tls_ticket));
+ /* apply to servers using tickets */
+ TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) {
+ if (srv->srv_tls_config == NULL ||
+ !srv->srv_conf.tls_ticket_enabled)
+ continue;
+ tls_config_add_ticket_key(srv->srv_tls_config,
+ httpd_env->sc_tls_ticket.tt_keyrev,
+ httpd_env->sc_tls_ticket.tt_key,
+ sizeof(httpd_env->sc_tls_ticket.tt_key));
+ }
break;
default:
return (-1);