From f6dc47f591d3a59fa15fed575a7dce95fdacc255 Mon Sep 17 00:00:00 2001 From: Harald Gutmann Date: Sat, 18 Mar 2023 23:31:39 +0100 Subject: [PATCH] pki: Add support for EST server label As specified in EST RFC 7030, Section 3.1 [1]. [1] https://www.rfc-editor.org/rfc/rfc7030.html#section-3.1 --- src/pki/commands/est.c | 10 +++++++--- src/pki/commands/estca.c | 10 +++++++--- src/pki/est/est_tls.c | 30 +++++++++++++++++++++++------- src/pki/est/est_tls.h | 3 ++- src/pki/man/pki---est.1.in | 4 ++++ src/pki/man/pki---estca.1.in | 4 ++++ 6 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/pki/commands/est.c b/src/pki/commands/est.c index 67e011f963..b9859e9ba0 100644 --- a/src/pki/commands/est.c +++ b/src/pki/commands/est.c @@ -32,7 +32,7 @@ */ static int est() { - char *arg, *url = NULL, *file = NULL, *error = NULL; + char *arg, *url = NULL, *label = NULL, *file = NULL, *error = NULL; char *client_cert_file = NULL, *client_key_file = NULL; char *keyid = NULL, *certid = NULL, *user_pass = NULL; cred_encoding_type_t form = CERT_ASN1_DER; @@ -60,6 +60,9 @@ static int est() case 'u': /* --url */ url = arg; continue; + case 'l': /* --label */ + label = arg; + continue; case 'i': /* --in */ file = arg; continue; @@ -256,7 +259,7 @@ static int est() est_op = EST_SIMPLE_REENROLL; } - est_tls = est_tls_create(url, client_cert, user_pass); + est_tls = est_tls_create(url, label, client_cert, user_pass); if (!est_tls) { DBG1(DBG_APP, "TLS connection to EST server was not established"); @@ -304,7 +307,7 @@ static int est() DBG1(DBG_APP, " going to sleep for %d seconds", poll_interval); sleep(poll_interval); - est_tls = est_tls_create(url, client_cert, user_pass); + est_tls = est_tls_create(url, label, client_cert, user_pass); if (!est_tls) { DBG1(DBG_APP, "TLS connection to EST server was not established"); @@ -360,6 +363,7 @@ static void __attribute__ ((constructor))reg() { {"help", 'h', 0, "show usage information"}, {"url", 'u', 1, "URL of the EST server"}, + {"label", 'l', 1, "label in the EST server path"}, {"in", 'i', 1, "PKCS#10 input file, default: stdin"}, {"cacert", 'C', 1, "CA certificate"}, {"cert", 'c', 1, "old certificate about to be renewed"}, diff --git a/src/pki/commands/estca.c b/src/pki/commands/estca.c index f6a584bb7d..925b15b731 100644 --- a/src/pki/commands/estca.c +++ b/src/pki/commands/estca.c @@ -32,7 +32,7 @@ static int estca() certificate_t *cacert; mem_cred_t *creds = NULL; est_tls_t *est_tls; - char *arg, *error = NULL, *url = NULL, *caout = NULL; + char *arg, *error = NULL, *url = NULL, *label = NULL, *caout = NULL; bool force = FALSE, success; u_int http_code = 0; status_t status = 1; @@ -50,6 +50,9 @@ static int estca() case 'u': /* --url */ url = arg; continue; + case 'l': /* --label */ + label = arg; + continue; case 'C': /* --cacert */ cacert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, arg, BUILD_END); @@ -87,7 +90,7 @@ static int estca() return command_usage("--url is required"); } - est_tls = est_tls_create(url, NULL, NULL); + est_tls = est_tls_create(url, label, NULL, NULL); if (!est_tls) { DBG1(DBG_APP, "TLS connection to EST server was not established"); @@ -132,7 +135,8 @@ static void __attribute__ ((constructor))reg() {"--url url [--cacert file]+ [--caout file] [--outform der|pem] [--force]"}, { {"help", 'h', 0, "show usage information"}, - {"url", 'u', 1, "URL of the SCEP server"}, + {"url", 'u', 1, "URL of the EST server"}, + {"label", 'l', 1, "label in the EST server path"}, {"cacert", 'C', 1, "TLS CA certificate"}, {"caout", 'c', 1, "CA certificate [template]"}, {"outform", 'f', 1, "encoding of stored certificates, default: der"}, diff --git a/src/pki/est/est_tls.c b/src/pki/est/est_tls.c index 4beae44bf8..ca450d5a56 100644 --- a/src/pki/est/est_tls.c +++ b/src/pki/est/est_tls.c @@ -80,6 +80,11 @@ struct private_est_tls_t { */ char *http_path; + /** + * Label string used for http requests + */ + char *http_label; + /** * Optional base64-encoded for http basic authentication */ @@ -108,13 +113,13 @@ static chunk_t build_http_request(private_est_tls_t *this, est_op_t op, chunk_t data = chunk_to_base64(in, NULL); len = asprintf(&http_header, - "POST %s/.well-known/est/%s HTTP/1.1\r\n" + "POST %s/.well-known/est%s%s HTTP/1.1\r\n" "Host: %s\r\n" "%s" "Content-Type: %s\r\n" "Content-Length: %d\r\n" "\r\n", - this->http_path, operations[op], this->http_host, http_auth, + this->http_path, this->http_label, operations[op], this->http_host, http_auth, request_types[op], (int)data.len); if (len > 0) { @@ -128,11 +133,11 @@ static chunk_t build_http_request(private_est_tls_t *this, est_op_t op, chunk_t else /* create HTTP GET request */ { len = asprintf(&http_header, - "GET %s/.well-known/est/%s HTTP/1.1\r\n" + "GET %s/.well-known/est%s%s HTTP/1.1\r\n" "Host: %s\r\n" "%s" "\r\n", - this->http_path, operations[op], this->http_host, http_auth); + this->http_path, this->http_label, operations[op], this->http_host, http_auth); if (len > 0) { request = chunk_create(http_header, len); @@ -289,11 +294,12 @@ METHOD(est_tls_t, destroy, void, } chunk_clear(&this->user_pass); free(this->http_host); + free(this->http_label); free(this->http_path); free(this); } -static bool est_tls_init(private_est_tls_t *this, char *uri, +static bool est_tls_init(private_est_tls_t *this, char *uri, char *label, certificate_t *client_cert) { identification_t *client_id = NULL, *server_id = NULL; @@ -321,6 +327,16 @@ static bool est_tls_init(private_est_tls_t *this, char *uri, *path_str = '\0'; } + /* ensure sure label starts and ends with '/' character */ + if (!label || !label[0] || + asprintf(&this->http_label, "%s%s%s", + label[0] == '/' ? "" : "/", + label, + label[strlen(label) - 1] == '/' ? "" : "/") < 0) + { + this->http_label = strdup("/"); + } + /* duplicate string since we are going to manipulate it */ host_str = strdup(uri); @@ -392,7 +408,7 @@ end: /** * See header */ -est_tls_t *est_tls_create(char *uri, certificate_t *client_cert, char *user_pass) +est_tls_t *est_tls_create(char *uri, char *label, certificate_t *client_cert, char *user_pass) { private_est_tls_t *this; @@ -408,7 +424,7 @@ est_tls_t *est_tls_create(char *uri, certificate_t *client_cert, char *user_pass this->user_pass = chunk_to_base64(chunk_from_str(user_pass), NULL); } - if (!est_tls_init(this, uri, client_cert)) + if (!est_tls_init(this, uri, label, client_cert)) { destroy(this); return NULL; diff --git a/src/pki/est/est_tls.h b/src/pki/est/est_tls.h index ded2aeb19a..0aaae48f58 100644 --- a/src/pki/est/est_tls.h +++ b/src/pki/est/est_tls.h @@ -70,10 +70,11 @@ struct est_tls_t { * Create a est_tls instance. * * @param uri URI (https://...) + * @param label Optional EST server label * @param client_cert Optional client certificate * @param user_pass Optional username:password for HTTP Basic Authentication */ -est_tls_t *est_tls_create(char *uri, certificate_t *client_cert, +est_tls_t *est_tls_create(char *uri, char *label, certificate_t *client_cert, char *user_pass); #endif /** EST_TLS_H_ @}*/ diff --git a/src/pki/man/pki---est.1.in b/src/pki/man/pki---est.1.in index a4d9c282fe..50a7617d27 100644 --- a/src/pki/man/pki---est.1.in +++ b/src/pki/man/pki---est.1.in @@ -8,6 +8,7 @@ pki \-\-est \- Enroll an X.509 certificate with an EST server . .SY pki\ \-\-est .BI\-\-\-url\~ url +.OP \-\-label label .OP \-\-in file .BI \-\-cacert\~ file .RB [ \-\-cert @@ -61,6 +62,9 @@ Read command line options from \fIfile\fR. .BI "\-u, \-\-url " url URL of the EST server. .TP +.BI "\-l, \-\-label " label +Label in the EST server path. +.TP .BI "\-i, \-\-in " file PKCS#10 certificate request. If not given, the certificate request is read from \fISTDIN\fR. diff --git a/src/pki/man/pki---estca.1.in b/src/pki/man/pki---estca.1.in index 00db818a43..212eb41f7d 100644 --- a/src/pki/man/pki---estca.1.in +++ b/src/pki/man/pki---estca.1.in @@ -8,6 +8,7 @@ pki \-\-estca \- Get CA certificate[s] from an EST server . .SY pki\ \-\-estca .BI\-\-\-url\~ url +.OP \-\-label label .BI\-\-\-cacert\~ file .OP \-\-caout file .OP \-\-outform encoding @@ -47,6 +48,9 @@ Read command line options from \fIfile\fR. .BI "\-u, \-\-url " url URL of the SCEP server. .TP +.BI "\-l, \-\-label " label +Label in the EST server path. +.TP .BI "\-C, \-\-cacert " file CA certificate in the trust chain used for EST TLS server signature verification. Can be used multiple times. -- 2.47.2