relayd SSL/TLS keep RSA private keys in separate process

2014-04-09 Thread Reyk Floeter
Hi,

relayd uses privsep to mitigate the risk of potential attacks.
OpenSSL's SSL code wasn't designed with privsep in mind.  We already
have a hack to load the keys and certificates in the parent process
and to send them via imsg to the chroot'ed relays; OpenSSL normally
wants to load them from files.

This diff goes a bit further by moving the 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 requests to the new ca process (I
used the name ca because something similar exists in iked) instead
of operating on the private key directly.

The diff is still experimental, misses support for the SSL inspection,
probably client mode and hasn't been tested very well.  The following
configuration has been tested:

relay wwwssl {
listen on $ext_addr port 443 ssl
forward to 127.0.0.1 port 80
}

It may impact performance because it adds a little for the RSA
communication between the processes, but SSL only does it once to get
the session keys and RSA is already slow.

I would like to get some first thoughts / feedback.

Reyk

Index: Makefile
===
RCS file: /cvs/src/usr.sbin/relayd/Makefile,v
retrieving revision 1.24
diff -u -p -u -p -r1.24 Makefile
--- Makefile18 Jan 2014 05:54:51 -  1.24
+++ Makefile9 Apr 2014 14:02:37 -
@@ -1,10 +1,12 @@
 #  $OpenBSD: Makefile,v 1.24 2014/01/18 05:54:51 martynas Exp $
 
 PROG=  relayd
-SRCS=  parse.y log.c control.c ssl.c ssl_privsep.c \
-   relayd.c pfe.c pfe_filter.c pfe_route.c hce.c relay.c \
-   relay_http.c relay_udp.c carp.c check_icmp.c check_tcp.c \
-   check_script.c name2id.c snmp.c shuffle.c proc.c config.c
+SRCS=  parse.y
+SRCS+= ca.c carp.c check_icmp.c check_script.c check_tcp.c \
+   config.c control.c hce.c log.c name2id.c \
+   pfe.c pfe_filter.c pfe_route.c proc.c \
+   relay.c relay_http.c relay_udp.c relayd.c \
+   shuffle.c snmp.c ssl.c ssl_privsep.c
 MAN=   relayd.8 relayd.conf.5
 
 LDADD= -levent -lssl -lcrypto -lutil
Index: ca.c
===
RCS file: ca.c
diff -N ca.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ ca.c9 Apr 2014 14:02:37 -
@@ -0,0 +1,414 @@
+/* $OpenBSD$   */
+
+/*
+ * Copyright (c) 2014 Reyk Floeter r...@openbsd.org
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include sys/param.h
+#include sys/queue.h
+#include sys/socket.h
+#include sys/uio.h
+
+#include net/if.h
+#include netinet/in.h
+
+#include limits.h
+#include event.h
+#include fcntl.h
+#include unistd.h
+#include string.h
+#include stdlib.h
+#include errno.h
+
+#include openssl/pem.h
+#include openssl/evp.h
+#include openssl/rsa.h
+#include openssl/engine.h
+
+#include relayd.h
+
+voidca_init(struct privsep *, struct privsep_proc *p, void *);
+
+int ca_dispatch_parent(int, struct privsep_proc *, struct imsg *);
+int ca_dispatch_relay(int, struct privsep_proc *, struct imsg *);
+
+int rsae_pub_enc(int, const u_char *, u_char *, RSA *, int);
+int rsae_pub_dec(int,const u_char *, u_char *, RSA *, int);
+int rsae_priv_enc(int, const u_char *, u_char *, RSA *, int);
+int rsae_priv_dec(int, const u_char *, u_char *, RSA *, int);
+int rsae_mod_exp(BIGNUM *, const BIGNUM *, RSA *, BN_CTX *);
+int rsae_bn_mod_exp(BIGNUM *, const BIGNUM *, const BIGNUM *,
+   const BIGNUM *, BN_CTX *, BN_MONT_CTX *);
+int rsae_init(RSA *);
+int rsae_finish(RSA *);
+int rsae_sign(int, const u_char *, u_int,
+   u_char *, u_int *, const RSA *);
+int rsae_verify(int dtype, const u_char *m, u_int,
+   const u_char *, u_int, const RSA *);
+int rsae_keygen(RSA *, int, BIGNUM *, BN_GENCB *);
+
+static struct relayd *env = NULL;
+extern int  proc_id;
+
+static struct privsep_proc procs[] = {
+   { parent, PROC_PARENT,ca_dispatch_parent },
+   { relay,  PROC_RELAY, ca_dispatch_relay },
+};
+
+pid_t
+ca(struct privsep *ps, struct privsep_proc *p)
+{
+   env = 

Re: OpenSSH hole, April 9

2014-04-09 Thread Devin Reade

Quoting Theo de Raadt dera...@cvs.openbsd.org:


If tomorrow Damien or I had to announce a major OpenSSH hole, how
screwed would the Internet be?


Would you mind clarifying this a bit?  Was the post strictly a
(justified) comment about the lack of funding, or should we be
anticipating another announcement in addition to the existing OpenSSL
mess?

Devin



Re: OpenSSH hole, April 9

2014-04-09 Thread Bob Beck
On Wed, Apr 09, 2014 at 02:49:21PM -0600, Devin Reade wrote:
 Quoting Theo de Raadt dera...@cvs.openbsd.org:
 
 If tomorrow Damien or I had to announce a major OpenSSH hole, how
 screwed would the Internet be?
 
 Would you mind clarifying this a bit?  Was the post strictly a
 (justified) comment about the lack of funding, or should we be
 anticipating another announcement in addition to the existing OpenSSL
 mess?

The former. While nothing's ever for sure, OpenSSH does not normally
attempt to include exploit mitigation technique circumvention mechanisms.

-Bob



Re: OpenSSH hole, April 9

2014-04-09 Thread Devin Reade

Thanks for the clarification.

I would also like to thank whomever for the extra descriptive text on
the openssl patch issued the other day.  Having the clarification on
the (non)impact on OpenSSH right in the patch was good ...

Devin




Re: OpenSSH hole, April 9

2014-04-09 Thread STeve Andre'

On 04/09/14 16:49, Devin Reade wrote:

Quoting Theo de Raadt dera...@cvs.openbsd.org:


If tomorrow Damien or I had to announce a major OpenSSH hole, how
screwed would the Internet be?


Would you mind clarifying this a bit?  Was the post strictly a
(justified) comment about the lack of funding, or should we be
anticipating another announcement in addition to the existing OpenSSL
mess?

Devin




That was a rhetorical question.



Re: OpenSSH hole, April 9

2014-04-09 Thread Theo de Raadt
Thanks for the clarification.

I would also like to thank whomever for the extra descriptive text on
the openssl patch issued the other day.  Having the clarification on
the (non)impact on OpenSSH right in the patch was good ...

You are welcome.  Stuart Henderson wrote the draft, but he forgot that
part, and Damien Miller and I realized it was needed.  We sensed there
might be some ambiguity...  we'll take care the next time an
OpenOffice problem also.

... as long as you aren't using FreeBSD or a derivative (hint: Jupiper),
you are fine.  That's the only place I know of an OpenSSH hole.

Oh now I sense some angst.  Please ask Kirk McKusick, he knows the
story about why this is not being disclosed to FreeBSD.  Sometimes I
feel a bit sorry for them (and for him), but then the next minute I
don't feel sorry because there's damn good reasons they won't be
told about what I found.

Does that answer help?  Hope so.