mirror of
https://github.com/curl/curl.git
synced 2026-07-31 11:38:06 +03:00
openssl: change default file type to provider
Openssl 3+ encourages using providers for all data storages. This commit sets it as the default file type when supported, when the file type is not explicitly defined (instead of PEM by default). This change also removes the explicit check on a provider being loaded, before trying to open the matching store: openssl should raise an explicit error when opening it, and an explicit check in libcurl breaks the possibility of a default provider in Openssl. This change should not have any impact on behavior, since openssl default implementation embeds a provider for PEM file types. This change full leverages the Openssl store providers: with this, the end user does not need to maintain the actual storage type in calls to libcurl, and can freely ignore storage types by changing the URI (or file path).
This commit is contained in:
parent
372d721e92
commit
a27665b872
1 changed files with 99 additions and 105 deletions
|
|
@ -861,7 +861,11 @@ static CURLcode ossl_seed(struct Curl_easy *data)
|
|||
static int ossl_do_file_type(const char *type)
|
||||
{
|
||||
if(!type || !type[0])
|
||||
#ifdef OPENSSL_HAS_PROVIDERS
|
||||
return SSL_FILETYPE_PROVIDER;
|
||||
#else
|
||||
return SSL_FILETYPE_PEM;
|
||||
#endif
|
||||
if(curl_strequal(type, "PEM"))
|
||||
return SSL_FILETYPE_PEM;
|
||||
if(curl_strequal(type, "DER"))
|
||||
|
|
@ -1113,6 +1117,10 @@ static int providercheck(struct Curl_easy *data,
|
|||
const char *key_file)
|
||||
{
|
||||
#ifdef OPENSSL_HAS_PROVIDERS
|
||||
EVP_PKEY *priv_key = NULL;
|
||||
OSSL_STORE_CTX *store = NULL;
|
||||
OSSL_STORE_INFO *info = NULL;
|
||||
UI_METHOD *ui_method = NULL;
|
||||
char error_buffer[256];
|
||||
/* Implicitly use pkcs11 provider if none was provided and the
|
||||
* key_file is a PKCS#11 URI */
|
||||
|
|
@ -1124,67 +1132,58 @@ static int providercheck(struct Curl_easy *data,
|
|||
}
|
||||
}
|
||||
|
||||
if(data->state.provider_loaded) {
|
||||
/* Load the private key from the provider */
|
||||
EVP_PKEY *priv_key = NULL;
|
||||
OSSL_STORE_CTX *store = NULL;
|
||||
OSSL_STORE_INFO *info = NULL;
|
||||
UI_METHOD *ui_method = UI_create_method("curl user interface");
|
||||
if(!ui_method) {
|
||||
failf(data, "unable to create " OSSL_PACKAGE " user-interface method");
|
||||
return 0;
|
||||
}
|
||||
UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL()));
|
||||
UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL()));
|
||||
UI_method_set_reader(ui_method, ssl_ui_reader);
|
||||
UI_method_set_writer(ui_method, ssl_ui_writer);
|
||||
|
||||
store = OSSL_STORE_open_ex(key_file, data->state.libctx,
|
||||
data->state.propq, ui_method, NULL, NULL,
|
||||
NULL, NULL);
|
||||
if(!store) {
|
||||
failf(data, "Failed to open OpenSSL store: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
UI_destroy_method(ui_method);
|
||||
return 0;
|
||||
}
|
||||
if(OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY) != 1) {
|
||||
failf(data, "Failed to set store preference. Ignoring the error: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
}
|
||||
|
||||
info = OSSL_STORE_load(store);
|
||||
if(info) {
|
||||
int ossl_type = OSSL_STORE_INFO_get_type(info);
|
||||
|
||||
if(ossl_type == OSSL_STORE_INFO_PKEY)
|
||||
priv_key = OSSL_STORE_INFO_get1_PKEY(info);
|
||||
OSSL_STORE_INFO_free(info);
|
||||
}
|
||||
OSSL_STORE_close(store);
|
||||
UI_destroy_method(ui_method);
|
||||
if(!priv_key) {
|
||||
failf(data, "No private key found in the openssl store: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
|
||||
failf(data, "unable to set private key [%s]",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
EVP_PKEY_free(priv_key);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_free(priv_key); /* we do not need the handle any more... */
|
||||
}
|
||||
else {
|
||||
failf(data, "crypto provider not set, cannot load private key");
|
||||
/* Load the private key from the provider */
|
||||
ui_method = UI_create_method("curl user interface");
|
||||
if(!ui_method) {
|
||||
failf(data, "unable to create " OSSL_PACKAGE " user-interface method");
|
||||
return 0;
|
||||
}
|
||||
UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL()));
|
||||
UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL()));
|
||||
UI_method_set_reader(ui_method, ssl_ui_reader);
|
||||
UI_method_set_writer(ui_method, ssl_ui_writer);
|
||||
|
||||
store = OSSL_STORE_open_ex(key_file, data->state.libctx,
|
||||
data->state.propq, ui_method, NULL, NULL,
|
||||
NULL, NULL);
|
||||
if(!store) {
|
||||
failf(data, "Failed to open OpenSSL store: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
UI_destroy_method(ui_method);
|
||||
return 0;
|
||||
}
|
||||
if(OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY) != 1) {
|
||||
failf(data, "Failed to set store preference. Ignoring the error: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
}
|
||||
|
||||
info = OSSL_STORE_load(store);
|
||||
if(info) {
|
||||
int ossl_type = OSSL_STORE_INFO_get_type(info);
|
||||
|
||||
if(ossl_type == OSSL_STORE_INFO_PKEY)
|
||||
priv_key = OSSL_STORE_INFO_get1_PKEY(info);
|
||||
OSSL_STORE_INFO_free(info);
|
||||
}
|
||||
OSSL_STORE_close(store);
|
||||
UI_destroy_method(ui_method);
|
||||
if(!priv_key) {
|
||||
failf(data, "No private key found in the openssl store: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
|
||||
failf(data, "unable to set private key [%s]",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
EVP_PKEY_free(priv_key);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_free(priv_key); /* we do not need the handle any more... */
|
||||
return 1;
|
||||
#else
|
||||
(void)ctx;
|
||||
|
|
@ -1269,6 +1268,10 @@ static int providerload(struct Curl_easy *data,
|
|||
const char *cert_file)
|
||||
{
|
||||
#ifdef OPENSSL_HAS_PROVIDERS
|
||||
OSSL_STORE_INFO *info = NULL;
|
||||
X509 *cert = NULL;
|
||||
OSSL_STORE_CTX *store = NULL;
|
||||
int rc;
|
||||
char error_buffer[256];
|
||||
/* Implicitly use pkcs11 provider if none was provided and the
|
||||
* cert_file is a PKCS#11 URI */
|
||||
|
|
@ -1280,55 +1283,46 @@ static int providerload(struct Curl_easy *data,
|
|||
}
|
||||
}
|
||||
|
||||
if(data->state.provider_loaded) {
|
||||
/* Load the certificate from the provider */
|
||||
OSSL_STORE_INFO *info = NULL;
|
||||
X509 *cert = NULL;
|
||||
OSSL_STORE_CTX *store =
|
||||
OSSL_STORE_open_ex(cert_file, data->state.libctx,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
int rc;
|
||||
/* Load the certificate from the provider */
|
||||
|
||||
if(!store) {
|
||||
failf(data, "Failed to open OpenSSL store: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
return 0;
|
||||
}
|
||||
if(OSSL_STORE_expect(store, OSSL_STORE_INFO_CERT) != 1) {
|
||||
failf(data, "Failed to set store preference. Ignoring the error: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
}
|
||||
store = OSSL_STORE_open_ex(cert_file, data->state.libctx,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
info = OSSL_STORE_load(store);
|
||||
if(info) {
|
||||
int ossl_type = OSSL_STORE_INFO_get_type(info);
|
||||
|
||||
if(ossl_type == OSSL_STORE_INFO_CERT)
|
||||
cert = OSSL_STORE_INFO_get1_CERT(info);
|
||||
OSSL_STORE_INFO_free(info);
|
||||
}
|
||||
OSSL_STORE_close(store);
|
||||
if(!cert) {
|
||||
failf(data, "No cert found in the openssl store: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = SSL_CTX_use_certificate(ctx, cert);
|
||||
X509_free(cert); /* we do not need the handle any more... */
|
||||
|
||||
if(rc != 1) {
|
||||
failf(data, "unable to set client certificate [%s]",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
return 0;
|
||||
}
|
||||
if(!store) {
|
||||
failf(data, "Failed to open OpenSSL store: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
failf(data, "crypto provider not set, cannot load certificate");
|
||||
if(OSSL_STORE_expect(store, OSSL_STORE_INFO_CERT) != 1) {
|
||||
failf(data, "Failed to set store preference. Ignoring the error: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
}
|
||||
|
||||
info = OSSL_STORE_load(store);
|
||||
if(info) {
|
||||
int ossl_type = OSSL_STORE_INFO_get_type(info);
|
||||
|
||||
if(ossl_type == OSSL_STORE_INFO_CERT)
|
||||
cert = OSSL_STORE_INFO_get1_CERT(info);
|
||||
OSSL_STORE_INFO_free(info);
|
||||
}
|
||||
OSSL_STORE_close(store);
|
||||
if(!cert) {
|
||||
failf(data, "No cert found in the openssl store: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = SSL_CTX_use_certificate(ctx, cert);
|
||||
X509_free(cert); /* we do not need the handle any more... */
|
||||
|
||||
if(rc != 1) {
|
||||
failf(data, "unable to set client certificate [%s]",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
sizeof(error_buffer)));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue