[patch] relayd OCSP stapling for TLS server

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[patch] relayd OCSP stapling for TLS server

Bruno Flueckiger
Hi,

The patch below adds OCSP stapling to the TLS server in relayd(8). The
OCSP response is read from a binary encoded DER file that can be created
using ocspcheck(8).

If a file with the same name as the certificate and private key files is
found, its content is loaded and OCSP stapling is active. If there is no
file or loading its content fails, OCSP stapling remains disabled.

relayd(8) uses the same mechanism it uses to find the certificate file,
only the file name extension is different: .der instead of .pem

Cheers,
Bruno

Index: usr.sbin/relayd/config.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/config.c,v
retrieving revision 1.39
diff -u -p -r1.39 config.c
--- usr.sbin/relayd/config.c 1 Jun 2019 09:54:19 -0000 1.39
+++ usr.sbin/relayd/config.c 20 Jun 2019 17:37:09 -0000
@@ -913,6 +913,14 @@ config_setrelay(struct relayd *env, stru
     rlay->rl_conf.name);
  return (-1);
  }
+ if (cert->cert_ocsp_fd != -1 &&
+    config_setrelayfd(ps, id, n,
+    cert->cert_id, cert->cert_relayid,
+    RELAY_FD_OCSP, cert->cert_ocsp_fd) == -1) {
+ log_warn("%s: fd passing failed for "
+    "`%s'", __func__,
+    rlay->rl_conf.name);
+ }
  }
  }

@@ -992,6 +1000,10 @@ config_setrelay(struct relayd *env, stru
  close(cert->cert_key_fd);
  cert->cert_key_fd = -1;
  }
+ if (cert->cert_ocsp_fd != -1) {
+ close(cert->cert_ocsp_fd);
+ cert->cert_ocsp_fd = -1;
+ }
  }

  return (0);
