Hi Jack,

On Fri, Jul 21, 2017 at 06:33:43PM +0930, Jack Burton wrote:
> Thoughts?

I've tested your diff.  The main feature looks fine to me.  TLS
connections with and with out Clients certs, as well as with and without
certificate revocation lists seams to work.  Also, the tests are
passing.

But, I found a bug in the part of the FastCGI variables.  The following
condition is always false.

> Index: usr.sbin/httpd/server_fcgi.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/httpd/server_fcgi.c,v
> retrieving revision 1.74
> diff -u -p -r1.74 server_fcgi.c
> --- usr.sbin/httpd/server_fcgi.c      21 Jan 2017 11:32:04 -0000      1.74
> +++ usr.sbin/httpd/server_fcgi.c      21 Jul 2017 08:25:57 -0000
> @@ -282,11 +283,57 @@ server_fcgi(struct httpd *env, struct cl
...
> +             if (srv_conf->tls_ca != NULL) {
...

It has to be replaced with the following condition:

+               if (clt->clt_srv->srv_conf.tls_ca != NULL) {

To make this working I have to change two void pointers by more specific
types.  Below, you find the whole diff:

bye,
Jan

Index: regress/usr.sbin/httpd/tests/Client.pm
===================================================================
RCS file: /mount/openbsd/cvs/src/regress/usr.sbin/httpd/tests/Client.pm,v
retrieving revision 1.1
diff -u -p -r1.1 Client.pm
--- regress/usr.sbin/httpd/tests/Client.pm      16 Jul 2015 16:35:57 -0000      
1.1
+++ regress/usr.sbin/httpd/tests/Client.pm      21 Jul 2017 11:20:24 -0000
@@ -59,6 +59,11 @@ sub child {
            PeerAddr            => $self->{connectaddr},
            PeerPort            => $self->{connectport},
            SSL_verify_mode     => SSL_VERIFY_NONE,
+           SSL_use_cert        => $self->{offertlscert} ? 1 : 0,
+           SSL_cert_file       => $self->{offertlscert} ?
+                                       $self->{chroot}."/client.crt" : "",
+           SSL_key_file        => $self->{offertlscert} ?
+                                       $self->{chroot}."/client.key" : "",
        ) or die ref($self), " $iosocket socket connect failed: $!,$SSL_ERROR";
        print STDERR "connect sock: ",$cs->sockhost()," ",$cs->sockport(),"\n";
        print STDERR "connect peer: ",$cs->peerhost()," ",$cs->peerport(),"\n";
Index: regress/usr.sbin/httpd/tests/Httpd.pm
===================================================================
RCS file: /mount/openbsd/cvs/src/regress/usr.sbin/httpd/tests/Httpd.pm,v
retrieving revision 1.2
diff -u -p -r1.2 Httpd.pm
--- regress/usr.sbin/httpd/tests/Httpd.pm       30 Jan 2017 21:18:24 -0000      
1.2
+++ regress/usr.sbin/httpd/tests/Httpd.pm       21 Jul 2017 11:20:24 -0000
@@ -72,6 +72,8 @@ sub new {
            print $fh "\n";
            print $fh "\ttls certificate \"".$args{chroot}."/server.crt\"\n";
            print $fh "\ttls key \"".$args{chroot}."/server.key\"";
+           $self->{verifytls}
+               and print $fh "\ntls client ca \"".$args{chroot}."/ca.crt\"";
        }
        print $fh "\n\troot \"/\"";
        print $fh "\n\tlog style combined";
Index: regress/usr.sbin/httpd/tests/Makefile
===================================================================
RCS file: /mount/openbsd/cvs/src/regress/usr.sbin/httpd/tests/Makefile,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile
--- regress/usr.sbin/httpd/tests/Makefile       14 Jul 2017 13:31:44 -0000      
1.8
+++ regress/usr.sbin/httpd/tests/Makefile       21 Jul 2017 11:20:24 -0000
@@ -77,10 +77,16 @@ ca.crt:
 server.req:
        openssl req -batch -new -subj 
/L=OpenBSD/O=httpd-regress/OU=server/CN=localhost/ -nodes -newkey rsa -keyout 
server.key -out server.req
 
+client.req:
+       openssl req -batch -new -subj 
/L=OpenBSD/O=httpd-regress/OU=client/CN=localhost/ -nodes -newkey rsa -keyout 
client.key -out $@
+
 server.crt: ca.crt server.req
        openssl x509 -CAcreateserial -CAkey ca.key -CA ca.crt -req -in 
server.req -out server.crt
 
-${REGRESS_TARGETS:M*tls*} ${REGRESS_TARGETS:M*https*}: server.crt
+client.crt: ca.crt client.req
+       openssl x509 -CAcreateserial -CAkey ca.key -CA ca.crt -req -in 
client.req -out $@
+
+${REGRESS_TARGETS:M*tls*} ${REGRESS_TARGETS:M*https*}: server.crt client.crt
 
 # make perl syntax check for all args files
 
Index: usr.sbin/httpd/config.c
===================================================================
RCS file: /mount/openbsd/cvs/src/usr.sbin/httpd/config.c,v
retrieving revision 1.53
diff -u -p -r1.53 config.c
--- usr.sbin/httpd/config.c     19 Jul 2017 17:36:25 -0000      1.53
+++ usr.sbin/httpd/config.c     21 Jul 2017 11:20:24 -0000
@@ -304,10 +304,18 @@ config_setserver_tls(struct httpd *env, 
 
        log_debug("%s: configuring tls for %s", __func__, srv_conf->name);
 
+       if (config_settls(env, srv, TLS_CFG_CA, "ca", srv_conf->tls_ca,
+           srv_conf->tls_ca_len) != 0)
+               return (-1);
+
        if (config_settls(env, srv, TLS_CFG_CERT, "cert", srv_conf->tls_cert,
            srv_conf->tls_cert_len) != 0)
                return (-1);
 
+       if (config_settls(env, srv, TLS_CFG_CRL, "crl", srv_conf->tls_crl,
+           srv_conf->tls_crl_len) != 0)
+               return (-1);
+
        if (config_settls(env, srv, TLS_CFG_KEY, "key", srv_conf->tls_key,
            srv_conf->tls_key_len) != 0)
                return (-1);
@@ -655,9 +663,21 @@ config_getserver_tls(struct httpd *env, 
        }
 
        switch (tls_conf.tls_type) {
+       case TLS_CFG_CA:
+               if (config_gettls(env, srv_conf, &tls_conf, "ca", p, len,
+                   &srv_conf->tls_ca, &srv_conf->tls_ca_len) != 0)
+                       goto fail;
+               break;
+
        case TLS_CFG_CERT:
                if (config_gettls(env, srv_conf, &tls_conf, "cert", p, len,
                    &srv_conf->tls_cert, &srv_conf->tls_cert_len) != 0)
+                       goto fail;
+               break;
+
+       case TLS_CFG_CRL:
+               if (config_gettls(env, srv_conf, &tls_conf, "crl", p, len,
+                   &srv_conf->tls_crl, &srv_conf->tls_crl_len) != 0)
                        goto fail;
                break;
 
Index: usr.sbin/httpd/httpd.conf.5
===================================================================
RCS file: /mount/openbsd/cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.82
diff -u -p -r1.82 httpd.conf.5
--- usr.sbin/httpd/httpd.conf.5 9 Apr 2017 09:13:28 -0000       1.82
+++ usr.sbin/httpd/httpd.conf.5 21 Jul 2017 11:20:24 -0000
@@ -342,6 +342,28 @@ The revision of the HTTP specification u
 .It Ic SERVER_SOFTWARE
 The server software name of
 .Xr httpd 8 .
+.It Ic TLS_PEER_CHAIN
+The TLS client certificate chain, if any, PEM encoded, with
+newlines translated to tabs.
+.It Ic TLS_PEER_CRL
+A variable that is set to
+.Qq on
+when the server has been configured to check the client certificate chain
+against CRL(s).
+This variable is omitted otherwise.
+.It Ic TLS_PEER_EXPIRES
+The time at which the TLS cient certificate, if any, expires,
+in seconds since the epoch.
+.It Ic TLS_PEER_HASH
+A hash of the TLS client certificate, if any.
+See
+.Xr tls_peer_cert_hash 3 .
+.It Ic TLS_PEER_ISSUER
+The issuer of the TLS client certificate, if any.
+.It Ic TLS_PEER_OCSP_URL
+The OCSP URL from the TLS client certificate, if any.
+.It Ic TLS_PEER_SUBJECT
+The subject of the TLS client certificate, if any.
 .El
 .It Ic hsts Oo Ar option Oc
 Enable HTTP Strict Transport Security.
@@ -526,6 +548,17 @@ will be used (strong crypto cipher suite
 See the CIPHERS section of
 .Xr openssl 1
 for information about SSL/TLS cipher suites and preference lists.
+.It Ic client ca Ar cafile Op Ic crl Ar crlfile
+Require TLS client certificates whose authenticity can be verified
+against the CA certificate(s) in
+.Ar cafile
+in order to proceed beyond the TLS handshake.
+With
+.Ic crl
+specified, additionally require that no certificate in the client chain be
+listed as revoked in the CRL(s) in
+.Ar crlfile .
+CA certificates and CRLs should be PEM encoded.
 .It Ic dhe Ar params
 Specify the DHE parameters to use for DHE cipher suites.
 Valid parameter values are none, legacy and auto.
@@ -688,6 +721,7 @@ server "www.example.com" {
 .Ed
 .Sh SEE ALSO
 .Xr htpasswd 1 ,
+.Xr tls_peer_cert_hash 3 ,
 .Xr patterns 7 ,
 .Xr httpd 8 ,
 .Xr ocspcheck 8 ,
Index: usr.sbin/httpd/httpd.h
===================================================================
RCS file: /mount/openbsd/cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.133
diff -u -p -r1.133 httpd.h
--- usr.sbin/httpd/httpd.h      19 Jul 2017 17:36:25 -0000      1.133
+++ usr.sbin/httpd/httpd.h      27 Jul 2017 08:52:47 -0000
@@ -324,8 +324,8 @@ struct range_data {
 struct client {
        uint32_t                 clt_id;
        pid_t                    clt_pid;
-       void                    *clt_srv;
-       void                    *clt_srv_conf;
+       struct server           *clt_srv;
+       struct server_config    *clt_srv_conf;
        uint32_t                 clt_srv_id;
        struct sockaddr_storage  clt_srv_ss;
        struct str_match         clt_srv_match;
@@ -476,9 +476,15 @@ struct server_config {
        uint32_t                 maxrequests;
        size_t                   maxrequestbody;
 
+       uint8_t                 *tls_ca;
+       char                    *tls_ca_file;
+       size_t                   tls_ca_len;
        uint8_t                 *tls_cert;
        size_t                   tls_cert_len;
        char                    *tls_cert_file;
+       uint8_t                 *tls_crl;
+       char                    *tls_crl_file;
+       size_t                   tls_crl_len;
        char                     tls_ciphers[NAME_MAX];
        char                     tls_dhe_params[NAME_MAX];
        char                     tls_ecdhe_curve[NAME_MAX];
@@ -520,7 +526,9 @@ struct server_config {
 TAILQ_HEAD(serverhosts, server_config);
 
 enum tls_config_type {
+       TLS_CFG_CA,
        TLS_CFG_CERT,
+       TLS_CFG_CRL,
        TLS_CFG_KEY,
        TLS_CFG_OCSP_STAPLE,
 };
@@ -594,6 +602,8 @@ int  cmdline_symset(char *);
 /* server.c */
 void    server(struct privsep *, struct privsep_proc *);
 int     server_tls_cmp(struct server *, struct server *, int);
+int     server_tls_load_ca(struct server *);
+int     server_tls_load_crl(struct server *);
 int     server_tls_load_keypair(struct server *);
 int     server_tls_load_ocsp(struct server *);
 void    server_generate_ticket_key(struct server_config *);
Index: usr.sbin/httpd/parse.y
===================================================================
RCS file: /mount/openbsd/cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.90
diff -u -p -r1.90 parse.y
--- usr.sbin/httpd/parse.y      25 Mar 2017 17:25:34 -0000      1.90
+++ usr.sbin/httpd/parse.y      21 Jul 2017 11:20:24 -0000
@@ -135,6 +135,7 @@ typedef struct {
 %token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET
 %token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
 %token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS
+%token CA CLIENT CRL
 %token <v.string>      STRING
 %token  <v.number>     NUMBER
 %type  <v.port>        port
@@ -344,6 +345,22 @@ server             : SERVER optmatch STRING        {
                                YYERROR;
                        }
 
+                       if (server_tls_load_ca(srv) == -1) {
+                               yyerror("server \"%s\": failed to load "
+                                   "ca cert(s)", srv->srv_conf.name);
+                               serverconfig_free(srv_conf);
+                               free(srv);
+                               YYERROR;
+                       }
+
+                       if (server_tls_load_crl(srv) == -1) {
+                               yyerror("server \"%s\": failed to load crl(s)",
+                                   srv->srv_conf.name);
+                               serverconfig_free(srv_conf);
+                               free(srv);
+                               YYERROR;
+                       }
+
                        if (server_tls_load_ocsp(srv) == -1) {
                                yyerror("server \"%s\": failed to load "
                                    "ocsp staple", srv->srv_conf.name);
@@ -737,6 +754,12 @@ tlsopts            : CERTIFICATE STRING            {
                        }
                        free($2);
                }
+               | CLIENT CA STRING tlsclientopt {
+                       free(srv_conf->tls_ca_file);
+                       if ((srv_conf->tls_ca_file = strdup($3)) == NULL)
+                               fatal("out of memory");
+                       free($3);
+               }
                | DHE STRING                    {
                        if (strlcpy(srv_conf->tls_dhe_params, $2,
                            sizeof(srv_conf->tls_dhe_params)) >=
@@ -785,6 +808,14 @@ tlsopts            : CERTIFICATE STRING            {
                }
                ;
 
+tlsclientopt   : /* empty */
+               | CRL STRING    {
+                       free(srv_conf->tls_crl_file);
+                       if ((srv_conf->tls_crl_file = strdup($2)) == NULL)
+                               fatal("out of memory");
+                       free($2);
+               }
+
 root           : ROOT rootflags
                | ROOT '{' optnl rootflags_l '}'
                ;
@@ -1217,12 +1248,15 @@ lookup(char *s)
                { "block",              BLOCK },
                { "body",               BODY },
                { "buffer",             BUFFER },
+               { "ca",                 CA },
                { "certificate",        CERTIFICATE },
                { "chroot",             CHROOT },
                { "ciphers",            CIPHERS },
+               { "client",             CLIENT },
                { "combined",           COMBINED },
                { "common",             COMMON },
                { "connection",         CONNECTION },
+               { "crl",                CRL },
                { "default",            DEFAULT },
                { "dhe",                DHE },
                { "directory",          DIRECTORY },
@@ -2049,6 +2083,15 @@ server_inherit(struct server *src, struc
        if ((dst->srv_conf.tls_key_file =
            strdup(src->srv_conf.tls_key_file)) == NULL)
                fatal("out of memory");
+       if (src->srv_conf.tls_ca_file != NULL) {
+               if ((dst->srv_conf.tls_ca_file =
+                   strdup(src->srv_conf.tls_ca_file)) == NULL)
+                       fatal("out of memory");
+               if (src->srv_conf.tls_crl_file != NULL &&
+                   (dst->srv_conf.tls_crl_file =
+                   strdup(src->srv_conf.tls_crl_file)) == NULL)
+                       fatal("out of memory");
+       }
        if (src->srv_conf.tls_ocsp_staple_file != NULL) {
                if ((dst->srv_conf.tls_ocsp_staple_file =
                    strdup(src->srv_conf.tls_ocsp_staple_file)) == NULL)
@@ -2087,6 +2130,22 @@ server_inherit(struct server *src, struc
 
        if (server_tls_load_keypair(dst) == -1) {
                yyerror("failed to load public/private keys "
+                   "for server %s", dst->srv_conf.name);
+               serverconfig_free(&dst->srv_conf);
+               free(dst);
+               return (NULL);
+       }
+
+       if (server_tls_load_ca(dst) == -1) {
+               yyerror("failed to load ca cert(s) "
+                   "for server %s", dst->srv_conf.name);
+               serverconfig_free(&dst->srv_conf);
+               free(dst);
+               return (NULL);
+       }
+
+       if (server_tls_load_crl(dst) == -1) {
+               yyerror("failed to load crl(s) "
                    "for server %s", dst->srv_conf.name);
                serverconfig_free(&dst->srv_conf);
                free(dst);
Index: usr.sbin/httpd/server.c
===================================================================
RCS file: /mount/openbsd/cvs/src/usr.sbin/httpd/server.c,v
retrieving revision 1.110
diff -u -p -r1.110 server.c
--- usr.sbin/httpd/server.c     19 Jul 2017 17:36:25 -0000      1.110
+++ usr.sbin/httpd/server.c     21 Jul 2017 11:20:24 -0000
@@ -197,6 +197,40 @@ server_tls_load_ocsp(struct server *srv)
 }
 
 int
+server_tls_load_ca(struct server *srv)
+{
+       if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0 ||
+           srv->srv_conf.tls_ca_file == NULL)
+               return (0);
+
+       if ((srv->srv_conf.tls_ca = tls_load_file(
+           srv->srv_conf.tls_ca_file,
+           &srv->srv_conf.tls_ca_len, NULL)) == NULL)
+               return (-1);
+       log_debug("%s: using ca cert(s) from %s", __func__,
+           srv->srv_conf.tls_ca_file);
+
+       return (0);
+}
+
+int
+server_tls_load_crl(struct server *srv)
+{
+       if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0 ||
+           srv->srv_conf.tls_crl_file == NULL)
+               return (0);
+
+       if ((srv->srv_conf.tls_crl = tls_load_file(
+           srv->srv_conf.tls_crl_file,
+           &srv->srv_conf.tls_crl_len, NULL)) == NULL)
+               return (-1);
+       log_debug("%s: using crl(s) from %s", __func__,
+           srv->srv_conf.tls_crl_file);
+
+       return (0);
+}
+
+int
 server_tls_init(struct server *srv)
 {
        struct server_config *srv_conf;
@@ -254,6 +288,24 @@ server_tls_init(struct server *srv)
                return (-1);
        }
 
+       if (srv->srv_conf.tls_ca != NULL) {
+               if (tls_config_set_ca_mem(srv->srv_tls_config,
+                   srv->srv_conf.tls_ca, srv->srv_conf.tls_ca_len) != 0) {
+                       log_warnx("%s: failed to add ca cert(s)", __func__);
+                       return (-1);
+               }
+               tls_config_verify_client(srv->srv_tls_config);
+
+               if (srv->srv_conf.tls_crl != NULL) {
+                       if (tls_config_set_crl_mem(srv->srv_tls_config,
+                           srv->srv_conf.tls_crl,
+                           srv->srv_conf.tls_crl_len) != 0) {
+                               log_warnx("%s: failed to add crl(s)", __func__);
+                               return (-1);
+                       }
+               }
+       }
+
        TAILQ_FOREACH(srv_conf, &srv->srv_hosts, entry) {
                if (srv_conf->tls_cert == NULL || srv_conf->tls_key == NULL)
                        continue;
@@ -267,6 +319,28 @@ server_tls_init(struct server *srv)
                        log_warnx("%s: failed to add tls keypair", __func__);
                        return (-1);
                }
+
+               if (srv->srv_conf.tls_ca == NULL)
+                       continue;
+
+               log_debug("%s: adding ca cert(s) for server %s", __func__,
+                   srv->srv_conf.name);
+               if (tls_config_set_ca_mem(srv->srv_tls_config,
+                   srv_conf->tls_ca, srv_conf->tls_ca_len) != 0) {
+                       log_warnx("%s: failed to add ca cert(s)", __func__);
+                       return (-1);
+               }
+
+               if (srv->srv_conf.tls_crl == NULL)
+                       continue;
+
+               log_debug("%s: adding crl(s) for server %s", __func__,
+                   srv->srv_conf.name);
+               if (tls_config_set_crl_mem(srv->srv_tls_config,
+                   srv_conf->tls_crl, srv_conf->tls_crl_len) != 0) {
+                       log_warnx("%s: failed to add crl(s)", __func__);
+                       return (-1);
+               }
        }
 
        /* set common session ID among all processes */
@@ -412,7 +486,11 @@ void
 serverconfig_free(struct server_config *srv_conf)
 {
        free(srv_conf->return_uri);
+       free(srv_conf->tls_ca_file);
+       free(srv_conf->tls_ca);
        free(srv_conf->tls_cert_file);
+       free(srv_conf->tls_crl_file);
+       free(srv_conf->tls_crl);
        free(srv_conf->tls_key_file);
        free(srv_conf->tls_ocsp_staple_file);
        free(srv_conf->tls_ocsp_staple);
@@ -425,8 +503,12 @@ serverconfig_reset(struct server_config 
 {
        srv_conf->auth = NULL;
        srv_conf->return_uri = NULL;
+       srv_conf->tls_ca = NULL;
+       srv_conf->tls_ca_file = NULL;
        srv_conf->tls_cert = NULL;
        srv_conf->tls_cert_file = NULL;
+       srv_conf->tls_crl = NULL;
+       srv_conf->tls_crl_file = NULL;
        srv_conf->tls_key = NULL;
        srv_conf->tls_key_file = NULL;
        srv_conf->tls_ocsp_staple = NULL;
Index: usr.sbin/httpd/server_fcgi.c
===================================================================
RCS file: /mount/openbsd/cvs/src/usr.sbin/httpd/server_fcgi.c,v
retrieving revision 1.74
diff -u -p -r1.74 server_fcgi.c
--- usr.sbin/httpd/server_fcgi.c        21 Jan 2017 11:32:04 -0000      1.74
+++ usr.sbin/httpd/server_fcgi.c        27 Jul 2017 09:29:31 -0000
@@ -93,11 +93,12 @@ server_fcgi(struct httpd *env, struct cl
        struct fcgi_record_header       *h;
        struct fcgi_begin_request_body  *begin;
        char                             hbuf[HOST_NAME_MAX+1];
-       size_t                           scriptlen;
+       size_t                           chainlen, scriptlen;
        int                              pathlen;
        int                              fd = -1, ret;
        const char                      *stripped, *p, *alias, *errstr = NULL;
-       char                            *str, *script = NULL;
+       char                            *chainc, *chainp, *str, *script = NULL;
+       const uint8_t                   *chain;
 
        if (srv_conf->socket[0] == ':') {
                struct sockaddr_storage  ss;
@@ -282,11 +283,57 @@ server_fcgi(struct httpd *env, struct cl
                goto fail;
        }
 
-       if (srv_conf->flags & SRVFLAG_TLS)
+       if (srv_conf->flags & SRVFLAG_TLS) {
                if (fcgi_add_param(&param, "HTTPS", "on", clt) == -1) {
                        errstr = "failed to encode param";
                        goto fail;
                }
+               if (clt->clt_srv->srv_conf.tls_ca != NULL) {
+                       chain = tls_peer_cert_chain_pem(clt->clt_tls_ctx,
+                           &chainlen);
+                       if ((chainc = strndup(chain, chainlen)) == NULL)
+                               goto fail;
+                       chainp = chainc;
+                       while ((chainp = strchr(chainp, '\n')) != NULL)
+                               *chainp = '\t';
+                       ret = fcgi_add_param(&param, "TLS_PEER_CHAIN", chainc,
+                           clt);
+                       free(chainc);
+                       if (ret == -1) {
+                               errstr = "failed to encode param";
+                               goto fail;
+                       }
+                       if (fcgi_add_param(&param, "TLS_PEER_SUBJECT",
+                           tls_peer_cert_subject(clt->clt_tls_ctx), clt) == -1
+                           || fcgi_add_param(&param, "TLS_PEER_ISSUER",
+                           tls_peer_cert_issuer(clt->clt_tls_ctx), clt) == -1
+                           || fcgi_add_param(&param, "TLS_PEER_HASH",
+                           tls_peer_cert_hash(clt->clt_tls_ctx), clt) == -1) {
+                               errstr = "failed to encode param";
+                               goto fail;
+                       }
+                       if (asprintf(&str, "%lld",
+                           tls_peer_cert_notafter(clt->clt_tls_ctx)) == -1
+                           || fcgi_add_param(&param, "TLS_PEER_EXPIRES", str,
+                           clt) == -1) {
+                               errstr = "failed to encode param";
+                               goto fail;
+                       }
+                       free(str);
+                       str = NULL;
+                       if (tls_peer_ocsp_url(clt->clt_tls_ctx) != NULL
+                           && fcgi_add_param(&param, "TLS_PEER_OCSP_URL",
+                           tls_peer_ocsp_url(clt->clt_tls_ctx), clt) == -1) {
+                               errstr = "failed to encode param";
+                               goto fail;
+                       }
+                       if (srv_conf->tls_crl != NULL && fcgi_add_param(&param,
+                           "TLS_PEER_CRL", "on", clt) == -1) {
+                               errstr = "failed to encode param";
+                               goto fail;
+                       }
+               }
+       }
 
        (void)print_host(&clt->clt_ss, hbuf, sizeof(hbuf));
        if (fcgi_add_param(&param, "REMOTE_ADDR", hbuf, clt) == -1) {

Reply via email to