commit ba94a608a89110740cb24ef098c476c84d371918 from: Omar Polo date: Tue Jan 04 23:14:34 2022 UTC add `require client ca' for proxy blocks refactor the code that calls validate_against_ca into an helper function to reuse it in both apply_require_ca and (optionally) in apply_reverse_proxy. commit - 280fd79b8f5d42097d2a1a315338559261cb1e74 commit + ba94a608a89110740cb24ef098c476c84d371918 blob - 92f6985ae691b1d31f5aeb3421516ef2e02af9d9 blob + 9e8415dc232bc054d956e379bc1b53808ba25c9d --- gmid.h +++ gmid.h @@ -112,6 +112,7 @@ struct proxy { size_t certlen; uint8_t *key; size_t keylen; + X509_STORE *reqca; TAILQ_ENTRY(proxy) proxies; }; blob - 43a7b15c80d3c94252642ca2f81c727b4f53f720 blob + 57cf3f5c72c7f07008879881d2a19bf18cb0cbb0 --- parse.y +++ parse.y @@ -351,6 +351,13 @@ proxy_opt : CERT string { free(proxy->host); parsehp($2, &proxy->host, &proxy->port, "1965"); } + | REQUIRE CLIENT CA string { + only_once(proxy->reqca, "require client ca"); + ensure_absolute_path($4); + if ((proxy->reqca = load_ca($4)) == NULL) + yyerror("couldn't load ca cert: %s", $4); + free($4); + } | USE_TLS bool { proxy->notls = !$2; } blob - 991e126f99721dd111e9225158cbba52b7557d6a blob + 2faf79278168b55fb373c3e5b5cce7f9b8c0e898 --- server.c +++ server.c @@ -628,6 +628,26 @@ matched_proxy(struct client *c) } return NULL; +} + +static int +check_matching_certificate(X509_STORE *store, struct client *c) +{ + const uint8_t *cert; + size_t len; + + if (!tls_peer_cert_provided(c->ctx)) { + start_reply(c, CLIENT_CERT_REQ, "client certificate required"); + return 1; + } + + cert = tls_peer_cert_chain_pem(c->ctx, &len); + if (!validate_against_ca(store, cert, len)) { + start_reply(c, CERT_NOT_AUTH, "certificate not authorised"); + return 1; + } + + return 0; } /* 1 if matching a proxy relay-to (and apply it), 0 otherwise */ @@ -642,6 +662,9 @@ apply_reverse_proxy(struct client *c) c->proxy = p; + if (p->reqca != NULL && check_matching_certificate(p->reqca, c)) + return 1; + log_debug(c, "opening proxy connection for %s:%s", p->host, p->port); @@ -680,24 +703,10 @@ static int apply_require_ca(struct client *c) { X509_STORE *store; - const uint8_t *cert; - size_t len; if ((store = vhost_require_ca(c->host, c->iri.path)) == NULL) return 0; - - if (!tls_peer_cert_provided(c->ctx)) { - start_reply(c, CLIENT_CERT_REQ, "client certificate required"); - return 1; - } - - cert = tls_peer_cert_chain_pem(c->ctx, &len); - if (!validate_against_ca(store, cert, len)) { - start_reply(c, CERT_NOT_AUTH, "certificate not authorised"); - return 1; - } - - return 0; + return check_matching_certificate(store, c); } static size_t