From 63e4148927c91482e64a0d56eb4d36534ed5482a Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Fri, 18 Apr 2014 13:55:27 +0000 Subject: Introduce privsep for private keys: - Move RSA private keys to a new separate process instead of copying them to the relays. A custom RSA engine is used by the SSL/TLS code of the relay processes to send RSA private key encryption/decryption (also used for sign/verify) requests to the new "ca" processes instead of operating on the private key directly. - Each relay process gets its own related ca process. Setting "prefork 5" in the config file will spawn 10 processes (5 relay, 5 ca). This diff also reduces the default number of relay processes from 5 to 3 which should be suitable in most installations without a very heavy load. - Don't keep text versions of the keys in memory, parse them once and keep the binary representation. This might still be the case in OpenSSL's internals but will be fixed in the library. This diff doesn't prevent something like "heartbleed" but adds an additional mitigation to prevent leakage of the private keys from the processes doing SSL/TLS. With feedback from many ok benno@ --- usr.sbin/relayd/relay.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'usr.sbin/relayd/relay.c') diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index 8c73ded7bcd..ad7b7f86b65 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,7 +1,7 @@ -/* $OpenBSD: relay.c,v 1.167 2013/09/09 17:57:44 reyk Exp $ */ +/* $OpenBSD: relay.c,v 1.168 2014/04/18 13:55:26 reyk Exp $ */ /* - * Copyright (c) 2006 - 2013 Reyk Floeter + * Copyright (c) 2006 - 2014 Reyk Floeter * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -52,6 +52,8 @@ int relay_dispatch_parent(int, struct privsep_proc *, struct imsg *); int relay_dispatch_pfe(int, struct privsep_proc *, struct imsg *); +int relay_dispatch_ca(int, struct privsep_proc *, + struct imsg *); void relay_shutdown(void); void relay_nodedebug(const char *, struct protonode *); @@ -96,6 +98,7 @@ int proc_id; static struct privsep_proc procs[] = { { "parent", PROC_PARENT, relay_dispatch_parent }, { "pfe", PROC_PFE, relay_dispatch_pfe }, + { "ca", PROC_CA, relay_dispatch_ca } }; pid_t @@ -1781,6 +1784,12 @@ relay_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg) return (0); } +int +relay_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg) +{ + return (-1); +} + int relay_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) { @@ -1904,9 +1913,11 @@ relay_ssl_ctx_create(struct relay *rlay) goto err; log_debug("%s: loading private key", __func__); - if (!ssl_ctx_use_private_key(ctx, rlay->rl_ssl_key, - rlay->rl_conf.ssl_key_len)) + if (!ssl_ctx_fake_private_key(ctx, + &rlay->rl_conf.id, rlay->rl_ssl_cert, rlay->rl_conf.ssl_cert_len, + &rlay->rl_ssl_x509, &rlay->rl_ssl_pkey)) goto err; + if (!SSL_CTX_check_private_key(ctx)) goto err; @@ -1915,6 +1926,9 @@ relay_ssl_ctx_create(struct relay *rlay) strlen(rlay->rl_conf.name))) goto err; + /* The text versions of the keys/certs are not needed anymore */ + purge_key(&rlay->rl_ssl_cert, rlay->rl_conf.ssl_cert_len); + return (ctx); err: @@ -2087,7 +2101,7 @@ relay_ssl_connect(int fd, short event, void *arg) SSL_get_peer_certificate(con->se_out.ssl)) != NULL) { con->se_in.sslcert = ssl_update_certificate(servercert, - rlay->rl_ssl_key, rlay->rl_conf.ssl_key_len, + rlay->rl_ssl_pkey, rlay->rl_ssl_cakey, rlay->rl_conf.ssl_cakey_len, rlay->rl_ssl_cacert, rlay->rl_conf.ssl_cacert_len); } else -- cgit v1.2.3