@@ -1113,6 +1125,7 @@ config_getrelayfd(struct relayd *env, st
  switch (crfd.type) {
  case RELAY_FD_CERT:
  case RELAY_FD_KEY:
+ case RELAY_FD_OCSP:
  if ((cert = cert_find(env, crfd.id)) == NULL) {
  if ((cert = cert_add(env, crfd.id)) == NULL)
  return (-1);
@@ -1139,6 +1152,9 @@ config_getrelayfd(struct relayd *env, st
  break;
  case RELAY_FD_CAFILE:
  rlay->rl_tls_cacert_fd = imsg->fd;
+ break;
+ case RELAY_FD_OCSP:
+ cert->cert_ocsp_fd = imsg->fd;
  break;
  }

Index: usr.sbin/relayd/relay.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.247
diff -u -p -r1.247 relay.c
--- usr.sbin/relayd/relay.c 31 May 2019 15:15:37 -0000 1.247
+++ usr.sbin/relayd/relay.c 20 Jun 2019 17:37:09 -0000
@@ -2130,8 +2130,8 @@ relay_tls_ctx_create(struct relay *rlay)
  struct relay_cert *cert;
  const char *fake_key;
  int fake_keylen, keyfound = 0;
- char *buf = NULL, *cabuf = NULL;
- off_t len = 0, calen = 0;
+ char *buf = NULL, *cabuf = NULL, *ocspbuf = NULL;
+ off_t len = 0, calen = 0, ocsplen = 0;

  if ((tls_cfg = tls_config_new()) == NULL) {
  log_warnx("unable to allocate TLS config");
@@ -2209,9 +2209,19 @@ relay_tls_ctx_create(struct relay *rlay)
  goto err;
  }

+ if (cert->cert_ocsp_fd == -1)
+ goto without;
+
+ if ((ocspbuf = relay_load_fd(cert->cert_ocsp_fd,
+    &ocsplen)) == NULL) {
+ log_warn("failed to load ocsp staple");
+ ocsplen = 0;
+ }
+
+ without:
  if (keyfound == 1 &&
     tls_config_set_keypair_ocsp_mem(tls_cfg, buf, len,
-    fake_key, fake_keylen, NULL, 0) != 0) {
+    fake_key, fake_keylen, ocspbuf, ocsplen) != 0) {
  log_warnx("failed to set tls certificate: %s",
     tls_config_error(tls_cfg));
  goto err;
@@ -2223,7 +2233,7 @@ relay_tls_ctx_create(struct relay *rlay)
  goto err;

  if (tls_config_add_keypair_ocsp_mem(tls_cfg, buf, len,
-    fake_key, fake_keylen, NULL, 0) != 0) {
+    fake_key, fake_keylen, ocspbuf, ocsplen) != 0) {
  log_warnx("failed to add tls certificate: %s",
     tls_config_error(tls_cfg));
  goto err;
Index: usr.sbin/relayd/relayd.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.c,v
retrieving revision 1.179
diff -u -p -r1.179 relayd.c
--- usr.sbin/relayd/relayd.c 31 May 2019 15:25:57 -0000 1.179
+++ usr.sbin/relayd/relayd.c 20 Jun 2019 17:37:09 -0000
@@ -1270,6 +1270,7 @@ cert_add(struct relayd *env, objid_t id)
  cert->cert_id = id;
  cert->cert_fd = -1;
  cert->cert_key_fd = -1;
+ cert->cert_ocsp_fd = -1;

  TAILQ_INSERT_TAIL(env->sc_certs, cert, cert_entry);

@@ -1325,7 +1326,7 @@ relay_load_certfiles(struct relayd *env,
  struct protocol *proto = rlay->rl_proto;
  struct relay_cert *cert;
  int useport = htons(rlay->rl_conf.port);
- int cert_fd = -1, key_fd = -1;
+ int cert_fd = -1, key_fd = -1, ocsp_fd = -1;

  if (rlay->rl_conf.flags & F_TLSCLIENT) {
  if (strlen(proto->tlsca) && rlay->rl_tls_ca_fd == -1) {
@@ -1389,12 +1390,32 @@ relay_load_certfiles(struct relayd *env,
  goto fail;
  log_debug("%s: using private key %s", __func__, certfile);

+ if (useport) {
+ if (snprintf(certfile, sizeof(certfile),
+    "/etc/ssl/%s:%u.der", hbuf, useport) == -1)
+ goto add;
+ } else {
+ if (snprintf(certfile, sizeof(certfile),
+    "/etc/ssl/%s.der", hbuf) == -1)
+ goto add;
+ }
+ if (access(certfile, F_OK) == -1)
+ goto add;
+ if ((ocsp_fd = open(certfile, O_RDONLY)) == -1) {
+ log_warn("%s: cannot open ocsp staple file %s", __func__,
+    certfile);
+ goto add;
+ }
+ log_debug("%s: using ocsp staple file %s", __func__, certfile);
+
+ add:
  if ((cert = cert_add(env, 0)) == NULL)
  goto fail;

  cert->cert_relayid = rlay->rl_conf.id;
  cert->cert_fd = cert_fd;
  cert->cert_key_fd = key_fd;
+ cert->cert_ocsp_fd = ocsp_fd;

  return (0);

@@ -1403,6 +1424,8 @@ relay_load_certfiles(struct relayd *env,
  close(cert_fd);
  if (key_fd != -1)
  close(key_fd);
+ if (ocsp_fd != -1)
+ close(ocsp_fd);

  return (-1);
 }
Index: usr.sbin/relayd/relayd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.conf.5,v
retrieving revision 1.190
diff -u -p -r1.190 relayd.conf.5
--- usr.sbin/relayd/relayd.conf.5 31 May 2019 15:25:57 -0000 1.190
+++ usr.sbin/relayd/relayd.conf.5 20 Jun 2019 17:37:09 -0000
@@ -948,20 +948,27 @@ The default is
 .Ic no edh .
 .It Ic keypair Ar name
 The relay will attempt to look up a private key in
-.Pa /etc/ssl/private/name:port.key
-and a public certificate in
+.Pa /etc/ssl/private/name:port.key ,
+a public certificate in
 .Pa /etc/ssl/name:port.crt ,
+and an OCSP reponse for stapling in
+.Pa /etc/ssl/name:port.der ,
 where
 .Ar port
 is the specified port that the relay listens on.
 If these files are not present, the relay will continue to look in
-.Pa /etc/ssl/private/name.key
+.Pa /etc/ssl/private/name.key ,
+.Pa /etc/ssl/name.crt ,
 and
-.Pa /etc/ssl/name.crt .
+.Pa /etc/ssl/name.der .
 This option can be specified multiple times for TLS Server Name Indication.
 If not specified,
 a keypair will be loaded using the specified IP address of the relay as
 .Ar name .
+The OCSP response file is only required if the relay should provide OCSP
+stapling.
+.Xr ocspcheck 8
+can be used to create a staplefile.
 See
 .Xr ssl 8
 for details about SSL/TLS server certificates.
Index: usr.sbin/relayd/relayd.h
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.258
diff -u -p -r1.258 relayd.h
--- usr.sbin/relayd/relayd.h 31 May 2019 15:25:57 -0000 1.258
+++ usr.sbin/relayd/relayd.h 20 Jun 2019 17:37:09 -0000
@@ -141,7 +141,8 @@ enum fd_type {
  RELAY_FD_CERT = 1,
  RELAY_FD_CACERT = 2,
  RELAY_FD_CAFILE = 3,
- RELAY_FD_KEY = 4
+ RELAY_FD_KEY = 4,
+ RELAY_FD_OCSP = 5
 };

 struct ctl_relayfd {
@@ -781,6 +782,7 @@ struct relay_cert {
  objid_t cert_relayid;
  int cert_fd;
  int cert_key_fd;
+ int cert_ocsp_fd;
  EVP_PKEY *cert_pkey;
  TAILQ_ENTRY(relay_cert) cert_entry;
 };

Reply | Threaded
Open this post in threaded view
|

Re: [patch] relayd OCSP stapling for TLS server

Reyk Floeter-2
Hi Bruno,

thanks for your efforts. I‘ve already written an OCSP patch which was being delayed in review.

I don’t have the patch at hand but you can see the branch at https://github.com/reyk/relayd/tree/ocsp

Reyk

> Am 20.06.2019 um 19:58 schrieb Bruno Flueckiger <[hidden email]>:
>
> Hi,
>
> The patch below adds OCSP stapling to the TLS server in relayd(8). The
> OCSP response is read from a binary encoded DER file that can be created
> using ocspcheck(8).
>
> If a file with the same name as the certificate and private key files is
> found, its content is loaded and OCSP stapling is active. If there is no
> file or loading its content fails, OCSP stapling remains disabled.
>
> relayd(8) uses the same mechanism it uses to find the certificate file,
> only the file name extension is different: .der instead of .pem
>
> Cheers,
> Bruno
>
> Index: usr.sbin/relayd/config.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/relayd/config.c,v
> retrieving revision 1.39
> diff -u -p -r1.39 config.c
> --- usr.sbin/relayd/config.c    1 Jun 2019 09:54:19 -0000    1.39
> +++ usr.sbin/relayd/config.c    20 Jun 2019 17:37:09 -0000
> @@ -913,6 +913,14 @@ config_setrelay(struct relayd *env, stru
>                        rlay->rl_conf.name);
>                    return (-1);
>                }
> +                if (cert->cert_ocsp_fd != -1 &&
> +                    config_setrelayfd(ps, id, n,
> +                    cert->cert_id, cert->cert_relayid,
> +                    RELAY_FD_OCSP, cert->cert_ocsp_fd) == -1) {
> +                    log_warn("%s: fd passing failed for "
> +                        "`%s'", __func__,
> +                        rlay->rl_conf.name);
> +                }
>            }
>        }
>
> @@ -992,6 +1000,10 @@ config_setrelay(struct relayd *env, stru
>            close(cert->cert_key_fd);
>            cert->cert_key_fd = -1;
>        }
> +        if (cert->cert_ocsp_fd != -1) {
> +            close(cert->cert_ocsp_fd);
> +            cert->cert_ocsp_fd = -1;
> +        }
>    }
>
>    return (0);
> @@ -1113,6 +1125,7 @@ config_getrelayfd(struct relayd *env, st
>    switch (crfd.type) {
>    case RELAY_FD_CERT:
>    case RELAY_FD_KEY:
> +    case RELAY_FD_OCSP:
>        if ((cert = cert_find(env, crfd.id)) == NULL) {
>            if ((cert = cert_add(env, crfd.id)) == NULL)
>                return (-1);
> @@ -1139,6 +1152,9 @@ config_getrelayfd(struct relayd *env, st
>        break;
>    case RELAY_FD_CAFILE:
>        rlay->rl_tls_cacert_fd = imsg->fd;
> +        break;
> +    case RELAY_FD_OCSP:
> +        cert->cert_ocsp_fd = imsg->fd;
>        break;
>    }
>
> Index: usr.sbin/relayd/relay.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
> retrieving revision 1.247
> diff -u -p -r1.247 relay.c
> --- usr.sbin/relayd/relay.c    31 May 2019 15:15:37 -0000    1.247
> +++ usr.sbin/relayd/relay.c    20 Jun 2019 17:37:09 -0000
> @@ -2130,8 +2130,8 @@ relay_tls_ctx_create(struct relay *rlay)
>    struct relay_cert    *cert;
>    const char        *fake_key;
>    int             fake_keylen, keyfound = 0;
> -    char            *buf = NULL, *cabuf = NULL;
> -    off_t             len = 0, calen = 0;
> +    char            *buf = NULL, *cabuf = NULL, *ocspbuf = NULL;
> +    off_t             len = 0, calen = 0, ocsplen = 0;
>
>    if ((tls_cfg = tls_config_new()) == NULL) {
>        log_warnx("unable to allocate TLS config");
> @@ -2209,9 +2209,19 @@ relay_tls_ctx_create(struct relay *rlay)
>                goto err;
>            }
>
> +            if (cert->cert_ocsp_fd == -1)
> +                goto without;
> +
> +            if ((ocspbuf = relay_load_fd(cert->cert_ocsp_fd,
> +                &ocsplen)) == NULL) {
> +                log_warn("failed to load ocsp staple");
> +                ocsplen = 0;
> +            }
> +
> + without:
>            if (keyfound == 1 &&
>                tls_config_set_keypair_ocsp_mem(tls_cfg, buf, len,
> -                fake_key, fake_keylen, NULL, 0) != 0) {
> +                fake_key, fake_keylen, ocspbuf, ocsplen) != 0) {
>                log_warnx("failed to set tls certificate: %s",
>                    tls_config_error(tls_cfg));
>                goto err;
> @@ -2223,7 +2233,7 @@ relay_tls_ctx_create(struct relay *rlay)
>                goto err;
>
>            if (tls_config_add_keypair_ocsp_mem(tls_cfg, buf, len,
> -                fake_key, fake_keylen, NULL, 0) != 0) {
> +                fake_key, fake_keylen, ocspbuf, ocsplen) != 0) {
>                log_warnx("failed to add tls certificate: %s",
>                    tls_config_error(tls_cfg));
>                goto err;
> Index: usr.sbin/relayd/relayd.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/relayd/relayd.c,v
> retrieving revision 1.179
> diff -u -p -r1.179 relayd.c
> --- usr.sbin/relayd/relayd.c    31 May 2019 15:25:57 -0000    1.179
> +++ usr.sbin/relayd/relayd.c    20 Jun 2019 17:37:09 -0000
> @@ -1270,6 +1270,7 @@ cert_add(struct relayd *env, objid_t id)
>    cert->cert_id = id;
>    cert->cert_fd = -1;
>    cert->cert_key_fd = -1;
> +    cert->cert_ocsp_fd = -1;
>
>    TAILQ_INSERT_TAIL(env->sc_certs, cert, cert_entry);
>
> @@ -1325,7 +1326,7 @@ relay_load_certfiles(struct relayd *env,
>    struct protocol *proto = rlay->rl_proto;
>    struct relay_cert *cert;
>    int     useport = htons(rlay->rl_conf.port);
> -    int     cert_fd = -1, key_fd = -1;
> +    int     cert_fd = -1, key_fd = -1, ocsp_fd = -1;
>
>    if (rlay->rl_conf.flags & F_TLSCLIENT) {
>        if (strlen(proto->tlsca) && rlay->rl_tls_ca_fd == -1) {
> @@ -1389,12 +1390,32 @@ relay_load_certfiles(struct relayd *env,
>        goto fail;
>    log_debug("%s: using private key %s", __func__, certfile);
>
> +    if (useport) {
> +        if (snprintf(certfile, sizeof(certfile),
> +            "/etc/ssl/%s:%u.der", hbuf, useport) == -1)
> +            goto add;
> +    } else {
> +        if (snprintf(certfile, sizeof(certfile),
> +            "/etc/ssl/%s.der", hbuf) == -1)
> +            goto add;
> +    }
> +    if (access(certfile, F_OK) == -1)
> +        goto add;
> +    if ((ocsp_fd = open(certfile, O_RDONLY)) == -1) {
> +        log_warn("%s: cannot open ocsp staple file %s", __func__,
> +            certfile);
> +        goto add;
> +    }
> +    log_debug("%s: using ocsp staple file %s", __func__, certfile);
> +
> + add:
>    if ((cert = cert_add(env, 0)) == NULL)
>        goto fail;
>
>    cert->cert_relayid = rlay->rl_conf.id;
>    cert->cert_fd = cert_fd;
>    cert->cert_key_fd = key_fd;
> +    cert->cert_ocsp_fd = ocsp_fd;
>
>    return (0);
>
> @@ -1403,6 +1424,8 @@ relay_load_certfiles(struct relayd *env,
>        close(cert_fd);
>    if (key_fd != -1)
>        close(key_fd);
> +    if (ocsp_fd != -1)
> +        close(ocsp_fd);
>
>    return (-1);
> }
> Index: usr.sbin/relayd/relayd.conf.5
> ===================================================================
> RCS file: /cvs/src/usr.sbin/relayd/relayd.conf.5,v
> retrieving revision 1.190
> diff -u -p -r1.190 relayd.conf.5
> --- usr.sbin/relayd/relayd.conf.5    31 May 2019 15:25:57 -0000    1.190
> +++ usr.sbin/relayd/relayd.conf.5    20 Jun 2019 17:37:09 -0000
> @@ -948,20 +948,27 @@ The default is
> .Ic no edh .
> .It Ic keypair Ar name
> The relay will attempt to look up a private key in
> -.Pa /etc/ssl/private/name:port.key
> -and a public certificate in
> +.Pa /etc/ssl/private/name:port.key ,
> +a public certificate in
> .Pa /etc/ssl/name:port.crt ,
> +and an OCSP reponse for stapling in
> +.Pa /etc/ssl/name:port.der ,
> where
> .Ar port
> is the specified port that the relay listens on.
> If these files are not present, the relay will continue to look in
> -.Pa /etc/ssl/private/name.key
> +.Pa /etc/ssl/private/name.key ,
> +.Pa /etc/ssl/name.crt ,
> and
> -.Pa /etc/ssl/name.crt .
> +.Pa /etc/ssl/name.der .
> This option can be specified multiple times for TLS Server Name Indication.
> If not specified,
> a keypair will be loaded using the specified IP address of the relay as
> .Ar name .
> +The OCSP response file is only required if the relay should provide OCSP
> +stapling.
> +.Xr ocspcheck 8
> +can be used to create a staplefile.
> See
> .Xr ssl 8
> for details about SSL/TLS server certificates.
> Index: usr.sbin/relayd/relayd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
> retrieving revision 1.258
> diff -u -p -r1.258 relayd.h
> --- usr.sbin/relayd/relayd.h    31 May 2019 15:25:57 -0000    1.258
> +++ usr.sbin/relayd/relayd.h    20 Jun 2019 17:37:09 -0000
> @@ -141,7 +141,8 @@ enum fd_type {
>    RELAY_FD_CERT    = 1,
>    RELAY_FD_CACERT    = 2,
>    RELAY_FD_CAFILE    = 3,
> -    RELAY_FD_KEY    = 4
> +    RELAY_FD_KEY    = 4,
> +    RELAY_FD_OCSP    = 5
> };
>
> struct ctl_relayfd {
> @@ -781,6 +782,7 @@ struct relay_cert {
>    objid_t             cert_relayid;
>    int             cert_fd;
>    int             cert_key_fd;
> +    int             cert_ocsp_fd;
>    EVP_PKEY        *cert_pkey;
>    TAILQ_ENTRY(relay_cert)     cert_entry;
> };
>
Reply | Threaded
Open this post in threaded view
|

Re: [patch] relayd OCSP stapling for TLS server

Reyk Floeter-2
In reply to this post by Bruno Flueckiger
On Thu, Jun 20, 2019 at 07:58:10PM +0200, Bruno Flueckiger wrote:

> Hi,
>
> The patch below adds OCSP stapling to the TLS server in relayd(8). The
> OCSP response is read from a binary encoded DER file that can be created
> using ocspcheck(8).
>
> If a file with the same name as the certificate and private key files is
> found, its content is loaded and OCSP stapling is active. If there is no
> file or loading its content fails, OCSP stapling remains disabled.
>
> relayd(8) uses the same mechanism it uses to find the certificate file,
> only the file name extension is different: .der instead of .pem
>

I had this diff finished more than a month ago, but it had to wait for
the SNI diff to go in.  It is suprisingly similar to your version
except some minor difference in relay_tls_ctx_create(), the man page,
and the fact that I've decided for using ".ocsp" instead of ".der" for
the ending (as .der could be anything).

OK?

Reyk

Index: usr.sbin/relayd/config.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/config.c,v
retrieving revision 1.39
diff -u -p -u -p -r1.39 config.c
--- usr.sbin/relayd/config.c 1 Jun 2019 09:54:19 -0000 1.39
+++ usr.sbin/relayd/config.c 21 Jun 2019 11:11:05 -0000
@@ -903,6 +903,16 @@ config_setrelay(struct relayd *env, stru
     rlay->rl_conf.name);
  return (-1);
  }
+ if (id == PROC_RELAY &&
+    cert->cert_ocsp_fd != -1 &&
+    config_setrelayfd(ps, id, n,
+    cert->cert_id, cert->cert_relayid,
+    RELAY_FD_OCSP, cert->cert_ocsp_fd) == -1) {
+ log_warn("%s: fd passing failed for "
+    "`%s'", __func__,
+    rlay->rl_conf.name);
+ return (-1);
+ }
  if (id == PROC_CA &&
     cert->cert_key_fd != -1 &&
     config_setrelayfd(ps, id, n,
@@ -992,6 +1002,10 @@ config_setrelay(struct relayd *env, stru
  close(cert->cert_key_fd);
  cert->cert_key_fd = -1;
  }
+ if (cert->cert_ocsp_fd != -1) {
+ close(cert->cert_ocsp_fd);
+ cert->cert_ocsp_fd = -1;
+ }
  }
 
  return (0);
@@ -1113,6 +1127,7 @@ config_getrelayfd(struct relayd *env, st
  switch (crfd.type) {
  case RELAY_FD_CERT:
  case RELAY_FD_KEY:
+ case RELAY_FD_OCSP:
  if ((cert = cert_find(env, crfd.id)) == NULL) {
  if ((cert = cert_add(env, crfd.id)) == NULL)
  return (-1);
@@ -1133,6 +1148,9 @@ config_getrelayfd(struct relayd *env, st
  break;
  case RELAY_FD_KEY:
  cert->cert_key_fd = imsg->fd;
+ break;
+ case RELAY_FD_OCSP:
+ cert->cert_ocsp_fd = imsg->fd;
  break;
  case RELAY_FD_CACERT:
  rlay->rl_tls_ca_fd = imsg->fd;
Index: usr.sbin/relayd/relay.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.247
diff -u -p -u -p -r1.247 relay.c
--- usr.sbin/relayd/relay.c 31 May 2019 15:15:37 -0000 1.247
+++ usr.sbin/relayd/relay.c 21 Jun 2019 11:11:06 -0000
@@ -2130,8 +2130,8 @@ relay_tls_ctx_create(struct relay *rlay)
  struct relay_cert *cert;
  const char *fake_key;
  int fake_keylen, keyfound = 0;
- char *buf = NULL, *cabuf = NULL;
- off_t len = 0, calen = 0;
+ char *buf = NULL, *cabuf = NULL, *ocspbuf = NULL;
+ off_t len = 0, calen = 0, ocsplen = 0;
 
  if ((tls_cfg = tls_config_new()) == NULL) {
  log_warnx("unable to allocate TLS config");
@@ -2203,6 +2203,16 @@ relay_tls_ctx_create(struct relay *rlay)
  }
  cert->cert_fd = -1;
 
+ if (cert->cert_ocsp_fd != -1 &&
+    (ocspbuf = relay_load_fd(cert->cert_ocsp_fd,
+    &ocsplen)) == NULL) {
+ log_warn("failed to load OCSP staplefile");
+ goto err;
+ }
+ if (ocsplen == 0)
+ purge_key(&ocspbuf, ocsplen);
+ cert->cert_ocsp_fd = -1;
+
  if ((fake_keylen = ssl_ctx_fake_private_key(buf, len,
     &fake_key)) == -1) {
  /* error already printed */
@@ -2211,7 +2221,7 @@ relay_tls_ctx_create(struct relay *rlay)
 
  if (keyfound == 1 &&
     tls_config_set_keypair_ocsp_mem(tls_cfg, buf, len,
-    fake_key, fake_keylen, NULL, 0) != 0) {
+    fake_key, fake_keylen, ocspbuf, ocsplen) != 0) {
  log_warnx("failed to set tls certificate: %s",
     tls_config_error(tls_cfg));
  goto err;
@@ -2223,13 +2233,14 @@ relay_tls_ctx_create(struct relay *rlay)
  goto err;
 
  if (tls_config_add_keypair_ocsp_mem(tls_cfg, buf, len,
-    fake_key, fake_keylen, NULL, 0) != 0) {
+    fake_key, fake_keylen, ocspbuf, ocsplen) != 0) {
  log_warnx("failed to add tls certificate: %s",
     tls_config_error(tls_cfg));
  goto err;
  }
 
  purge_key(&buf, len);
+ purge_key(&ocspbuf, ocsplen);
  }
 
  if (rlay->rl_tls_cacert_fd != -1) {
@@ -2269,6 +2280,7 @@ relay_tls_ctx_create(struct relay *rlay)
 
  return (0);
  err:
+ purge_key(&ocspbuf, ocsplen);
  purge_key(&cabuf, calen);
  purge_key(&buf, len);
 
Index: usr.sbin/relayd/relayd.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.c,v
retrieving revision 1.179
diff -u -p -u -p -r1.179 relayd.c
--- usr.sbin/relayd/relayd.c 31 May 2019 15:25:57 -0000 1.179
+++ usr.sbin/relayd/relayd.c 21 Jun 2019 11:11:06 -0000
@@ -605,6 +605,8 @@ purge_relay(struct relayd *env, struct r
  close(cert->cert_fd);
  if (cert->cert_key_fd != -1)
  close(cert->cert_key_fd);
+ if (cert->cert_ocsp_fd != -1)
+ close(cert->cert_ocsp_fd);
  if (cert->cert_pkey != NULL)
  EVP_PKEY_free(cert->cert_pkey);
  TAILQ_REMOVE(env->sc_certs, cert, cert_entry);
@@ -1270,6 +1272,7 @@ cert_add(struct relayd *env, objid_t id)
  cert->cert_id = id;
  cert->cert_fd = -1;
  cert->cert_key_fd = -1;
+ cert->cert_ocsp_fd = -1;
 
  TAILQ_INSERT_TAIL(env->sc_certs, cert, cert_entry);
 
@@ -1325,7 +1328,7 @@ relay_load_certfiles(struct relayd *env,
  struct protocol *proto = rlay->rl_proto;
  struct relay_cert *cert;
  int useport = htons(rlay->rl_conf.port);
- int cert_fd = -1, key_fd = -1;
+ int cert_fd = -1, key_fd = -1, ocsp_fd = -1;
 
  if (rlay->rl_conf.flags & F_TLSCLIENT) {
  if (strlen(proto->tlsca) && rlay->rl_tls_ca_fd == -1) {
@@ -1389,12 +1392,25 @@ relay_load_certfiles(struct relayd *env,
  goto fail;
  log_debug("%s: using private key %s", __func__, certfile);
 
+ if (useport) {
+ if (snprintf(certfile, sizeof(certfile),
+    "/etc/ssl/%s:%u.ocsp", hbuf, useport) == -1)
+ goto fail;
+ } else {
+ if (snprintf(certfile, sizeof(certfile),
+    "/etc/ssl/%s.ocsp", hbuf) == -1)
+ goto fail;
+ }
+ if ((ocsp_fd = open(certfile, O_RDONLY)) != -1)
+ log_debug("%s: using OCSP staple file %s", __func__, certfile);
+
  if ((cert = cert_add(env, 0)) == NULL)
  goto fail;
 
  cert->cert_relayid = rlay->rl_conf.id;
  cert->cert_fd = cert_fd;
  cert->cert_key_fd = key_fd;
+ cert->cert_ocsp_fd = ocsp_fd;
 
  return (0);
 
@@ -1403,6 +1419,8 @@ relay_load_certfiles(struct relayd *env,
  close(cert_fd);
  if (key_fd != -1)
  close(key_fd);
+ if (ocsp_fd != -1)
+ close(ocsp_fd);
 
  return (-1);
 }
Index: usr.sbin/relayd/relayd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.conf.5,v
retrieving revision 1.190
diff -u -p -u -p -r1.190 relayd.conf.5
--- usr.sbin/relayd/relayd.conf.5 31 May 2019 15:25:57 -0000 1.190
+++ usr.sbin/relayd/relayd.conf.5 21 Jun 2019 11:11:07 -0000
@@ -965,6 +965,15 @@ a keypair will be loaded using the speci
 See
 .Xr ssl 8
 for details about SSL/TLS server certificates.
+.Pp
+An optional OCSP staple file will be used during TLS handshakes with
+this server if it is found as a non-empty file in
+.Pa /etc/ssl/name:port.ocsp
+or
+.Pa /etc/ssl/name.ocsp .
+The file should contain a DER-format OCSP response retrieved from an
+OCSP server for the certificate in use, and can be created using
+ocspcheck(8).
 .It Ic no cipher-server-preference
 Prefer the client's cipher list over the server's preferences when
 choosing a cipher for the connection.
@@ -1594,6 +1603,7 @@ router "uplinks" {
 }
 .Ed
 .Sh SEE ALSO
+.Xr ocspcheck 8 ,
 .Xr relayctl 8 ,
 .Xr relayd 8 ,
 .Xr snmpd 8 ,
Index: usr.sbin/relayd/relayd.h
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.258
diff -u -p -u -p -r1.258 relayd.h
--- usr.sbin/relayd/relayd.h 31 May 2019 15:25:57 -0000 1.258
+++ usr.sbin/relayd/relayd.h 21 Jun 2019 11:11:07 -0000
@@ -141,7 +141,8 @@ enum fd_type {
  RELAY_FD_CERT = 1,
  RELAY_FD_CACERT = 2,
  RELAY_FD_CAFILE = 3,
- RELAY_FD_KEY = 4
+ RELAY_FD_KEY = 4,
+ RELAY_FD_OCSP = 5
 };
 
 struct ctl_relayfd {
@@ -781,6 +782,7 @@ struct relay_cert {
  objid_t cert_relayid;
  int cert_fd;
  int cert_key_fd;
+ int cert_ocsp_fd;
  EVP_PKEY *cert_pkey;
  TAILQ_ENTRY(relay_cert) cert_entry;
 };

Reply | Threaded
Open this post in threaded view
|

Re: [patch] relayd OCSP stapling for TLS server

Theo Buehler-3
On Fri, Jun 21, 2019 at 01:28:03PM +0200, Reyk Floeter wrote:

> On Thu, Jun 20, 2019 at 07:58:10PM +0200, Bruno Flueckiger wrote:
> > Hi,
> >
> > The patch below adds OCSP stapling to the TLS server in relayd(8). The
> > OCSP response is read from a binary encoded DER file that can be created
> > using ocspcheck(8).
> >
> > If a file with the same name as the certificate and private key files is
> > found, its content is loaded and OCSP stapling is active. If there is no
> > file or loading its content fails, OCSP stapling remains disabled.
> >
> > relayd(8) uses the same mechanism it uses to find the certificate file,
> > only the file name extension is different: .der instead of .pem
> >
>
> I had this diff finished more than a month ago, but it had to wait for
> the SNI diff to go in.  It is suprisingly similar to your version
> except some minor difference in relay_tls_ctx_create(), the man page,
> and the fact that I've decided for using ".ocsp" instead of ".der" for
> the ending (as .der could be anything).
>
> OK?

Reads fine. Would be nice to hear that this works for Bruno, but it is

ok tb

Reply | Threaded
Open this post in threaded view
|

Re: [patch] relayd OCSP stapling for TLS server

Bruno Flueckiger
On 22.06., Theo Buehler wrote:

> On Fri, Jun 21, 2019 at 01:28:03PM +0200, Reyk Floeter wrote:
> > On Thu, Jun 20, 2019 at 07:58:10PM +0200, Bruno Flueckiger wrote:
> > > Hi,
> > >
> > > The patch below adds OCSP stapling to the TLS server in relayd(8). The
> > > OCSP response is read from a binary encoded DER file that can be created
> > > using ocspcheck(8).
> > >
> > > If a file with the same name as the certificate and private key files is
> > > found, its content is loaded and OCSP stapling is active. If there is no
> > > file or loading its content fails, OCSP stapling remains disabled.
> > >
> > > relayd(8) uses the same mechanism it uses to find the certificate file,
> > > only the file name extension is different: .der instead of .pem
> > >
> >
> > I had this diff finished more than a month ago, but it had to wait for
> > the SNI diff to go in.  It is suprisingly similar to your version
> > except some minor difference in relay_tls_ctx_create(), the man page,
> > and the fact that I've decided for using ".ocsp" instead of ".der" for
> > the ending (as .der could be anything).
> >
> > OK?
>
> Reads fine. Would be nice to hear that this works for Bruno, but it is
>
> ok tb
>

I like ".ocsp" better than ".der". And I'm a bit proud that my diff
turns out to be good, although late :-). It works for me.

Bruno