Enable client certificate authentication by specifying a -b path_to_ca_cert_file on the command line. When this parameter is set, TLS server requests a client certificate (signed by the specified CA). If client certificate authentication is successful, client cert data is stored in HTTPS_CLIENT_CERT, HTTPS_CLIENT_CERT_SHA256 and HTTPS_CLIENT_CERT_SN environment variables. Currently not supported by mbedtls backend.
Signed-off-by: Luka Logar <[email protected]> --- main.c | 10 ++++++++-- proc.c | 9 +++++++++ tls.c | 7 ++++++- tls.h | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 73e3d42..fb6a84e 100644 --- a/main.c +++ b/main.c @@ -141,6 +141,7 @@ static int usage(const char *name) " -K file ASN.1 server private key file\n" " -P ciphers Colon separated list of allowed TLS ciphers\n" " -q Redirect all HTTP requests to HTTPS\n" + " -b client_ca Enable TLS client auth using client_ca for certificate selection\n" #endif " -h directory Specify the document root, default is '.'\n" " -E string Use given virtual URL as 404 error handler\n" @@ -252,6 +253,7 @@ int main(int argc, char **argv) #ifdef HAVE_TLS int n_tls = 0; const char *tls_key = NULL, *tls_crt = NULL, *tls_ciphers = NULL; + const char *tls_client_ca = NULL; #endif #ifdef HAVE_LUA const char *lua_prefix = NULL, *lua_handler = NULL; @@ -263,7 +265,7 @@ int main(int argc, char **argv) init_defaults_pre(); signal(SIGPIPE, SIG_IGN); - while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:e:fh:H:I:i:K:k:L:l:m:N:n:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) { + while ((ch = getopt(argc, argv, "A:ab:C:c:Dd:E:e:fh:H:I:i:K:k:L:l:m:N:n:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) { switch(ch) { #ifdef HAVE_TLS case 'C': @@ -282,6 +284,10 @@ int main(int argc, char **argv) conf.tls_redirect = 1; break; + case 'b': + tls_client_ca = optarg; + break; + case 's': n_tls++; /* fall through */ @@ -535,7 +541,7 @@ int main(int argc, char **argv) return 1; } - if (uh_tls_init(tls_key, tls_crt, tls_ciphers)) + if (uh_tls_init(tls_key, tls_crt, tls_ciphers, tls_client_ca)) return 1; } #endif diff --git a/proc.c b/proc.c index 2b69703..798f385 100644 --- a/proc.c +++ b/proc.c @@ -90,6 +90,9 @@ enum extra_vars { VAR_PATH_INFO, VAR_USER, VAR_HTTPS, + VAR_HTTPS_CLIENT_CERT, + VAR_HTTPS_CLIENT_CERT_SHA256, + VAR_HTTPS_CLIENT_CERT_SN, VAR_REDIRECT, VAR_SERVER_NAME, VAR_SERVER_ADDR, @@ -118,6 +121,9 @@ static struct env_var extra_vars[] = { [VAR_PATH_INFO] = { "PATH_INFO" }, [VAR_USER] = { "REMOTE_USER" }, [VAR_HTTPS] = { "HTTPS" }, + [VAR_HTTPS_CLIENT_CERT] = { "HTTPS_CLIENT_CERT" }, + [VAR_HTTPS_CLIENT_CERT_SHA256] = { "HTTPS_CLIENT_CERT_SHA256" }, + [VAR_HTTPS_CLIENT_CERT_SN] = { "HTTPS_CLIENT_CERT_SN" }, [VAR_REDIRECT] = { "REDIRECT_STATUS", redirect_status }, [VAR_SERVER_NAME] = { "SERVER_NAME", local_addr }, [VAR_SERVER_ADDR] = { "SERVER_ADDR", local_addr }, @@ -154,6 +160,9 @@ struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) extra_vars[VAR_PATH_INFO].value = pi->info; extra_vars[VAR_USER].value = req->realm ? req->realm->user : NULL; extra_vars[VAR_HTTPS].value = cl->tls ? "on" : NULL; + extra_vars[VAR_HTTPS_CLIENT_CERT].value = cl->ssl.peer_cert; + extra_vars[VAR_HTTPS_CLIENT_CERT_SHA256].value = cl->ssl.peer_cert ? cl->ssl.peer_cert_sha256 : NULL; + extra_vars[VAR_HTTPS_CLIENT_CERT_SN].value = cl->ssl.peer_cert_sn; snprintf(redirect_status, sizeof(redirect_status), "%d", req->redirect_status); diff --git a/tls.c b/tls.c index 1da0881..bb616eb 100644 --- a/tls.c +++ b/tls.c @@ -31,7 +31,7 @@ static struct ustream_ssl_ops *ops; static void *dlh; static void *ctx; -int uh_tls_init(const char *key, const char *crt, const char *ciphers) +int uh_tls_init(const char *key, const char *crt, const char *ciphers, const char *client_ca) { static bool _init = false; @@ -68,6 +68,11 @@ int uh_tls_init(const char *key, const char *crt, const char *ciphers) return -EINVAL; } + if (client_ca && (ops->context_set_require_validation(ctx, 1) || ops->context_add_ca_crt_file(ctx, client_ca))) { + fprintf(stderr, "Can not enable TLS client authentication\n"); + return -EINVAL; + } + return 0; } diff --git a/tls.h b/tls.h index f457cb7..2b0b26a 100644 --- a/tls.h +++ b/tls.h @@ -22,7 +22,7 @@ #ifdef HAVE_TLS -int uh_tls_init(const char *key, const char *crt, const char *ciphers); +int uh_tls_init(const char *key, const char *crt, const char *ciphers, const char *client_ca); void uh_tls_client_attach(struct client *cl); void uh_tls_client_detach(struct client *cl); -- 2.25.1 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
