Hi,
This diff adds client side certificate checks to httpd. Most parts are
straight forward. But, to transfer the whole certificate authority
store to the server process through the imsg infrastructure I had to
change this in an chunked transfer.
The Documentation of this feature is included in httpd.conf.5.
This time, I also extend an httpd tls regression tests to use a client
side certificate. All tests pass :-)
If anything is wrong with this diff, just notify me, I will fix it.
Bye,
Jan
Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/config.c,v
retrieving revision 1.45
diff -u -p -r1.45 config.c
--- config.c 28 Apr 2016 14:20:11 -0000 1.45
+++ config.c 3 May 2016 19:51:57 -0000
@@ -236,51 +236,59 @@ config_settls(struct httpd *env, struct
struct server_config *srv_conf = &srv->srv_conf;
struct tls_config tls;
struct iovec iov[2];
- size_t c;
+ size_t n;
+ char *p;
if ((srv_conf->flags & SRVFLAG_TLS) == 0)
return (0);
log_debug("%s: configuring TLS for %s", __func__, srv_conf->name);
- if (srv_conf->tls_cert_len != 0) {
- DPRINTF("%s: sending TLS cert \"%s[%u]\" to %s fd %d", __func__,
- srv_conf->name, srv_conf->id, ps->ps_title[PROC_SERVER],
- srv->srv_s);
-
- memset(&tls, 0, sizeof(tls));
- tls.id = srv_conf->id;
- tls.tls_cert_len = srv_conf->tls_cert_len;
-
- c = 0;
- iov[c].iov_base = &tls;
- iov[c++].iov_len = sizeof(tls);
- iov[c].iov_base = srv_conf->tls_cert;
- iov[c++].iov_len = srv_conf->tls_cert_len;
+ if ((p = malloc(srv_conf->tls_ca_len + srv_conf->tls_cert_len +
+ srv_conf->tls_key_len)) == NULL) {
+ log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
+ "`%s'", __func__, srv_conf->name);
+ return (-1);
+ }
- if (proc_composev(ps, PROC_SERVER, IMSG_CFG_TLS, iov, c) != 0) {
- log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
- "`%s'", __func__, srv_conf->name);
- return (-1);
- }
+ memcpy(p, srv_conf->tls_ca, srv_conf->tls_ca_len);
+ n = srv_conf->tls_ca_len;
+ memcpy(p + n, srv_conf->tls_cert, srv_conf->tls_cert_len);
+ n += srv_conf->tls_cert_len;
+ memcpy(p + n, srv_conf->tls_key, srv_conf->tls_key_len);
+ n += srv_conf->tls_key_len;
+
+ /* send tls_config structure */
+ memset(&tls, 0, sizeof(tls));
+ tls.id = srv_conf->id;
+ tls.port = srv_conf->port;
+ memcpy(&tls.ss, &srv_conf->ss, sizeof(tls.ss));
+ tls.tls_ca_optional = srv_conf->tls_ca_optional;
+ tls.tls_ca_len = srv_conf->tls_ca_len;
+ tls.tls_cert_len = srv_conf->tls_cert_len;
+ tls.tls_key_len = srv_conf->tls_key_len;
+
+ if (proc_compose(ps, PROC_SERVER, IMSG_CFG_TLS, &tls, sizeof(tls)) !=
0) {
+ log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
+ "`%s'", __func__, srv_conf->name);
+ return (-1);
}
- if (srv_conf->tls_key_len != 0) {
- DPRINTF("%s: sending TLS key \"%s[%u]\" to %s fd %d", __func__,
- srv_conf->name, srv_conf->id, ps->ps_title[PROC_SERVER],
- srv->srv_s);
-
- memset(&tls, 0, sizeof(tls));
- tls.id = srv_conf->id;
- tls.tls_key_len = srv_conf->tls_key_len;
-
- c = 0;
- iov[c].iov_base = &tls;
- iov[c++].iov_len = sizeof(tls);
- iov[c].iov_base = srv_conf->tls_key;
- iov[c++].iov_len = srv_conf->tls_key_len;
+ iov[0].iov_base = &tls;
+ iov[0].iov_len = sizeof(tls);
+
+#define MSG_CHUNK_SIZE (MAX_IMSGSIZE - (ssize_t)IMSG_HEADER_SIZE -
iov[0].iov_len)
+
+ /* transfer in chunks */
+ for (; n > 0; p += MSG_CHUNK_SIZE) {
+ size_t len = n > MSG_CHUNK_SIZE ? MSG_CHUNK_SIZE : n;
+ n -= len;
- if (proc_composev(ps, PROC_SERVER, IMSG_CFG_TLS, iov, c) != 0) {
+ iov[1].iov_base = p;
+ iov[1].iov_len = len;
+
+ if (proc_composev(ps, PROC_SERVER, IMSG_CFG_TLS_CHNK, iov, 2)
+ != 0) {
log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
"`%s'", __func__, srv_conf->name);
return (-1);
@@ -555,6 +563,52 @@ config_getserver(struct httpd *env, stru
}
int
+config_gettls_chunk(struct httpd *env, struct imsg *imsg)
+{
+ struct server_config *srv_conf = NULL;
+ struct tls_config tls_conf;
+ uint8_t *p = imsg->data;
+ size_t s = 0;
+
+ IMSG_SIZE_CHECK(imsg, &tls_conf);
+ memcpy(&tls_conf, p, sizeof(tls_conf));
+ s = sizeof(tls_conf);
+
+ if ((srv_conf = serverconfig_byid(tls_conf.id)) == NULL) {
+ log_debug("%s: server not found", __func__);
+ goto fail;
+ }
+
+#define CHUNK_CPY(dst, dst_len, dst_size, src, src_size, src_off) \
+ do { \
+ if (dst_len < dst_size) { \
+ size_t n = dst_size - dst_len; \
+ if (n > src_size - src_off) \
+ n = src_size - src_off; \
+ memcpy(dst + dst_len, src + src_off, n); \
+ dst_len += n; \
+ src_off += n; \
+ } \
+ } while(0)
+
+ CHUNK_CPY(srv_conf->tls_ca, srv_conf->tls_ca_len,
+ srv_conf->tls_ca_size, p, IMSG_DATA_SIZE(imsg), s);
+
+ CHUNK_CPY(srv_conf->tls_cert, srv_conf->tls_cert_len,
+ srv_conf->tls_cert_size, p, IMSG_DATA_SIZE(imsg), s);
+
+ CHUNK_CPY(srv_conf->tls_key, srv_conf->tls_key_len,
+ srv_conf->tls_key_size, p, IMSG_DATA_SIZE(imsg), s);
+
+#undef CHUNK_CPY
+
+ return (0);
+
+ fail:
+ return (-1);
+}
+
+int
config_gettls(struct httpd *env, struct imsg *imsg)
{
#ifdef DEBUG
@@ -569,12 +623,6 @@ config_gettls(struct httpd *env, struct
memcpy(&tls_conf, p, sizeof(tls_conf));
s = sizeof(tls_conf);
- if ((IMSG_DATA_SIZE(imsg) - s) <
- (tls_conf.tls_cert_len + tls_conf.tls_key_len)) {
- log_debug("%s: invalid message length", __func__);
- goto fail;
- }
-
if ((srv_conf = serverconfig_byid(tls_conf.id)) == NULL) {
log_debug("%s: server not found", __func__);
goto fail;
@@ -584,20 +632,25 @@ config_gettls(struct httpd *env, struct
ps->ps_title[privsep_process], ps->ps_instance,
srv_conf->name, srv->srv_conf.id);
- if (tls_conf.tls_cert_len != 0) {
- srv_conf->tls_cert_len = tls_conf.tls_cert_len;
- if ((srv_conf->tls_cert = get_data(p + s,
- tls_conf.tls_cert_len)) == NULL)
- goto fail;
- s += tls_conf.tls_cert_len;
- }
- if (tls_conf.tls_key_len != 0) {
- srv_conf->tls_key_len = tls_conf.tls_key_len;
- if ((srv_conf->tls_key = get_data(p + s,
- tls_conf.tls_key_len)) == NULL)
- goto fail;
- s += tls_conf.tls_key_len;
- }
+ srv_conf->tls_ca_optional = tls_conf.tls_ca_optional;
+ srv_conf->tls_ca_len = 0;
+ srv_conf->tls_cert_len = 0;
+ srv_conf->tls_key_len = 0;
+
+ srv_conf->tls_ca_size = tls_conf.tls_ca_len;
+ srv_conf->tls_cert_size = tls_conf.tls_cert_len;
+ srv_conf->tls_key_size = tls_conf.tls_key_len;
+
+ free(srv_conf->tls_ca);
+ free(srv_conf->tls_cert);
+ free(srv_conf->tls_key);
+
+ if ((srv_conf->tls_ca = malloc(tls_conf.tls_ca_len)) == NULL)
+ goto fail;
+ if ((srv_conf->tls_cert = malloc(tls_conf.tls_cert_len)) == NULL)
+ goto fail;
+ if ((srv_conf->tls_key = malloc(tls_conf.tls_key_len)) == NULL)
+ goto fail;
return (0);
Index: httpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.73
diff -u -p -r1.73 httpd.conf.5
--- httpd.conf.5 9 May 2016 19:36:54 -0000 1.73
+++ httpd.conf.5 10 May 2016 16:18:04 -0000
@@ -498,6 +498,13 @@ Set the TLS configuration for the server
These options are only used if TLS has been enabled via the listen directive.
Valid options are:
.Bl -tag -width Ds
+.It Ic ca Ar file Oo Ic optional Oc
+Specify a certificate authority for verifying client side certificates.
+.Ar file
+should contain a PEM encoded certificate of the certificate authority.
+The parameter
+.Ic optional
+does not requiring the client to send a certificate.
.It Ic certificate Ar file
Specify the certificate to use for this server.
The
Index: httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.103
diff -u -p -r1.103 httpd.h
--- httpd.h 28 Apr 2016 14:20:11 -0000 1.103
+++ httpd.h 7 May 2016 02:53:08 -0000
@@ -203,6 +203,7 @@ enum imsg_type {
IMSG_CTL_REOPEN,
IMSG_CFG_SERVER,
IMSG_CFG_TLS,
+ IMSG_CFG_TLS_CHNK,
IMSG_CFG_MEDIA,
IMSG_CFG_AUTH,
IMSG_CFG_DONE,
@@ -424,14 +425,21 @@ struct server_config {
uint32_t maxrequests;
size_t maxrequestbody;
+ uint8_t *tls_ca;
+ size_t tls_ca_len;
+ size_t tls_ca_size;
+ char *tls_ca_file;
+ uint8_t tls_ca_optional;
uint8_t *tls_cert;
size_t tls_cert_len;
+ size_t tls_cert_size;
char *tls_cert_file;
char tls_ciphers[NAME_MAX];
char tls_dhe_params[NAME_MAX];
char tls_ecdhe_curve[NAME_MAX];
uint8_t *tls_key;
size_t tls_key_len;
+ size_t tls_key_size;
char *tls_key_file;
uint32_t tls_protocols;
@@ -465,8 +473,15 @@ TAILQ_HEAD(serverhosts, server_config);
struct tls_config {
uint32_t id;
+ in_port_t port;
+ struct sockaddr_storage ss;
+
+ int tls_ca_optional;
+ size_t tls_ca_len;
size_t tls_cert_len;
size_t tls_key_len;
+
+ size_t chunk_size;
};
struct server {
@@ -720,6 +735,7 @@ int config_setserver(struct httpd *, st
int config_settls(struct httpd *, struct server *);
int config_getserver(struct httpd *, struct imsg *);
int config_gettls(struct httpd *, struct imsg *);
+int config_gettls_chunk(struct httpd *, struct imsg *);
int config_setmedia(struct httpd *, struct media_type *);
int config_getmedia(struct httpd *, struct imsg *);
int config_setauth(struct httpd *, struct auth *);
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.77
diff -u -p -r1.77 parse.y
--- parse.y 22 Nov 2015 13:27:13 -0000 1.77
+++ parse.y 7 May 2016 02:45:39 -0000
@@ -129,12 +129,12 @@ typedef struct {
%}
-%token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON
-%token COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LISTEN
-%token LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY ON PORT PREFORK PROTOCOLS
-%token REQUEST REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TIMEOUT
-%token TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD
-%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS
+%token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CA CERTIFICATE CHROOT CIPHERS
+%token COMMON COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY
+%token LISTEN LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY ON PORT PREFORK
+%token PROTOCOLS REQUEST REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG
+%token TCP TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD
+%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS OPTIONAL
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.port> port
@@ -244,6 +244,7 @@ server : SERVER optmatch STRING {
s->srv_conf.flags |= SRVFLAG_SERVER_MATCH;
s->srv_conf.logformat = LOG_FORMAT_COMMON;
s->srv_conf.tls_protocols = TLS_PROTOCOLS_DEFAULT;
+ s->srv_conf.tls_ca_file = NULL;
if ((s->srv_conf.tls_cert_file =
strdup(HTTPD_TLS_CERT)) == NULL)
fatal("out of memory");
@@ -315,7 +316,7 @@ server : SERVER optmatch STRING {
}
if (server_tls_load_keypair(srv) == -1) {
- yyerror("failed to load public/private keys "
+ yyerror("XXfailed to load public/private keys "
"for server %s", srv->srv_conf.name);
serverconfig_free(srv_conf);
free(srv);
@@ -663,7 +664,21 @@ tlsopts_l : tlsopts optcommanl tlsopts_l
| tlsopts optnl
;
-tlsopts : CERTIFICATE STRING {
+tlsopts : CA STRING {
+ srv_conf->tls_ca_optional = 0;
+ free(srv_conf->tls_ca_file);
+ if ((srv_conf->tls_ca_file = strdup($2)) == NULL)
+ fatal("out of memory");
+ free($2);
+ }
+ | CA STRING OPTIONAL {
+ srv_conf->tls_ca_optional = 1;
+ free(srv_conf->tls_ca_file);
+ if ((srv_conf->tls_ca_file = strdup($2)) == NULL)
+ fatal("out of memory");
+ free($2);
+ }
+ | CERTIFICATE STRING {
free(srv_conf->tls_cert_file);
if ((srv_conf->tls_cert_file = strdup($2)) == NULL)
fatal("out of memory");
@@ -1148,6 +1163,7 @@ lookup(char *s)
{ "block", BLOCK },
{ "body", BODY },
{ "buffer", BUFFER },
+ { "ca", CA},
{ "certificate", CERTIFICATE },
{ "chroot", CHROOT },
{ "ciphers", CIPHERS },
@@ -1176,6 +1192,7 @@ lookup(char *s)
{ "no", NO },
{ "nodelay", NODELAY },
{ "on", ON },
+ { "optional", OPTIONAL },
{ "pass", PASS },
{ "port", PORT },
{ "prefork", PREFORK },
@@ -1970,16 +1987,26 @@ server_inherit(struct server *src, struc
/* Copy the source server and assign a new Id */
memcpy(&dst->srv_conf, &src->srv_conf, sizeof(dst->srv_conf));
+ 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 ((dst->srv_conf.tls_cert_file =
strdup(src->srv_conf.tls_cert_file)) == NULL)
fatal("out of memory");
if ((dst->srv_conf.tls_key_file =
strdup(src->srv_conf.tls_key_file)) == NULL)
fatal("out of memory");
+ dst->srv_conf.tls_ca = NULL;
dst->srv_conf.tls_cert = NULL;
dst->srv_conf.tls_key = NULL;
+ dst->srv_conf.tls_ca_len = 0;
dst->srv_conf.tls_cert_len = 0;
dst->srv_conf.tls_key_len = 0;
+ dst->srv_conf.tls_ca_size = 0;
+ dst->srv_conf.tls_cert_size = 0;
+ dst->srv_conf.tls_key_size = 0;
if (src->srv_conf.return_uri != NULL &&
(dst->srv_conf.return_uri =
@@ -2012,7 +2039,7 @@ server_inherit(struct server *src, struc
dst->srv_conf.flags |= (alias->flags & SRVFLAG_SERVER_MATCH);
if (server_tls_load_keypair(dst) == -1) {
- yyerror("failed to load public/private keys "
+ yyerror("YYfailed to load public/private keys "
"for server %s", dst->srv_conf.name);
serverconfig_free(&dst->srv_conf);
free(dst);
Index: server.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server.c,v
retrieving revision 1.85
diff -u -p -r1.85 server.c
--- server.c 28 Apr 2016 17:18:06 -0000 1.85
+++ server.c 7 May 2016 22:58:20 -0000
@@ -138,6 +138,15 @@ server_tls_load_keypair(struct server *s
if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0)
return (0);
+ if (srv->srv_conf.tls_ca_file != NULL) {
+ 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 certificate authority %s", __func__,
+ srv->srv_conf.tls_ca_file);
+ }
+
if ((srv->srv_conf.tls_cert = tls_load_file(
srv->srv_conf.tls_cert_file, &srv->srv_conf.tls_cert_len,
NULL)) == NULL)
@@ -199,6 +208,20 @@ server_tls_init(struct server *srv)
return (-1);
}
+ if (srv->srv_conf.tls_ca_len > 0) {
+ log_warnx("%s: set tls ca len: %zu", __func__,
+ srv->srv_conf.tls_ca_len);
+ 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 set tls ca", __func__);
+ return (-1);
+ }
+ if (srv->srv_conf.tls_ca_optional)
+ tls_config_verify_client_optional(srv->srv_tls_config);
+ else
+ tls_config_verify_client(srv->srv_tls_config);
+ }
+
if (tls_config_set_keypair_mem(srv->srv_tls_config,
srv->srv_conf.tls_cert, srv->srv_conf.tls_cert_len,
srv->srv_conf.tls_key, srv->srv_conf.tls_key_len) != 0) {
@@ -215,12 +238,16 @@ server_tls_init(struct server *srv)
/* We're now done with the public/private key... */
tls_config_clear_keys(srv->srv_tls_config);
+ explicit_bzero(srv->srv_conf.tls_ca, srv->srv_conf.tls_ca_len);
explicit_bzero(srv->srv_conf.tls_cert, srv->srv_conf.tls_cert_len);
explicit_bzero(srv->srv_conf.tls_key, srv->srv_conf.tls_key_len);
+ free(srv->srv_conf.tls_ca);
free(srv->srv_conf.tls_cert);
free(srv->srv_conf.tls_key);
+ srv->srv_conf.tls_ca = NULL;
srv->srv_conf.tls_cert = NULL;
srv->srv_conf.tls_key = NULL;
+ srv->srv_conf.tls_ca_len = 0;
srv->srv_conf.tls_cert_len = 0;
srv->srv_conf.tls_key_len = 0;
@@ -317,9 +344,15 @@ void
serverconfig_free(struct server_config *srv_conf)
{
free(srv_conf->return_uri);
+ free(srv_conf->tls_ca_file);
free(srv_conf->tls_cert_file);
free(srv_conf->tls_key_file);
+ if (srv_conf->tls_ca != NULL) {
+ explicit_bzero(srv_conf->tls_ca, srv_conf->tls_ca_len);
+ free(srv_conf->tls_ca);
+ }
+
if (srv_conf->tls_cert != NULL) {
explicit_bzero(srv_conf->tls_cert, srv_conf->tls_cert_len);
free(srv_conf->tls_cert);
@@ -336,6 +369,8 @@ 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_key = NULL;
@@ -1132,6 +1167,9 @@ server_dispatch_parent(int fd, struct pr
break;
case IMSG_CFG_TLS:
config_gettls(env, imsg);
+ break;
+ case IMSG_CFG_TLS_CHNK:
+ config_gettls_chunk(env, imsg);
break;
case IMSG_CFG_DONE:
config_getcfg(env, imsg);
Index: tests/Client.pm
===================================================================
RCS file: /cvs/src/regress/usr.sbin/httpd/tests/Client.pm,v
retrieving revision 1.1
diff -u -p -r1.1 Client.pm
--- tests/Client.pm 16 Jul 2015 16:35:57 -0000 1.1
+++ tests/Client.pm 10 May 2016 16:09:23 -0000
@@ -59,6 +59,9 @@ sub child {
PeerAddr => $self->{connectaddr},
PeerPort => $self->{connectport},
SSL_verify_mode => SSL_VERIFY_NONE,
+ SSL_use_cert => $self->{clientcert} ? 1 : 0,
+ SSL_cert_file => $self->{clientcert} ?
$self->{chroot}."/client.crt" : "",
+ SSL_key_file => $self->{clientcert} ?
$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: tests/Httpd.pm
===================================================================
RCS file: /cvs/src/regress/usr.sbin/httpd/tests/Httpd.pm,v
retrieving revision 1.1
diff -u -p -r1.1 Httpd.pm
--- tests/Httpd.pm 16 Jul 2015 16:35:57 -0000 1.1
+++ tests/Httpd.pm 10 May 2016 16:03:01 -0000
@@ -71,6 +71,9 @@ sub new {
print $fh "\n";
print $fh "\ttls certificate \"".$args{chroot}."/server.crt\"\n";
print $fh "\ttls key \"".$args{chroot}."/server.key\"";
+ if ($self->{clientcert}) {
+ print $fh "\n\ttls ca \"".$args{chroot}."/ca.crt\"";
+ }
}
print $fh "\n\troot \"/\"";
print $fh "\n\tlog style combined";
Index: tests/Makefile
===================================================================
RCS file: /cvs/src/regress/usr.sbin/httpd/tests/Makefile,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile
--- tests/Makefile 16 Jul 2015 17:00:41 -0000 1.2
+++ tests/Makefile 10 May 2016 14:18:13 -0000
@@ -88,7 +88,13 @@ server.req:
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.req:
+ openssl req -batch -new -subj
/L=OpenBSD/O=httpd-regress/OU=client/CN=user/ -nodes -newkey rsa -keyout
client.key -out client.req
+
+client.crt: ca.crt client.req
+ openssl x509 -CAcreateserial -CAkey ca.key -CA ca.crt -req -in
client.req -out client.crt
+
+${REGRESS_TARGETS:M*tls*} ${REGRESS_TARGETS:M*https*}: server.crt client.crt
# make perl syntax check for all args files
Index: tests/args-tls.pl
===================================================================
RCS file: /cvs/src/regress/usr.sbin/httpd/tests/args-tls.pl,v
retrieving revision 1.1
diff -u -p -r1.1 args-tls.pl
--- tests/args-tls.pl 16 Jul 2015 16:35:57 -0000 1.1
+++ tests/args-tls.pl 10 May 2016 16:09:35 -0000
@@ -7,9 +7,11 @@ our %args = (
client => {
tls => 1,
loggrep => 'Issuer.*/OU=ca/',
+ clientcert => 1,
},
httpd => {
listentls => 1,
+ clientcert => 1,
},
len => 512,
md5 => path_md5("512")