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
This commit is contained in:
committed by
Tobias Brunner
parent
7a47adb4f0
commit
f6dc47f591
@@ -32,7 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
static int est()
|
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 *client_cert_file = NULL, *client_key_file = NULL;
|
||||||
char *keyid = NULL, *certid = NULL, *user_pass = NULL;
|
char *keyid = NULL, *certid = NULL, *user_pass = NULL;
|
||||||
cred_encoding_type_t form = CERT_ASN1_DER;
|
cred_encoding_type_t form = CERT_ASN1_DER;
|
||||||
@@ -60,6 +60,9 @@ static int est()
|
|||||||
case 'u': /* --url */
|
case 'u': /* --url */
|
||||||
url = arg;
|
url = arg;
|
||||||
continue;
|
continue;
|
||||||
|
case 'l': /* --label */
|
||||||
|
label = arg;
|
||||||
|
continue;
|
||||||
case 'i': /* --in */
|
case 'i': /* --in */
|
||||||
file = arg;
|
file = arg;
|
||||||
continue;
|
continue;
|
||||||
@@ -256,7 +259,7 @@ static int est()
|
|||||||
est_op = EST_SIMPLE_REENROLL;
|
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)
|
if (!est_tls)
|
||||||
{
|
{
|
||||||
DBG1(DBG_APP, "TLS connection to EST server was not established");
|
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);
|
DBG1(DBG_APP, " going to sleep for %d seconds", poll_interval);
|
||||||
sleep(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)
|
if (!est_tls)
|
||||||
{
|
{
|
||||||
DBG1(DBG_APP, "TLS connection to EST server was not established");
|
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"},
|
{"help", 'h', 0, "show usage information"},
|
||||||
{"url", 'u', 1, "URL of the EST server"},
|
{"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"},
|
{"in", 'i', 1, "PKCS#10 input file, default: stdin"},
|
||||||
{"cacert", 'C', 1, "CA certificate"},
|
{"cacert", 'C', 1, "CA certificate"},
|
||||||
{"cert", 'c', 1, "old certificate about to be renewed"},
|
{"cert", 'c', 1, "old certificate about to be renewed"},
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ static int estca()
|
|||||||
certificate_t *cacert;
|
certificate_t *cacert;
|
||||||
mem_cred_t *creds = NULL;
|
mem_cred_t *creds = NULL;
|
||||||
est_tls_t *est_tls;
|
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;
|
bool force = FALSE, success;
|
||||||
u_int http_code = 0;
|
u_int http_code = 0;
|
||||||
status_t status = 1;
|
status_t status = 1;
|
||||||
@@ -50,6 +50,9 @@ static int estca()
|
|||||||
case 'u': /* --url */
|
case 'u': /* --url */
|
||||||
url = arg;
|
url = arg;
|
||||||
continue;
|
continue;
|
||||||
|
case 'l': /* --label */
|
||||||
|
label = arg;
|
||||||
|
continue;
|
||||||
case 'C': /* --cacert */
|
case 'C': /* --cacert */
|
||||||
cacert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
|
cacert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
|
||||||
CERT_X509, BUILD_FROM_FILE, arg, BUILD_END);
|
CERT_X509, BUILD_FROM_FILE, arg, BUILD_END);
|
||||||
@@ -87,7 +90,7 @@ static int estca()
|
|||||||
return command_usage("--url is required");
|
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)
|
if (!est_tls)
|
||||||
{
|
{
|
||||||
DBG1(DBG_APP, "TLS connection to EST server was not established");
|
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]"},
|
{"--url url [--cacert file]+ [--caout file] [--outform der|pem] [--force]"},
|
||||||
{
|
{
|
||||||
{"help", 'h', 0, "show usage information"},
|
{"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"},
|
{"cacert", 'C', 1, "TLS CA certificate"},
|
||||||
{"caout", 'c', 1, "CA certificate [template]"},
|
{"caout", 'c', 1, "CA certificate [template]"},
|
||||||
{"outform", 'f', 1, "encoding of stored certificates, default: der"},
|
{"outform", 'f', 1, "encoding of stored certificates, default: der"},
|
||||||
|
|||||||
+23
-7
@@ -80,6 +80,11 @@ struct private_est_tls_t {
|
|||||||
*/
|
*/
|
||||||
char *http_path;
|
char *http_path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Label string used for http requests
|
||||||
|
*/
|
||||||
|
char *http_label;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional base64-encoded <username:password> for http basic authentication
|
* Optional base64-encoded <username:password> 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);
|
data = chunk_to_base64(in, NULL);
|
||||||
|
|
||||||
len = asprintf(&http_header,
|
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"
|
"Host: %s\r\n"
|
||||||
"%s"
|
"%s"
|
||||||
"Content-Type: %s\r\n"
|
"Content-Type: %s\r\n"
|
||||||
"Content-Length: %d\r\n"
|
"Content-Length: %d\r\n"
|
||||||
"\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);
|
request_types[op], (int)data.len);
|
||||||
if (len > 0)
|
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 */
|
else /* create HTTP GET request */
|
||||||
{
|
{
|
||||||
len = asprintf(&http_header,
|
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"
|
"Host: %s\r\n"
|
||||||
"%s"
|
"%s"
|
||||||
"\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);
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
request = chunk_create(http_header, len);
|
request = chunk_create(http_header, len);
|
||||||
@@ -289,11 +294,12 @@ METHOD(est_tls_t, destroy, void,
|
|||||||
}
|
}
|
||||||
chunk_clear(&this->user_pass);
|
chunk_clear(&this->user_pass);
|
||||||
free(this->http_host);
|
free(this->http_host);
|
||||||
|
free(this->http_label);
|
||||||
free(this->http_path);
|
free(this->http_path);
|
||||||
free(this);
|
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)
|
certificate_t *client_cert)
|
||||||
{
|
{
|
||||||
identification_t *client_id = NULL, *server_id = NULL;
|
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';
|
*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 <hostname:port> string since we are going to manipulate it */
|
/* duplicate <hostname:port> string since we are going to manipulate it */
|
||||||
host_str = strdup(uri);
|
host_str = strdup(uri);
|
||||||
|
|
||||||
@@ -392,7 +408,7 @@ end:
|
|||||||
/**
|
/**
|
||||||
* See header
|
* 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;
|
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);
|
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);
|
destroy(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -70,10 +70,11 @@ struct est_tls_t {
|
|||||||
* Create a est_tls instance.
|
* Create a est_tls instance.
|
||||||
*
|
*
|
||||||
* @param uri URI (https://...)
|
* @param uri URI (https://...)
|
||||||
|
* @param label Optional EST server label
|
||||||
* @param client_cert Optional client certificate
|
* @param client_cert Optional client certificate
|
||||||
* @param user_pass Optional username:password for HTTP Basic Authentication
|
* @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);
|
char *user_pass);
|
||||||
|
|
||||||
#endif /** EST_TLS_H_ @}*/
|
#endif /** EST_TLS_H_ @}*/
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ pki \-\-est \- Enroll an X.509 certificate with an EST server
|
|||||||
.
|
.
|
||||||
.SY pki\ \-\-est
|
.SY pki\ \-\-est
|
||||||
.BI\-\-\-url\~ url
|
.BI\-\-\-url\~ url
|
||||||
|
.OP \-\-label label
|
||||||
.OP \-\-in file
|
.OP \-\-in file
|
||||||
.BI \-\-cacert\~ file
|
.BI \-\-cacert\~ file
|
||||||
.RB [ \-\-cert
|
.RB [ \-\-cert
|
||||||
@@ -61,6 +62,9 @@ Read command line options from \fIfile\fR.
|
|||||||
.BI "\-u, \-\-url " url
|
.BI "\-u, \-\-url " url
|
||||||
URL of the EST server.
|
URL of the EST server.
|
||||||
.TP
|
.TP
|
||||||
|
.BI "\-l, \-\-label " label
|
||||||
|
Label in the EST server path.
|
||||||
|
.TP
|
||||||
.BI "\-i, \-\-in " file
|
.BI "\-i, \-\-in " file
|
||||||
PKCS#10 certificate request. If not given, the certificate request is read from
|
PKCS#10 certificate request. If not given, the certificate request is read from
|
||||||
\fISTDIN\fR.
|
\fISTDIN\fR.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ pki \-\-estca \- Get CA certificate[s] from an EST server
|
|||||||
.
|
.
|
||||||
.SY pki\ \-\-estca
|
.SY pki\ \-\-estca
|
||||||
.BI\-\-\-url\~ url
|
.BI\-\-\-url\~ url
|
||||||
|
.OP \-\-label label
|
||||||
.BI\-\-\-cacert\~ file
|
.BI\-\-\-cacert\~ file
|
||||||
.OP \-\-caout file
|
.OP \-\-caout file
|
||||||
.OP \-\-outform encoding
|
.OP \-\-outform encoding
|
||||||
@@ -47,6 +48,9 @@ Read command line options from \fIfile\fR.
|
|||||||
.BI "\-u, \-\-url " url
|
.BI "\-u, \-\-url " url
|
||||||
URL of the SCEP server.
|
URL of the SCEP server.
|
||||||
.TP
|
.TP
|
||||||
|
.BI "\-l, \-\-label " label
|
||||||
|
Label in the EST server path.
|
||||||
|
.TP
|
||||||
.BI "\-C, \-\-cacert " file
|
.BI "\-C, \-\-cacert " file
|
||||||
CA certificate in the trust chain used for EST TLS server signature verification.
|
CA certificate in the trust chain used for EST TLS server signature verification.
|
||||||
Can be used multiple times.
|
Can be used multiple times.
|
||||||
|
|||||||
Reference in New Issue
Block a user