From: Tobias Brunner Date: Thu, 24 Jul 2025 14:03:15 +0000 (+0200) Subject: openssl: Simplify wrapping private key objects X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2F2848-openssl-pkcs12-eddsa;p=thirdparty%2Fstrongswan.git openssl: Simplify wrapping private key objects --- diff --git a/src/libstrongswan/plugins/openssl/openssl_engine.c b/src/libstrongswan/plugins/openssl/openssl_engine.c index 7a7082b074..7ae67588b2 100644 --- a/src/libstrongswan/plugins/openssl/openssl_engine.c +++ b/src/libstrongswan/plugins/openssl/openssl_engine.c @@ -29,9 +29,7 @@ #include -#include "openssl_ec_private_key.h" -#include "openssl_ed_private_key.h" -#include "openssl_rsa_private_key.h" +#include "openssl_util.h" /** * Login to engine with a PIN specified for a keyid @@ -156,27 +154,7 @@ private_key_t *openssl_private_key_connect(key_type_t type, va_list args) "engine '%s'", keyname, engine_id); return NULL; } - - switch (EVP_PKEY_base_id(key)) - { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - return openssl_rsa_private_key_create(key, TRUE); -#endif -#ifndef OPENSSL_NO_ECDSA - case EVP_PKEY_EC: - return openssl_ec_private_key_create(key, TRUE); -#endif -#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC) - case EVP_PKEY_ED25519: - case EVP_PKEY_ED448: - return openssl_ed_private_key_create(key, TRUE); -#endif /* OPENSSL_VERSION_NUMBER */ - default: - EVP_PKEY_free(key); - break; - } - return NULL; + return openssl_wrap_private_key(key, TRUE); } /* diff --git a/src/libstrongswan/plugins/openssl/openssl_pkcs12.c b/src/libstrongswan/plugins/openssl/openssl_pkcs12.c index 40ddcfd4a2..cba968b91a 100644 --- a/src/libstrongswan/plugins/openssl/openssl_pkcs12.c +++ b/src/libstrongswan/plugins/openssl/openssl_pkcs12.c @@ -103,45 +103,17 @@ static bool add_cas(private_pkcs12_t *this, STACK_OF(X509) *cas) */ static bool add_key(private_pkcs12_t *this, EVP_PKEY *private) { - private_key_t *key = NULL; - chunk_t encoding; - key_type_t type; + private_key_t *key; if (!private) { /* no private key is ok */ return TRUE; } - switch (EVP_PKEY_base_id(private)) - { - case EVP_PKEY_RSA: - type = KEY_RSA; - break; - case EVP_PKEY_EC: - type = KEY_ECDSA; - break; - case EVP_PKEY_ED25519: - type = KEY_ED25519; - break; - case EVP_PKEY_ED448: - type = KEY_ED448; - break; - default: - EVP_PKEY_free(private); - return FALSE; - } - encoding = openssl_i2chunk(PrivateKey, private); - if (encoding.ptr) + key = openssl_wrap_private_key(private, FALSE); + if (key) { - key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type, - BUILD_BLOB_ASN1_DER, encoding, - BUILD_END); - if (key) - { - this->creds->add_key(this->creds, key); - } + this->creds->add_key(this->creds, key); } - chunk_clear(&encoding); - EVP_PKEY_free(private); return key != NULL; } diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c index e5d2022aa7..2ee4d4569f 100644 --- a/src/libstrongswan/plugins/openssl/openssl_plugin.c +++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c @@ -290,29 +290,7 @@ static private_key_t *openssl_private_key_load(key_type_t type, va_list args) if (blob.ptr) { key = d2i_AutoPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len); - if (key) - { - switch (EVP_PKEY_base_id(key)) - { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - return openssl_rsa_private_key_create(key, FALSE); -#endif -#ifndef OPENSSL_NO_ECDSA - case EVP_PKEY_EC: - return openssl_ec_private_key_create(key, FALSE); -#endif -#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC) && \ - !defined(OPENSSL_IS_AWSLC) - case EVP_PKEY_ED25519: - case EVP_PKEY_ED448: - return openssl_ed_private_key_create(key, FALSE); -#endif /* OPENSSL_VERSION_NUMBER && !OPENSSL_NO_EC && !OPENSSL_IS_AWSLC */ - default: - EVP_PKEY_free(key); - break; - } - } + return openssl_wrap_private_key(key, FALSE); } return NULL; } diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c index 7b74d27051..43bf2a752b 100644 --- a/src/libstrongswan/plugins/openssl/openssl_util.c +++ b/src/libstrongswan/plugins/openssl/openssl_util.c @@ -28,6 +28,10 @@ #include #endif +#include "openssl_ec_private_key.h" +#include "openssl_ed_private_key.h" +#include "openssl_rsa_private_key.h" + /* these were added with 1.1.0 when ASN1_OBJECT was made opaque */ #if OPENSSL_VERSION_NUMBER < 0x10100000L #define OBJ_get0_data(o) ((o)->data) @@ -136,6 +140,37 @@ bool openssl_fingerprint(EVP_PKEY *key, cred_encoding_type_t type, chunk_t *fp) return TRUE; } +/* + * Described in header + */ +private_key_t *openssl_wrap_private_key(EVP_PKEY *key, bool engine) +{ + if (key) + { + switch (EVP_PKEY_base_id(key)) + { +#ifndef OPENSSL_NO_RSA + case EVP_PKEY_RSA: + return openssl_rsa_private_key_create(key, engine); +#endif +#ifndef OPENSSL_NO_ECDSA + case EVP_PKEY_EC: + return openssl_ec_private_key_create(key, engine); +#endif +#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC) && \ +!defined(OPENSSL_IS_AWSLC) + case EVP_PKEY_ED25519: + case EVP_PKEY_ED448: + return openssl_ed_private_key_create(key, engine); +#endif /* OPENSSL_VERSION_NUMBER && !OPENSSL_NO_EC && !OPENSSL_IS_AWSLC */ + default: + EVP_PKEY_free(key); + break; + } + } + return NULL; +} + /** * Described in header. */ diff --git a/src/libstrongswan/plugins/openssl/openssl_util.h b/src/libstrongswan/plugins/openssl/openssl_util.h index 78e23f58c6..8e6f001993 100644 --- a/src/libstrongswan/plugins/openssl/openssl_util.h +++ b/src/libstrongswan/plugins/openssl/openssl_util.h @@ -57,6 +57,15 @@ bool openssl_compute_shared_key(EVP_PKEY *priv, EVP_PKEY *pub, chunk_t *shared); */ bool openssl_fingerprint(EVP_PKEY *key, cred_encoding_type_t type, chunk_t *fp); +/** + * Wrap the given OpenSSL private key in a type-specific private key object. + * + * @param key key object to wrap + * @param engine TRUE if key can't be accessed directly + * @returns created object or NULL if key type is not supported + */ +private_key_t *openssl_wrap_private_key(EVP_PKEY *key, bool engine); + /** * Concatenates two bignums into a chunk, thereby enforcing the length of * a single BIGNUM, if necessary, by prepending it with zeros.