summaryrefslogtreecommitdiffstats
path: root/usr.sbin/httpd/server.c
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2017-03-25 17:25:34 +0000
committerclaudio <claudio@openbsd.org>2017-03-25 17:25:34 +0000
commitfe006a116d1775efa666fe8afddc5dc84efc24f2 (patch)
tree2b6dfe5c61eeeefa0636e444b71eedbb97ad997b /usr.sbin/httpd/server.c
parentOpenSSL documented the public function BIO_printf(3) (and friends) (diff)
downloadwireguard-openbsd-fe006a116d1775efa666fe8afddc5dc84efc24f2.tar.xz
wireguard-openbsd-fe006a116d1775efa666fe8afddc5dc84efc24f2.zip
Implement TLS ticket support in httpd. Off by default. Use
tls ticket lifetime default to turn it on with a 2h ticket lifetime. Rekeying happens after a quarter of that time. OK reky@ and bob@
Diffstat (limited to 'usr.sbin/httpd/server.c')
-rw-r--r--usr.sbin/httpd/server.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/usr.sbin/httpd/server.c b/usr.sbin/httpd/server.c
index a00378bf9de..9ff532d7746 100644
--- a/usr.sbin/httpd/server.c
+++ b/usr.sbin/httpd/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.107 2017/02/07 12:27:42 reyk Exp $ */
+/* $OpenBSD: server.c,v 1.108 2017/03/25 17:25:34 claudio Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -58,6 +58,7 @@ int server_socket(struct sockaddr_storage *, in_port_t,
struct server_config *, int, int);
int server_socket_listen(struct sockaddr_storage *, in_port_t,
struct server_config *);
+struct server *server_byid(uint32_t);
int server_tls_init(struct server *);
void server_tls_readcb(int, short, void *);
@@ -135,6 +136,8 @@ server_tls_cmp(struct server *s1, struct server *s2, int match_keypair)
if (sc1->tls_protocols != sc2->tls_protocols)
return (-1);
+ if (sc1->tls_ticket_lifetime != sc2->tls_ticket_lifetime)
+ return (-1);
if (strcmp(sc1->tls_ciphers, sc2->tls_ciphers) != 0)
return (-1);
if (strcmp(sc1->tls_dhe_params, sc2->tls_dhe_params) != 0)
@@ -266,6 +269,31 @@ 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_lifetime) {
+ if (tls_config_set_session_lifetime(srv->srv_tls_config,
+ srv->srv_conf.tls_ticket_lifetime) == -1) {
+ log_warnx("%s: could not set the TLS session lifetime: "
+ "%s", __func__,
+ tls_config_error(srv->srv_tls_config));
+ return (-1);
+ }
+ tls_config_add_ticket_key(srv->srv_tls_config,
+ srv->srv_conf.tls_ticket_key.tt_keyrev,
+ srv->srv_conf.tls_ticket_key.tt_key,
+ sizeof(srv->srv_conf.tls_ticket_key.tt_key));
+ explicit_bzero(&srv->srv_conf.tls_ticket_key,
+ sizeof(srv->srv_conf.tls_ticket_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));
@@ -287,6 +315,16 @@ server_tls_init(struct server *srv)
}
void
+server_generate_ticket_key(struct server_config *srv_conf)
+{
+ struct server_tls_ticket *key = &srv_conf->tls_ticket_key;
+
+ key->tt_id = srv_conf->id;
+ key->tt_keyrev = arc4random();
+ arc4random_buf(key->tt_key, sizeof(key->tt_key));
+}
+
+void
server_init(struct privsep *ps, struct privsep_proc *p, void *arg)
{
server_http();
@@ -438,6 +476,18 @@ serverconfig_byid(uint32_t id)
return (NULL);
}
+struct server *
+server_byid(uint32_t id)
+{
+ struct server *srv;
+
+ TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) {
+ if (srv->srv_conf.id == id)
+ return (srv);
+ }
+ return (NULL);
+}
+
int
server_foreach(int (*srv_cb)(struct server *,
struct server_config *, void *), void *arg)
@@ -1226,6 +1276,9 @@ server_close(struct client *clt, const char *msg)
int
server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
{
+ struct server *srv;
+ struct server_tls_ticket key;
+
switch (imsg->hdr.type) {
case IMSG_CFG_MEDIA:
config_getmedia(httpd_env, imsg);
@@ -1248,6 +1301,16 @@ server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_CTL_RESET:
config_getreset(httpd_env, imsg);
break;
+ case IMSG_TLSTICKET_REKEY:
+ IMSG_SIZE_CHECK(imsg, (&key));
+ memcpy(&key, imsg->data, sizeof(key));
+ /* apply to the right server */
+ srv = server_byid(key.tt_id);
+ if (srv) {
+ tls_config_add_ticket_key(srv->srv_tls_config,
+ key.tt_keyrev, key.tt_key, sizeof(key.tt_key));
+ }
+ break;
default:
return (-1);
}