mirror of
https://github.com/moparisthebest/curl
synced 2025-02-28 17:31:46 -05:00
ssl: set engine implicitly when a PKCS#11 URI is provided
This allows the use of PKCS#11 URI for certificates and keys without setting the corresponding type as "ENG" and the engine as "pkcs11" explicitly. If a PKCS#11 URI is provided for certificate, key, proxy_certificate or proxy_key, the corresponding type is set as "ENG" if not provided and the engine is set to "pkcs11" if not provided. Acked-by: Nikos Mavrogiannopoulos Closes #2333
This commit is contained in:
parent
c892795ea3
commit
298d2565e2
@ -23,6 +23,13 @@ nickname contains ":", it needs to be preceded by "\\" so that it is not
|
|||||||
recognized as password delimiter. If the nickname contains "\\", it needs to
|
recognized as password delimiter. If the nickname contains "\\", it needs to
|
||||||
be escaped as "\\\\" so that it is not recognized as an escape character.
|
be escaped as "\\\\" so that it is not recognized as an escape character.
|
||||||
|
|
||||||
|
If curl is built against OpenSSL library, and the engine pkcs11 is available,
|
||||||
|
then a PKCS#11 URI (RFC 7512) can be used to specify a certificate located in
|
||||||
|
a PKCS#11 device. A string beginning with "pkcs11:" will be interpreted as a
|
||||||
|
PKCS#11 URI. If a PKCS#11 URI is provided, then the --engine option will be set
|
||||||
|
as "pkcs11" if none was provided and the --cert-type option will be set as
|
||||||
|
"ENG" if none was provided.
|
||||||
|
|
||||||
(iOS and macOS only) If curl is built against Secure Transport, then the
|
(iOS and macOS only) If curl is built against Secure Transport, then the
|
||||||
certificate string can either be the name of a certificate/private key in the
|
certificate string can either be the name of a certificate/private key in the
|
||||||
system or user keychain, or the path to a PKCS#12-encoded certificate and
|
system or user keychain, or the path to a PKCS#12-encoded certificate and
|
||||||
|
@ -7,4 +7,11 @@ Private key file name. Allows you to provide your private key in this separate
|
|||||||
file. For SSH, if not specified, curl tries the following candidates in order:
|
file. For SSH, if not specified, curl tries the following candidates in order:
|
||||||
'~/.ssh/id_rsa', '~/.ssh/id_dsa', './id_rsa', './id_dsa'.
|
'~/.ssh/id_rsa', '~/.ssh/id_dsa', './id_rsa', './id_dsa'.
|
||||||
|
|
||||||
|
If curl is built against OpenSSL library, and the engine pkcs11 is available,
|
||||||
|
then a PKCS#11 URI (RFC 7512) can be used to specify a private key located in a
|
||||||
|
PKCS#11 device. A string beginning with "pkcs11:" will be interpreted as a
|
||||||
|
PKCS#11 URI. If a PKCS#11 URI is provided, then the --engine option will be set
|
||||||
|
as "pkcs11" if none was provided and the --key-type option will be set as
|
||||||
|
"ENG" if none was provided.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
|
@ -558,8 +558,25 @@ static int ssl_ui_writer(UI *ui, UI_STRING *uis)
|
|||||||
}
|
}
|
||||||
return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
|
return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if a given string is a PKCS#11 URI
|
||||||
|
*/
|
||||||
|
static bool is_pkcs11_uri(const char *string)
|
||||||
|
{
|
||||||
|
if(strncasecompare(string, "pkcs11:", 7)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
|
||||||
|
const char *engine);
|
||||||
|
|
||||||
static
|
static
|
||||||
int cert_stuff(struct connectdata *conn,
|
int cert_stuff(struct connectdata *conn,
|
||||||
SSL_CTX* ctx,
|
SSL_CTX* ctx,
|
||||||
@ -622,6 +639,16 @@ int cert_stuff(struct connectdata *conn,
|
|||||||
case SSL_FILETYPE_ENGINE:
|
case SSL_FILETYPE_ENGINE:
|
||||||
#if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
|
#if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
|
||||||
{
|
{
|
||||||
|
/* Implicitly use pkcs11 engine if none was provided and the
|
||||||
|
* cert_file is a PKCS#11 URI */
|
||||||
|
if(!data->state.engine) {
|
||||||
|
if(is_pkcs11_uri(cert_file)) {
|
||||||
|
if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(data->state.engine) {
|
if(data->state.engine) {
|
||||||
const char *cmd_name = "LOAD_CERT_CTRL";
|
const char *cmd_name = "LOAD_CERT_CTRL";
|
||||||
struct {
|
struct {
|
||||||
@ -798,6 +825,17 @@ int cert_stuff(struct connectdata *conn,
|
|||||||
#ifdef USE_OPENSSL_ENGINE
|
#ifdef USE_OPENSSL_ENGINE
|
||||||
{ /* XXXX still needs some work */
|
{ /* XXXX still needs some work */
|
||||||
EVP_PKEY *priv_key = NULL;
|
EVP_PKEY *priv_key = NULL;
|
||||||
|
|
||||||
|
/* Implicitly use pkcs11 engine if none was provided and the
|
||||||
|
* key_file is a PKCS#11 URI */
|
||||||
|
if(!data->state.engine) {
|
||||||
|
if(is_pkcs11_uri(key_file)) {
|
||||||
|
if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(data->state.engine) {
|
if(data->state.engine) {
|
||||||
UI_METHOD *ui_method =
|
UI_METHOD *ui_method =
|
||||||
UI_create_method((char *)"curl user interface");
|
UI_create_method((char *)"curl user interface");
|
||||||
|
@ -342,7 +342,7 @@ void parse_cert_parameter(const char *cert_parameter,
|
|||||||
* looks like a RFC7512 PKCS#11 URI which can be used as-is.
|
* looks like a RFC7512 PKCS#11 URI which can be used as-is.
|
||||||
* Also if cert_parameter contains no colon nor backslash, this
|
* Also if cert_parameter contains no colon nor backslash, this
|
||||||
* means no passphrase was given and no characters escaped */
|
* means no passphrase was given and no characters escaped */
|
||||||
if(!strncmp(cert_parameter, "pkcs11:", 7) ||
|
if(curl_strnequal(cert_parameter, "pkcs11:", 7) ||
|
||||||
!strpbrk(cert_parameter, ":\\")) {
|
!strpbrk(cert_parameter, ":\\")) {
|
||||||
*certname = strdup(cert_parameter);
|
*certname = strdup(cert_parameter);
|
||||||
return;
|
return;
|
||||||
|
@ -113,6 +113,19 @@ static bool is_fatal_error(CURLcode code)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if a given string is a PKCS#11 URI
|
||||||
|
*/
|
||||||
|
static bool is_pkcs11_uri(const char *string)
|
||||||
|
{
|
||||||
|
if(curl_strnequal(string, "pkcs11:", 7)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __VMS
|
#ifdef __VMS
|
||||||
/*
|
/*
|
||||||
* get_vms_file_size does what it takes to get the real size of the file
|
* get_vms_file_size does what it takes to get the real size of the file
|
||||||
@ -1073,6 +1086,46 @@ static CURLcode operate_do(struct GlobalConfig *global,
|
|||||||
my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
|
my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
|
||||||
|
|
||||||
if(curlinfo->features & CURL_VERSION_SSL) {
|
if(curlinfo->features & CURL_VERSION_SSL) {
|
||||||
|
/* Check if config->cert is a PKCS#11 URI and set the
|
||||||
|
* config->cert_type if necessary */
|
||||||
|
if(config->cert) {
|
||||||
|
if(!config->cert_type) {
|
||||||
|
if(is_pkcs11_uri(config->cert)) {
|
||||||
|
config->cert_type = strdup("ENG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if config->key is a PKCS#11 URI and set the
|
||||||
|
* config->key_type if necessary */
|
||||||
|
if(config->key) {
|
||||||
|
if(!config->key_type) {
|
||||||
|
if(is_pkcs11_uri(config->key)) {
|
||||||
|
config->key_type = strdup("ENG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if config->proxy_cert is a PKCS#11 URI and set the
|
||||||
|
* config->proxy_type if necessary */
|
||||||
|
if(config->proxy_cert) {
|
||||||
|
if(!config->proxy_cert_type) {
|
||||||
|
if(is_pkcs11_uri(config->proxy_cert)) {
|
||||||
|
config->proxy_cert_type = strdup("ENG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if config->proxy_key is a PKCS#11 URI and set the
|
||||||
|
* config->proxy_key_type if necessary */
|
||||||
|
if(config->proxy_key) {
|
||||||
|
if(!config->proxy_key_type) {
|
||||||
|
if(is_pkcs11_uri(config->proxy_key)) {
|
||||||
|
config->proxy_key_type = strdup("ENG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my_setopt_str(curl, CURLOPT_SSLCERT, config->cert);
|
my_setopt_str(curl, CURLOPT_SSLCERT, config->cert);
|
||||||
my_setopt_str(curl, CURLOPT_PROXY_SSLCERT, config->proxy_cert);
|
my_setopt_str(curl, CURLOPT_PROXY_SSLCERT, config->proxy_cert);
|
||||||
my_setopt_str(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
|
my_setopt_str(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
|
||||||
|
@ -56,6 +56,9 @@ UNITTEST_START
|
|||||||
"foo:bar\\\\", "foo", "bar\\\\",
|
"foo:bar\\\\", "foo", "bar\\\\",
|
||||||
"foo:bar:", "foo", "bar:",
|
"foo:bar:", "foo", "bar:",
|
||||||
"foo\\::bar\\:", "foo:", "bar\\:",
|
"foo\\::bar\\:", "foo:", "bar\\:",
|
||||||
|
"pkcs11:foobar", "pkcs11:foobar", NULL,
|
||||||
|
"PKCS11:foobar", "PKCS11:foobar", NULL,
|
||||||
|
"PkCs11:foobar", "PkCs11:foobar", NULL,
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
"c:\\foo:bar:baz", "c:\\foo", "bar:baz",
|
"c:\\foo:bar:baz", "c:\\foo", "bar:baz",
|
||||||
"c:\\foo\\:bar:baz", "c:\\foo:bar", "baz",
|
"c:\\foo\\:bar:baz", "c:\\foo:bar", "baz",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user