Instead of using imsg to pass certificates, pass the fd to the cert to the
relay processes. This allows for large certificates and esp. ca file to
work. OCSP stapling will also be added through this.

OK?
-- 
:wq Claudio

Index: ca.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/ca.c,v
retrieving revision 1.28
diff -u -p -r1.28 ca.c
--- ca.c        9 Aug 2017 21:31:16 -0000       1.28
+++ ca.c        12 Aug 2017 14:05:44 -0000
@@ -109,18 +109,23 @@ void
 ca_launch(void)
 {
        char             hash[TLS_CERT_HASH_SIZE];
+       char            *buf;
        BIO             *in = NULL;
        EVP_PKEY        *pkey = NULL;
        struct relay    *rlay;
        X509            *cert = NULL;
+       off_t            len;
 
        TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
                if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) == 0)
                        continue;
 
-               if (rlay->rl_conf.tls_cert_len) {
-                       if ((in = BIO_new_mem_buf(rlay->rl_tls_cert,
-                           rlay->rl_conf.tls_cert_len)) == NULL)
+               if (rlay->rl_tls_cert_fd != -1) {
+                       if ((buf = relay_load_fd(rlay->rl_tls_cert_fd,
+                           &len)) == NULL)
+                               fatalx("ca_launch: cert");
+
+                       if ((in = BIO_new_mem_buf(buf, len)) == NULL)
                                fatalx("ca_launch: cert");
 
                        if ((cert = PEM_read_bio_X509(in, NULL,
@@ -131,8 +136,7 @@ ca_launch(void)
 
                        BIO_free(in);
                        X509_free(cert);
-                       purge_key(&rlay->rl_tls_cert,
-                           rlay->rl_conf.tls_cert_len);
+                       purge_key(&buf, len);
                }
                if (rlay->rl_conf.tls_key_len) {
                        if ((in = BIO_new_mem_buf(rlay->rl_tls_key,
@@ -153,9 +157,12 @@ ca_launch(void)
                            rlay->rl_conf.tls_key_len);
                }
 
-               if (rlay->rl_conf.tls_cacert_len) {
-                       if ((in = BIO_new_mem_buf(rlay->rl_tls_cacert,
-                           rlay->rl_conf.tls_cacert_len)) == NULL)
+               if (rlay->rl_tls_cacert_fd != -1) {
+                       if ((buf = relay_load_fd(rlay->rl_tls_cacert_fd,
+                           &len)) == NULL)
+                               fatalx("ca_launch: cacert");
+
+                       if ((in = BIO_new_mem_buf(buf, len)) == NULL)
                                fatalx("ca_launch: cacert");
 
                        if ((cert = PEM_read_bio_X509(in, NULL,
@@ -166,8 +173,7 @@ ca_launch(void)
 
                        BIO_free(in);
                        X509_free(cert);
-                       purge_key(&rlay->rl_tls_cacert,
-                           rlay->rl_conf.tls_cacert_len);
+                       purge_key(&buf, len);
                }
                if (rlay->rl_conf.tls_cakey_len) {
                        if ((in = BIO_new_mem_buf(rlay->rl_tls_cakey,
@@ -187,6 +193,7 @@ ca_launch(void)
                        purge_key(&rlay->rl_tls_cakey,
                            rlay->rl_conf.tls_cakey_len);
                }
+               close(rlay->rl_tls_ca_fd);
        }
 }
 
@@ -196,6 +203,9 @@ ca_dispatch_parent(int fd, struct privse
        switch (imsg->hdr.type) {
        case IMSG_CFG_RELAY:
                config_getrelay(env, imsg);
+               break;
+       case IMSG_CFG_RELAY_FD:
+               config_getrelayfd(env, imsg);
                break;
        case IMSG_CFG_DONE:
                config_getcfg(env, imsg);
Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/config.c,v
retrieving revision 1.33
diff -u -p -r1.33 config.c
--- config.c    14 Sep 2017 08:59:54 -0000      1.33
+++ config.c    30 Sep 2017 16:52:36 -0000
@@ -47,10 +47,10 @@ config_init(struct relayd *env)
        }
 
        ps->ps_what[PROC_PARENT] = CONFIG_ALL;
-       ps->ps_what[PROC_PFE] = CONFIG_ALL & ~CONFIG_PROTOS;
+       ps->ps_what[PROC_PFE] = CONFIG_ALL & ~(CONFIG_PROTOS|CONFIG_CERTS);
        ps->ps_what[PROC_HCE] = CONFIG_TABLES;
-       ps->ps_what[PROC_CA] = CONFIG_RELAYS;
-       ps->ps_what[PROC_RELAY] = CONFIG_RELAYS|
+       ps->ps_what[PROC_CA] = CONFIG_RELAYS|CONFIG_CERTS;
+       ps->ps_what[PROC_RELAY] = CONFIG_RELAYS|CONFIG_CERTS|
            CONFIG_TABLES|CONFIG_PROTOS|CONFIG_CA_ENGINE;
 
        /* Other configuration */
@@ -771,6 +771,25 @@ config_getrule(struct relayd *env, struc
        return (0);
 }
 
+static int
+config_setrelayfd(struct privsep *ps, int id, int n, int rlay_id, int type,
+    int ofd)
+{
+       struct ctl_relayfd      rfd;
+       int                     fd;
+
+       rfd.relayid = rlay_id;
+       rfd.type = type;
+
+       if ((fd = dup(ofd)) == -1)
+               return (-1);
+       if (proc_compose_imsg(ps, id, n, IMSG_CFG_RELAY_FD, -1, fd,
+           &rfd, sizeof(rfd)) != 0)
+               return (-1);
+
+       return (0);
+}
+
 int
 config_setrelay(struct relayd *env, struct relay *rlay)
 {
@@ -802,24 +821,13 @@ config_setrelay(struct relayd *env, stru
                c = 0;
                iov[c].iov_base = &rl;
                iov[c++].iov_len = sizeof(rl);
-               if (rl.tls_cert_len) {
-                       iov[c].iov_base = rlay->rl_tls_cert;
-                       iov[c++].iov_len = rl.tls_cert_len;
-               }
+
                if ((what & CONFIG_CA_ENGINE) == 0 &&
                    rl.tls_key_len) {
                        iov[c].iov_base = rlay->rl_tls_key;
                        iov[c++].iov_len = rl.tls_key_len;
                } else
                        rl.tls_key_len = 0;
-               if (rl.tls_ca_len) {
-                       iov[c].iov_base = rlay->rl_tls_ca;
-                       iov[c++].iov_len = rl.tls_ca_len;
-               }
-               if (rl.tls_cacert_len) {
-                       iov[c].iov_base = rlay->rl_tls_cacert;
-                       iov[c++].iov_len = rl.tls_cacert_len;
-               }
                if ((what & CONFIG_CA_ENGINE) == 0 &&
                    rl.tls_cakey_len) {
                        iov[c].iov_base = rlay->rl_tls_cakey;
@@ -841,7 +849,6 @@ config_setrelay(struct relayd *env, stru
                                            __func__, rlay->rl_conf.name);
                                        return (-1);
                                }
-
                                /* Prevent fd exhaustion in the parent. */
                                if (proc_flush_imsg(ps, id, n) == -1) {
                                        log_warn("%s: failed to flush "
@@ -860,6 +867,48 @@ config_setrelay(struct relayd *env, stru
                        }
                }
 
+
+               if (what & CONFIG_CERTS) {
+                       n = -1;
+                       proc_range(ps, id, &n, &m);
+                       for (n = 0; n < m; n++) {
+                               if (rlay->rl_tls_cert_fd != -1 &&
+                                   config_setrelayfd(ps, id, n,
+                                   rlay->rl_conf.id, RELAY_FD_CERT,
+                                   rlay->rl_tls_cert_fd) == -1) {
+                                       log_warn("%s: fd passing failed for "
+                                           "`%s'", __func__,
+                                           rlay->rl_conf.name);
+                                       return (-1);
+                               }
+                               if (rlay->rl_tls_ca_fd != -1 &&
+                                   config_setrelayfd(ps, id, n,
+                                   rlay->rl_conf.id, RELAY_FD_CACERT,
+                                   rlay->rl_tls_ca_fd) == -1) {
+                                       log_warn("%s: fd passing failed for "
+                                           "`%s'", __func__,
+                                           rlay->rl_conf.name);
+                                       return (-1);
+                               }
+                               if (rlay->rl_tls_cacert_fd != -1 &&
+                                   config_setrelayfd(ps, id, n,
+                                   rlay->rl_conf.id, RELAY_FD_CAFILE,
+                                   rlay->rl_tls_cacert_fd) == -1) {
+                                       log_warn("%s: fd passing failed for "
+                                           "`%s'", __func__,
+                                           rlay->rl_conf.name);
+                                       return (-1);
+                               }
+                               /* Prevent fd exhaustion in the parent. */
+                               if (proc_flush_imsg(ps, id, n) == -1) {
+                                       log_warn("%s: failed to flush "
+                                           "IMSG_CFG_RELAY imsg for `%s'",
+                                           __func__, rlay->rl_conf.name);
+                                       return (-1);
+                               }
+                       }
+               }
+
                if ((what & CONFIG_TABLES) == 0)
                        continue;
 
@@ -883,6 +932,18 @@ config_setrelay(struct relayd *env, stru
                close(rlay->rl_s);
                rlay->rl_s = -1;
        }
+       if (rlay->rl_tls_cert_fd != -1) {
+               close(rlay->rl_tls_cert_fd);
+               rlay->rl_tls_cert_fd = -1;
+       }
+       if (rlay->rl_tls_cacert_fd != -1) {
+               close(rlay->rl_tls_cacert_fd);
+               rlay->rl_tls_cacert_fd = -1;
+       }
+       if (rlay->rl_tls_ca_fd != -1) {
+               close(rlay->rl_tls_ca_fd);
+               rlay->rl_tls_ca_fd = -1;
+       }
 
        return (0);
 }
@@ -903,6 +964,9 @@ config_getrelay(struct relayd *env, stru
        s = sizeof(rlay->rl_conf);
 
        rlay->rl_s = imsg->fd;
+       rlay->rl_tls_cert_fd = -1;
+       rlay->rl_tls_ca_fd = -1;
+       rlay->rl_tls_cacert_fd = -1;
 
        if (ps->ps_what[privsep_process] & CONFIG_PROTOS) {
                if (rlay->rl_conf.proto == EMPTY_ID)
@@ -915,39 +979,17 @@ config_getrelay(struct relayd *env, stru
        }
 
        if ((off_t)(IMSG_DATA_SIZE(imsg) - s) <
-           (rlay->rl_conf.tls_cert_len +
-           rlay->rl_conf.tls_key_len +
-           rlay->rl_conf.tls_ca_len +
-           rlay->rl_conf.tls_cacert_len +
-           rlay->rl_conf.tls_cakey_len)) {
+           (rlay->rl_conf.tls_key_len + rlay->rl_conf.tls_cakey_len)) {
                log_debug("%s: invalid message length", __func__);
                goto fail;
        }
 
-       if (rlay->rl_conf.tls_cert_len) {
-               if ((rlay->rl_tls_cert = get_data(p + s,
-                   rlay->rl_conf.tls_cert_len)) == NULL)
-                       goto fail;
-               s += rlay->rl_conf.tls_cert_len;
-       }
        if (rlay->rl_conf.tls_key_len) {
                if ((rlay->rl_tls_key = get_data(p + s,
                    rlay->rl_conf.tls_key_len)) == NULL)
                        goto fail;
                s += rlay->rl_conf.tls_key_len;
        }
-       if (rlay->rl_conf.tls_ca_len) {
-               if ((rlay->rl_tls_ca = get_data(p + s,
-                   rlay->rl_conf.tls_ca_len)) == NULL)
-                       goto fail;
-               s += rlay->rl_conf.tls_ca_len;
-       }
-       if (rlay->rl_conf.tls_cacert_len) {
-               if ((rlay->rl_tls_cacert = get_data(p + s,
-                   rlay->rl_conf.tls_cacert_len)) == NULL)
-                       goto fail;
-               s += rlay->rl_conf.tls_cacert_len;
-       }
        if (rlay->rl_conf.tls_cakey_len) {
                if ((rlay->rl_tls_cakey = get_data(p + s,
                    rlay->rl_conf.tls_cakey_len)) == NULL)
@@ -967,9 +1009,8 @@ config_getrelay(struct relayd *env, stru
        return (0);
 
  fail:
-       free(rlay->rl_tls_cert);
        free(rlay->rl_tls_key);
-       free(rlay->rl_tls_ca);
+       free(rlay->rl_tls_cakey);
        close(rlay->rl_s);
        free(rlay);
        return (-1);
@@ -1009,6 +1050,45 @@ config_getrelaytable(struct relayd *env,
        DPRINTF("%s: %s %d received relay table %s for relay %s", __func__,
            env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
            table->conf.name, rlay->rl_conf.name);
+
+       return (0);
+
+ fail:
+       free(rlt);
+       return (-1);
+}
+
+int
+config_getrelayfd(struct relayd *env, struct imsg *imsg)
+{
+       struct relay_table      *rlt = NULL;
+       struct ctl_relayfd       crfd;
+       struct relay            *rlay;
+       u_int8_t                *p = imsg->data;
+
+       IMSG_SIZE_CHECK(imsg, &crfd);
+       memcpy(&crfd, p, sizeof(crfd));
+
+       if ((rlay = relay_find(env, crfd.relayid)) == NULL) {
+               log_debug("%s: unknown relay", __func__);
+               goto fail;
+       }
+
+       switch (crfd.type) {
+       case RELAY_FD_CERT:
+               rlay->rl_tls_cert_fd = imsg->fd;
+               break;
+       case RELAY_FD_CACERT:
+               rlay->rl_tls_ca_fd = imsg->fd;
+               break;
+       case RELAY_FD_CAFILE:
+               rlay->rl_tls_cacert_fd = imsg->fd;
+               break;
+       }
+
+       DPRINTF("%s: %s %d received relay fd %d type %d for relay %s", __func__,
+           env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
+           imsg->fd, crfd.type, rlay->rl_conf.name);
 
        return (0);
 
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.218
diff -u -p -r1.218 parse.y
--- parse.y     16 Nov 2017 14:24:34 -0000      1.218
+++ parse.y     18 Nov 2017 18:00:46 -0000
@@ -99,7 +99,6 @@ objid_t                        last_relay_id = 0;
 objid_t                         last_proto_id = 0;
 objid_t                         last_rt_id = 0;
 objid_t                         last_nr_id = 0;
-objid_t                         last_key_id = 0;
 
 static struct rdr      *rdr = NULL;
 static struct table    *table = NULL;
@@ -1669,6 +1668,9 @@ relay             : RELAY STRING  {
                        r->rl_proto = NULL;
                        r->rl_conf.proto = EMPTY_ID;
                        r->rl_conf.dstretry = 0;
+                       r->rl_tls_cert_fd = -1;
+                       r->rl_tls_ca_fd = -1;
+                       r->rl_tls_cacert_fd = -1;
                        TAILQ_INIT(&r->rl_tables);
                        if (last_relay_id == INT_MAX) {
                                yyerror("too many relays defined");
@@ -3201,10 +3203,8 @@ int
 relay_id(struct relay *rl)
 {
        rl->rl_conf.id = ++last_relay_id;
-       rl->rl_conf.tls_keyid = ++last_key_id;
-       rl->rl_conf.tls_cakeyid = ++last_key_id;
 
-       if (last_relay_id == INT_MAX || last_key_id == INT_MAX)
+       if (last_relay_id == INT_MAX)
                return (-1);
 
        return (0);
@@ -3224,8 +3224,9 @@ relay_inherit(struct relay *ra, struct r
        rb->rl_conf.flags =
            (ra->rl_conf.flags & ~F_TLS) | (rc.flags & F_TLS);
        if (!(rb->rl_conf.flags & F_TLS)) {
-               rb->rl_tls_cert = NULL;
-               rb->rl_conf.tls_cert_len = 0;
+               rb->rl_tls_cert_fd = -1;
+               rb->rl_tls_cacert_fd = -1;
+               rb->rl_tls_ca_fd = -1;
                rb->rl_tls_key = NULL;
                rb->rl_conf.tls_key_len = 0;
        }
Index: relay.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.229
diff -u -p -r1.229 relay.c
--- relay.c     27 Nov 2017 17:35:49 -0000      1.229
+++ relay.c     27 Nov 2017 18:48:47 -0000
@@ -81,7 +81,6 @@ void           relay_tls_connected(struct ctl_re
 void            relay_tls_readcb(int, short, void *);
 void            relay_tls_writecb(int, short, void *);
 
-char           *relay_load_file(const char *, off_t *);
 extern void     bufferevent_read_pressure_cb(struct evbuffer *, size_t,
                    size_t, void *);
 
@@ -965,6 +964,8 @@ relay_error(struct bufferevent *bev, sho
        struct rsession         *con = cre->con;
        struct evbuffer         *dst;
 
+       DPRINTF("%s: session %d: dir %d state %d to read %lld error %x",
+               __func__, con->se_id, cre->dir, cre->state, cre->toread, error);
        if (error & EVBUFFER_TIMEOUT) {
                if (cre->splicelen >= 0) {
                        bufferevent_enable(bev, EV_READ);
@@ -1923,6 +1924,9 @@ relay_dispatch_parent(int fd, struct pri
        case IMSG_CFG_RELAY_TABLE:
                config_getrelaytable(env, imsg);
                break;
+       case IMSG_CFG_RELAY_FD:
+               config_getrelayfd(env, imsg);
+               break;
        case IMSG_CFG_DONE:
                config_getcfg(env, imsg);
                break;
@@ -2037,6 +2041,8 @@ relay_tls_ctx_create(struct relay *rlay)
        struct tls              *tls = NULL;
        const char              *fake_key;
        int                      fake_keylen;
+       char                    *buf = NULL, *cabuf = NULL;
+       off_t                    len = 0, calen = 0;
 
        if ((tls_cfg = tls_config_new()) == NULL) {
                log_warnx("unable to allocate TLS config");
@@ -2060,13 +2066,20 @@ relay_tls_ctx_create(struct relay *rlay)
                 */
                tls_config_insecure_noverifyname(tls_client_cfg);
 
-               if (rlay->rl_tls_ca != NULL) {
-                       if (tls_config_set_ca_mem(tls_client_cfg,
-                           rlay->rl_tls_ca, rlay->rl_conf.tls_ca_len) != 0) {
+               if (rlay->rl_tls_ca_fd != -1) {
+                       if ((buf = relay_load_fd(rlay->rl_tls_ca_fd, &len)) ==
+                           NULL) {
+                               log_warn("failed to read root certificates");
+                               goto err;
+                       }
+
+                       if (tls_config_set_ca_mem(tls_client_cfg, buf, len) !=
+                           0) {
                                log_warnx("failed to set root certificates: %s",
                                    tls_config_error(tls_client_cfg));
                                goto err;
                        }
+                       purge_key(&buf, len);
                } else {
                        /* No root cert available so disable the checking */
                        tls_config_insecure_noverifycert(tls_client_cfg);
@@ -2087,31 +2100,38 @@ relay_tls_ctx_create(struct relay *rlay)
                 */
                tls_config_skip_private_key_check(tls_cfg);
 
-               if ((fake_keylen = ssl_ctx_fake_private_key(rlay->rl_tls_cert,
-                   rlay->rl_conf.tls_cert_len, &fake_key)) == -1) {
+               if ((buf = relay_load_fd(rlay->rl_tls_cert_fd, &len)) == NULL) {
+                       log_warn("failed to load tls certificate");
+                       goto err;
+               }
+
+               if ((fake_keylen = ssl_ctx_fake_private_key(buf, len,
+                   &fake_key)) == -1) {
                        /* error already printed */
                        goto err;
                }
 
-               if (tls_config_set_keypair_ocsp_mem(tls_cfg,
-                   rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len,
+               if (tls_config_set_keypair_ocsp_mem(tls_cfg, buf, len,
                    fake_key, fake_keylen, NULL, 0) != 0) {
                        log_warnx("failed to set tls certificate: %s",
                            tls_config_error(tls_cfg));
                        goto err;
                }
 
-               if (rlay->rl_conf.tls_cacert_len) {
+
+               if (rlay->rl_tls_cacert_fd != -1) {
+                       if ((cabuf = relay_load_fd(rlay->rl_tls_cacert_fd,
+                           &calen)) == NULL) {
+                               log_warn("failed to load tls CA certificate");
+                               goto err;
+                       }
                        log_debug("%s: loading CA certificate", __func__);
-                       if (!ssl_load_pkey(
-                           rlay->rl_tls_cacert, rlay->rl_conf.tls_cacert_len,
+                       if (!ssl_load_pkey(cabuf, calen,
                            &rlay->rl_tls_cacertx509, &rlay->rl_tls_capkey))
                                goto err;
                        /* loading certificate public key */
                        log_debug("%s: loading certificate", __func__);
-                       if (!ssl_load_pkey(
-                           rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len,
-                           NULL, &rlay->rl_tls_pkey))
+                       if (!ssl_load_pkey(buf, len, NULL, &rlay->rl_tls_pkey))
                                goto err;
                }
 
@@ -2128,11 +2148,15 @@ relay_tls_ctx_create(struct relay *rlay)
                }
                rlay->rl_tls_cfg = tls_cfg;
                rlay->rl_tls_ctx = tls;
+
+               purge_key(&cabuf, calen);
+               purge_key(&buf, len);
        }
 
-       /* The text versions of the keys/certs are not needed anymore */
-       purge_key(&rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len);
-       purge_key(&rlay->rl_tls_cacert, rlay->rl_conf.tls_cacert_len);
+       /* The fd for the keys/certs are not needed anymore */
+       close(rlay->rl_tls_cert_fd);
+       close(rlay->rl_tls_cacert_fd);
+       close(rlay->rl_tls_ca_fd);
 
        if (rlay->rl_tls_client_cfg == NULL)
                tls_config_free(tls_client_cfg);
@@ -2141,6 +2165,9 @@ relay_tls_ctx_create(struct relay *rlay)
 
        return (0);
  err:
+       purge_key(&cabuf, calen);
+       purge_key(&buf, len);
+
        tls_config_free(tls_client_cfg);
        tls_config_free(tls_cfg);
        return (-1);
@@ -2547,21 +2574,21 @@ relay_cmp_af(struct sockaddr_storage *a,
 }
 
 char *
-relay_load_file(const char *name, off_t *len)
+relay_load_fd(int fd, off_t *len)
 {
+       char            *buf = NULL;
        struct stat      st;
        off_t            size;
-       u_int8_t        *buf = NULL;
-       int              fd;
+       ssize_t          rv;
 
-       if ((fd = open(name, O_RDONLY)) == -1)
-               return (NULL);
        if (fstat(fd, &st) != 0)
                goto fail;
        size = st.st_size;
        if ((buf = calloc(1, size + 1)) == NULL)
                goto fail;
-       if (read(fd, buf, size) != size)
+       if (lseek(fd, 0, SEEK_SET) != 0)
+               goto fail;
+       if ((rv = read(fd, buf, size)) != size)
                goto fail;
 
        close(fd);
@@ -2585,16 +2612,14 @@ relay_load_certfiles(struct relay *rlay)
 
        if (rlay->rl_conf.flags & F_TLSCLIENT) {
                if (strlen(proto->tlsca)) {
-                       if ((rlay->rl_tls_ca =
-                           relay_load_file(proto->tlsca,
-                           &rlay->rl_conf.tls_ca_len)) == NULL)
+                       if ((rlay->rl_tls_ca_fd =
+                           open(proto->tlsca, O_RDONLY)) == -1)
                                return (-1);
                        log_debug("%s: using ca %s", __func__, proto->tlsca);
                }
                if (strlen(proto->tlscacert)) {
-                       if ((rlay->rl_tls_cacert =
-                           relay_load_file(proto->tlscacert,
-                           &rlay->rl_conf.tls_cacert_len)) == NULL)
+                       if ((rlay->rl_tls_cacert_fd =
+                           open(proto->tlscacert, O_RDONLY)) == -1)
                                return (-1);
                        log_debug("%s: using ca certificate %s", __func__,
                            proto->tlscacert);
@@ -2619,13 +2644,11 @@ relay_load_certfiles(struct relay *rlay)
        if (snprintf(certfile, sizeof(certfile),
            "/etc/ssl/%s:%u.crt", hbuf, useport) == -1)
                return (-1);
-       if ((rlay->rl_tls_cert = relay_load_file(certfile,
-           &rlay->rl_conf.tls_cert_len)) == NULL) {
+       if ((rlay->rl_tls_cert_fd = open(certfile, O_RDONLY)) == -1) {
                if (snprintf(certfile, sizeof(certfile),
                    "/etc/ssl/%s.crt", hbuf) == -1)
                        return (-1);
-               if ((rlay->rl_tls_cert = relay_load_file(certfile,
-                   &rlay->rl_conf.tls_cert_len)) == NULL)
+               if ((rlay->rl_tls_cert_fd = open(certfile, O_RDONLY)) == -1)
                        return (-1);
                useport = 0;
        }
Index: relayd.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.c,v
retrieving revision 1.169
diff -u -p -r1.169 relayd.c
--- relayd.c    31 May 2017 04:14:34 -0000      1.169
+++ relayd.c    11 Aug 2017 19:22:21 -0000
@@ -294,9 +294,7 @@ parent_configure(struct relayd *env)
        TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
                /* Check for TLS Inspection */
                if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) ==
-                   (F_TLS|F_TLSCLIENT) &&
-                   rlay->rl_conf.tls_cacert_len &&
-                   rlay->rl_conf.tls_cakey_len)
+                   (F_TLS|F_TLSCLIENT) && rlay->rl_tls_cacert_fd != -1)
                        rlay->rl_conf.flags |= F_TLSINSPECT;
 
                config_setrelay(env, rlay);
@@ -571,9 +569,7 @@ purge_relay(struct relayd *env, struct r
        if (rlay->rl_dstbev != NULL)
                bufferevent_free(rlay->rl_dstbev);
 
-       purge_key(&rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len);
        purge_key(&rlay->rl_tls_key, rlay->rl_conf.tls_key_len);
-       purge_key(&rlay->rl_tls_ca, rlay->rl_conf.tls_ca_len);
        purge_key(&rlay->rl_tls_cakey, rlay->rl_conf.tls_cakey_len);
 
        if (rlay->rl_tls_pkey != NULL) {
Index: relayd.h
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.243
diff -u -p -r1.243 relayd.h
--- relayd.h    15 Nov 2017 19:03:26 -0000      1.243
+++ relayd.h    18 Nov 2017 18:00:46 -0000
@@ -90,6 +90,7 @@
 #define CONFIG_ROUTES          0x10
 #define CONFIG_RTS             0x20
 #define CONFIG_CA_ENGINE       0x40
+#define CONFIG_CERTS           0x80
 #define CONFIG_ALL             0xff
 
 #define SMALL_READ_BUF_SIZE    1024
@@ -136,6 +137,14 @@ struct ctl_relaytable {
        u_int32_t        flags;
 };
 
+struct ctl_relayfd {
+       objid_t          relayid;
+       int              type;
+};
+#define RELAY_FD_CERT  1
+#define RELAY_FD_CACERT        2
+#define RELAY_FD_CAFILE        3
+
 struct ctl_script {
        objid_t          host;
        int              retval;
@@ -759,13 +768,8 @@ struct relay_config {
        struct timeval           timeout;
        enum forwardmode         fwdmode;
        union hashkey            hashkey;
-       off_t                    tls_cert_len;
        off_t                    tls_key_len;
-       objid_t                  tls_keyid;
-       off_t                    tls_ca_len;
-       off_t                    tls_cacert_len;
        off_t                    tls_cakey_len;
-       objid_t                  tls_cakeyid;
 };
 
 struct relay {
@@ -789,11 +793,11 @@ struct relay {
        struct tls_config       *rl_tls_client_cfg;
        struct tls              *rl_tls_ctx;
 
-       char                    *rl_tls_cert;
+       int                     rl_tls_cert_fd;
+       int                     rl_tls_ca_fd;
+       int                     rl_tls_cacert_fd;
        char                    *rl_tls_key;
        EVP_PKEY                *rl_tls_pkey;
-       char                    *rl_tls_ca;
-       char                    *rl_tls_cacert;
        X509                    *rl_tls_cacertx509;
        char                    *rl_tls_cakey;
        EVP_PKEY                *rl_tls_capkey;
@@ -960,6 +964,8 @@ enum imsg_type {
        IMSG_CFG_RULE,
        IMSG_CFG_RELAY,
        IMSG_CFG_RELAY_TABLE,
+       IMSG_CFG_RELAY_CERT,
+       IMSG_CFG_RELAY_FD,
        IMSG_CFG_DONE,
        IMSG_CA_PRIVENC,
        IMSG_CA_PRIVDEC,
@@ -1163,6 +1169,7 @@ void       relay(struct privsep *, struct pri
 int     relay_privinit(struct relay *);
 void    relay_notify_done(struct host *, const char *);
 int     relay_session_cmp(struct rsession *, struct rsession *);
+char   *relay_load_fd(int, off_t *);
 int     relay_load_certfiles(struct relay *);
 void    relay_close(struct rsession *, const char *);
 void    relay_natlook(int, short, void *);
@@ -1423,5 +1430,6 @@ int        config_getrule(struct relayd *, str
 int     config_setrelay(struct relayd *, struct relay *);
 int     config_getrelay(struct relayd *, struct imsg *);
 int     config_getrelaytable(struct relayd *, struct imsg *);
+int     config_getrelayfd(struct relayd *, struct imsg *);
 
 #endif /* RELAYD_H */

Reply via email to