4070 lines
128 KiB
Diff
4070 lines
128 KiB
Diff
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||
|
index a64b7708..535c74a9 100644
|
||
|
--- a/CMakeLists.txt
|
||
|
+++ b/CMakeLists.txt
|
||
|
@@ -89,13 +89,6 @@ if (WITH_GSSAPI)
|
||
|
find_package(GSSAPI)
|
||
|
endif (WITH_GSSAPI)
|
||
|
|
||
|
-if (WITH_PKCS11_URI)
|
||
|
- find_package(softhsm)
|
||
|
- if (NOT SOFTHSM_FOUND)
|
||
|
- message(SEND_ERROR "Could not find softhsm module!")
|
||
|
- endif (NOT SOFTHSM_FOUND)
|
||
|
-endif (WITH_PKCS11_URI)
|
||
|
-
|
||
|
if (WITH_NACL)
|
||
|
find_package(NaCl)
|
||
|
if (NOT NACL_FOUND)
|
||
|
@@ -239,6 +232,7 @@ message(STATUS "Unit testing: ${UNIT_TESTING}")
|
||
|
message(STATUS "Client code testing: ${CLIENT_TESTING}")
|
||
|
message(STATUS "Blowfish cipher support: ${WITH_BLOWFISH_CIPHER}")
|
||
|
message(STATUS "PKCS #11 URI support: ${WITH_PKCS11_URI}")
|
||
|
+message(STATUS "With PKCS #11 provider support: ${WITH_PKCS11_PROVIDER}")
|
||
|
message(STATUS "DSA support: ${WITH_DSA}")
|
||
|
set(_SERVER_TESTING OFF)
|
||
|
if (WITH_SERVER)
|
||
|
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
|
||
|
index 9de10225..06ed23c8 100644
|
||
|
--- a/ConfigureChecks.cmake
|
||
|
+++ b/ConfigureChecks.cmake
|
||
|
@@ -489,12 +489,21 @@ if (WITH_PKCS11_URI)
|
||
|
if (WITH_GCRYPT)
|
||
|
message(FATAL_ERROR "PKCS #11 is not supported for gcrypt.")
|
||
|
set(WITH_PKCS11_URI 0)
|
||
|
- endif()
|
||
|
- if (WITH_MBEDTLS)
|
||
|
+ elseif (WITH_MBEDTLS)
|
||
|
message(FATAL_ERROR "PKCS #11 is not supported for mbedcrypto")
|
||
|
set(WITH_PKCS11_URI 0)
|
||
|
- endif()
|
||
|
- if (HAVE_OPENSSL AND NOT OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.1")
|
||
|
+ elseif (OPENSSL_FOUND AND OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0")
|
||
|
+ find_library(PKCS11_PROVIDER
|
||
|
+ NAMES
|
||
|
+ pkcs11.so
|
||
|
+ PATH_SUFFIXES
|
||
|
+ ossl-modules
|
||
|
+ )
|
||
|
+ if (NOT PKCS11_PROVIDER)
|
||
|
+ set(WITH_PKCS11_PROVIDER 0)
|
||
|
+ message(WARNING "Could not find pkcs11 provider! Falling back to engines")
|
||
|
+ endif (NOT PKCS11_PROVIDER)
|
||
|
+ elseif (HAVE_OPENSSL AND NOT OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.1")
|
||
|
message(FATAL_ERROR "PKCS #11 requires at least OpenSSL 1.1.1")
|
||
|
set(WITH_PKCS11_URI 0)
|
||
|
endif()
|
||
|
diff --git a/DefineOptions.cmake b/DefineOptions.cmake
|
||
|
index 6881b9a2..bc32abe5 100644
|
||
|
--- a/DefineOptions.cmake
|
||
|
+++ b/DefineOptions.cmake
|
||
|
@@ -13,6 +13,7 @@ option(WITH_PCAP "Compile with Pcap generation support" ON)
|
||
|
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
|
||
|
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||
|
option(WITH_PKCS11_URI "Build with PKCS#11 URI support" OFF)
|
||
|
+option(WITH_PKCS11_PROVIDER "Use the PKCS#11 provider for accessing pkcs11 objects" OFF)
|
||
|
option(UNIT_TESTING "Build with unit tests" OFF)
|
||
|
option(CLIENT_TESTING "Build with client tests; requires openssh" OFF)
|
||
|
option(SERVER_TESTING "Build with server tests; requires openssh and dropbear" OFF)
|
||
|
diff --git a/config.h.cmake b/config.h.cmake
|
||
|
index cc83734d..409f5d0d 100644
|
||
|
--- a/config.h.cmake
|
||
|
+++ b/config.h.cmake
|
||
|
@@ -276,6 +276,9 @@
|
||
|
/* Define to 1 if you want to enable PKCS #11 URI support */
|
||
|
#cmakedefine WITH_PKCS11_URI 1
|
||
|
|
||
|
+/* Define to 1 if we want to build a support for PKCS #11 provider. */
|
||
|
+#cmakedefine WITH_PKCS11_PROVIDER 1
|
||
|
+
|
||
|
/*************************** ENDIAN *****************************/
|
||
|
|
||
|
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||
|
diff --git a/doc/pkcs11.dox b/doc/pkcs11.dox
|
||
|
index 0bdfc6dc..c2732a81 100644
|
||
|
--- a/doc/pkcs11.dox
|
||
|
+++ b/doc/pkcs11.dox
|
||
|
@@ -9,11 +9,11 @@ objects stored on the tokens can be uniquely identified is called PKCS #11 URI
|
||
|
(Uniform Resource Identifier) and is defined in RFC 7512
|
||
|
(https://tools.ietf.org/html/rfc7512).
|
||
|
|
||
|
-Pre-requisites:
|
||
|
+# Pre-requisites (OpenSSL < 3.0):
|
||
|
|
||
|
-OpenSSL defines an abstract layer called the "engine" to achieve cryptographic
|
||
|
-acceleration. The engine_pkcs11 module acts like an interface between the PKCS #11
|
||
|
-modules and the OpenSSL engine.
|
||
|
+OpenSSL 1.x defines an abstract layer called the "engine" to achieve
|
||
|
+cryptographic acceleration. The engine_pkcs11 module acts like an interface
|
||
|
+between the PKCS #11 modules and the OpenSSL application.
|
||
|
|
||
|
To build and use libssh with PKCS #11 support:
|
||
|
1. Enable the cmake option: $ cmake -DWITH_PKCS11_URI=ON
|
||
|
@@ -21,6 +21,20 @@ To build and use libssh with PKCS #11 support:
|
||
|
3. Install and configure engine_pkcs11 (https://github.com/OpenSC/libp11).
|
||
|
4. Plug in a working smart card or configure softhsm (https://www.opendnssec.org/softhsm).
|
||
|
|
||
|
+# Pre-requisites (OpenSSL 3.0.8+)
|
||
|
+
|
||
|
+The OpenSSL 3.0 is deprecating usage of low-level engines in favor of high-level
|
||
|
+"providers" to provide alternative implementation of cryptographic operations
|
||
|
+or acceleration.
|
||
|
+
|
||
|
+To build and use libssh with PKCS #11 support using OpenSSL providers:
|
||
|
+1. Install and configure pkcs11 provider (https://github.com/latchset/pkcs11-provider).
|
||
|
+2. Enable the cmake options: $ cmake -DWITH_PKCS11_URI=ON -DWITH_PKCS11_PROVIDER=ON
|
||
|
+3. Build with OpenSSL.
|
||
|
+4. Plug in a working smart card or configure softhsm (https://www.opendnssec.org/softhsm).
|
||
|
+
|
||
|
+# New API functions
|
||
|
+
|
||
|
The functions ssh_pki_import_pubkey_file() and ssh_pki_import_privkey_file() that
|
||
|
import the public and private keys from files respectively are now modified to support
|
||
|
PKCS #11 URIs. These functions automatically detect if the provided filename is a file path
|
||
|
@@ -31,7 +45,7 @@ corresponding to the PKCS #11 URI are loaded from the PKCS #11 device.
|
||
|
If you wish to authenticate using public keys on your own, follow the steps mentioned under
|
||
|
"Authentication with public keys" in Chapter 2 - A deeper insight into authentication.
|
||
|
|
||
|
-The function pki_uri_import() is used to populate the public/private ssh_key from the
|
||
|
+The function pki_uri_import() is used to populate the public/private ssh_key from the
|
||
|
engine with PKCS #11 URIs as the look up.
|
||
|
|
||
|
Here is a minimalistic example of public key authentication using PKCS #11 URIs:
|
||
|
@@ -64,4 +78,10 @@ We recommend the users to provide a specific PKCS #11 URI so that it matches onl
|
||
|
If the engine discovers multiple slots that could potentially contain the private keys referenced
|
||
|
by the provided PKCS #11 URI, the engine will not try to authenticate.
|
||
|
|
||
|
+For testing, the SoftHSM PKCS#11 library is used. But it has some issues with
|
||
|
+OpenSSL initialization/cleanup when used with OpenSSL 3.0 so we are using it
|
||
|
+indirectly through a p11-kit remoting as described in the following article:
|
||
|
+
|
||
|
+https://p11-glue.github.io/p11-glue/p11-kit/manual/remoting.html
|
||
|
+
|
||
|
*/
|
||
|
diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h
|
||
|
index 3dba18d0..32016827 100644
|
||
|
--- a/include/libssh/crypto.h
|
||
|
+++ b/include/libssh/crypto.h
|
||
|
@@ -111,11 +111,7 @@ struct ssh_crypto_struct {
|
||
|
#endif /* WITH_GEX */
|
||
|
#ifdef HAVE_ECDH
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
EC_KEY *ecdh_privkey;
|
||
|
#else
|
||
|
EVP_PKEY *ecdh_privkey;
|
||
|
@@ -227,7 +223,7 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
|
||
|
size_t requested_len);
|
||
|
|
||
|
int secure_memcmp(const void *s1, const void *s2, size_t n);
|
||
|
-#ifdef HAVE_LIBCRYPTO
|
||
|
+#if defined(HAVE_LIBCRYPTO) && !defined(WITH_PKCS11_PROVIDER)
|
||
|
ENGINE *pki_get_engine(void);
|
||
|
#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
diff --git a/include/libssh/keys.h b/include/libssh/keys.h
|
||
|
index 615f1eae..79bba747 100644
|
||
|
--- a/include/libssh/keys.h
|
||
|
+++ b/include/libssh/keys.h
|
||
|
@@ -32,12 +32,7 @@ struct ssh_public_key_struct {
|
||
|
gcry_sexp_t dsa_pub;
|
||
|
gcry_sexp_t rsa_pub;
|
||
|
#elif defined(HAVE_LIBCRYPTO)
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- DSA *dsa_pub;
|
||
|
- RSA *rsa_pub;
|
||
|
-#else /* OPENSSL_VERSION_NUMBER */
|
||
|
EVP_PKEY *key_pub;
|
||
|
-#endif
|
||
|
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||
|
mbedtls_pk_context *rsa_pub;
|
||
|
void *dsa_pub;
|
||
|
@@ -50,12 +45,7 @@ struct ssh_private_key_struct {
|
||
|
gcry_sexp_t dsa_priv;
|
||
|
gcry_sexp_t rsa_priv;
|
||
|
#elif defined(HAVE_LIBCRYPTO)
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- DSA *dsa_priv;
|
||
|
- RSA *rsa_priv;
|
||
|
-#else
|
||
|
EVP_PKEY *key_priv;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||
|
mbedtls_pk_context *rsa_priv;
|
||
|
void *dsa_priv;
|
||
|
diff --git a/include/libssh/libcrypto.h b/include/libssh/libcrypto.h
|
||
|
index 87f30a4d..3abfa814 100644
|
||
|
--- a/include/libssh/libcrypto.h
|
||
|
+++ b/include/libssh/libcrypto.h
|
||
|
@@ -25,6 +25,7 @@
|
||
|
|
||
|
#ifdef HAVE_LIBCRYPTO
|
||
|
|
||
|
+#include "libssh/libssh.h"
|
||
|
#include <openssl/dsa.h>
|
||
|
#include <openssl/rsa.h>
|
||
|
#include <openssl/sha.h>
|
||
|
@@ -32,6 +33,7 @@
|
||
|
#include <openssl/hmac.h>
|
||
|
#include <openssl/evp.h>
|
||
|
#include <openssl/crypto.h>
|
||
|
+#include <openssl/ec.h>
|
||
|
|
||
|
typedef EVP_MD_CTX* SHACTX;
|
||
|
typedef EVP_MD_CTX* SHA256CTX;
|
||
|
@@ -111,6 +113,8 @@ typedef BN_CTX* bignum_CTX;
|
||
|
#define ssh_fips_mode() false
|
||
|
#endif
|
||
|
|
||
|
+ssh_string pki_key_make_ecpoint_string(const EC_GROUP *g, const EC_POINT *p);
|
||
|
+int pki_key_ecgroup_name_to_nid(const char *group);
|
||
|
#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
#endif /* LIBCRYPTO_H_ */
|
||
|
diff --git a/include/libssh/pki.h b/include/libssh/pki.h
|
||
|
index 879a1d5c..10814f5b 100644
|
||
|
--- a/include/libssh/pki.h
|
||
|
+++ b/include/libssh/pki.h
|
||
|
@@ -65,21 +65,8 @@ struct ssh_key_struct {
|
||
|
mbedtls_ecdsa_context *ecdsa;
|
||
|
void *dsa;
|
||
|
#elif defined(HAVE_LIBCRYPTO)
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- DSA *dsa;
|
||
|
- RSA *rsa;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Move into the #if above
|
||
|
- */
|
||
|
-# if defined(HAVE_OPENSSL_ECC)
|
||
|
- EC_KEY *ecdsa;
|
||
|
-# else
|
||
|
- void *ecdsa;
|
||
|
-# endif /* HAVE_OPENSSL_EC_H */
|
||
|
/* This holds either ENGINE key for PKCS#11 support or just key in
|
||
|
- * high-level format required by OpenSSL 3.0 */
|
||
|
+ * high-level format */
|
||
|
EVP_PKEY *key;
|
||
|
#endif /* HAVE_LIBGCRYPT */
|
||
|
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ED25519)
|
||
|
@@ -108,7 +95,7 @@ struct ssh_signature_struct {
|
||
|
#endif /* HAVE_LIBGCRYPT */
|
||
|
#if !defined(HAVE_LIBCRYPTO) || !defined(HAVE_OPENSSL_ED25519)
|
||
|
ed25519_signature *ed25519_sig;
|
||
|
-#endif
|
||
|
+#endif /* HAVE_LIBGCRYPT */
|
||
|
ssh_string raw_sig;
|
||
|
|
||
|
/* Security Key specific additions */
|
||
|
diff --git a/src/auth.c b/src/auth.c
|
||
|
index 4feb6558..c48eea5e 100644
|
||
|
--- a/src/auth.c
|
||
|
+++ b/src/auth.c
|
||
|
@@ -1409,21 +1409,21 @@ int ssh_userauth_agent_pubkey(ssh_session session,
|
||
|
key->type = publickey->type;
|
||
|
key->type_c = ssh_key_type_to_char(key->type);
|
||
|
key->flags = SSH_KEY_FLAG_PUBLIC;
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
key->dsa = publickey->dsa_pub;
|
||
|
key->rsa = publickey->rsa_pub;
|
||
|
#else
|
||
|
key->key = publickey->key_pub;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
rc = ssh_userauth_agent_publickey(session, username, key);
|
||
|
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
key->dsa = NULL;
|
||
|
key->rsa = NULL;
|
||
|
#else
|
||
|
key->key = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
ssh_key_free(key);
|
||
|
|
||
|
return rc;
|
||
|
diff --git a/src/ecdh_crypto.c b/src/ecdh_crypto.c
|
||
|
index 069b1372..a8bce894 100644
|
||
|
--- a/src/ecdh_crypto.c
|
||
|
+++ b/src/ecdh_crypto.c
|
||
|
@@ -30,11 +30,7 @@
|
||
|
|
||
|
#ifdef HAVE_ECDH
|
||
|
#include <openssl/ecdh.h>
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
#define NISTP256 NID_X9_62_prime256v1
|
||
|
#define NISTP384 NID_secp384r1
|
||
|
#define NISTP521 NID_secp521r1
|
||
|
@@ -48,11 +44,7 @@
|
||
|
/** @internal
|
||
|
* @brief Map the given key exchange enum value to its curve name.
|
||
|
*/
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
static int ecdh_kex_type_to_curve(enum ssh_key_exchange_e kex_type) {
|
||
|
#else
|
||
|
static const char *ecdh_kex_type_to_curve(enum ssh_key_exchange_e kex_type) {
|
||
|
@@ -64,183 +56,156 @@ static const char *ecdh_kex_type_to_curve(enum ssh_key_exchange_e kex_type) {
|
||
|
} else if (kex_type == SSH_KEX_ECDH_SHA2_NISTP521) {
|
||
|
return NISTP521;
|
||
|
}
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
return SSH_ERROR;
|
||
|
#else
|
||
|
return NULL;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
-/** @internal
|
||
|
- * @brief Starts ecdh-sha2-nistp256 key exchange
|
||
|
- */
|
||
|
-int ssh_client_ecdh_init(ssh_session session){
|
||
|
- int rc;
|
||
|
- ssh_string client_pubkey;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+/* @internal
|
||
|
+ * @brief Generate ECDH key pair for ecdh key exchange and store it in the
|
||
|
+ * session->next_crypto structure
|
||
|
*/
|
||
|
-#if 1
|
||
|
- EC_KEY *key;
|
||
|
- const EC_GROUP *group;
|
||
|
- const EC_POINT *pubkey;
|
||
|
- int curve;
|
||
|
- int len;
|
||
|
- bignum_CTX ctx = BN_CTX_new();
|
||
|
- if (ctx == NULL) {
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
+static ssh_string ssh_ecdh_generate(ssh_session session)
|
||
|
+{
|
||
|
+ ssh_string pubkey_string = NULL;
|
||
|
+ const EC_GROUP *group = NULL;
|
||
|
+ const EC_POINT *point = NULL;
|
||
|
+ int rc;
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ EC_KEY *key = NULL;
|
||
|
+ int curve;
|
||
|
#else
|
||
|
- const char *curve = NULL;
|
||
|
- EVP_PKEY *key = NULL;
|
||
|
- OSSL_PARAM *out_params = NULL;
|
||
|
- const OSSL_PARAM *pubkey_param = NULL;
|
||
|
- const uint8_t *pubkey = NULL;
|
||
|
- size_t pubkey_len;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-
|
||
|
- rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT);
|
||
|
- if (rc < 0) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- BN_CTX_free(ctx);
|
||
|
+ const char *curve = NULL;
|
||
|
+ EVP_PKEY *key = NULL;
|
||
|
+ OSSL_PARAM *out_params = NULL;
|
||
|
+ const OSSL_PARAM *pubkey_param = NULL;
|
||
|
+ const void *pubkey = NULL;
|
||
|
+ size_t pubkey_len;
|
||
|
+ int nid;
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
|
||
|
- curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- if (curve == SSH_ERROR) {
|
||
|
- BN_CTX_free(ctx);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
+ curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ if (curve == SSH_ERROR) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Failed to get curve name");
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
|
||
|
- key = EC_KEY_new_by_curve_name(curve);
|
||
|
+ key = EC_KEY_new_by_curve_name(curve);
|
||
|
#else
|
||
|
- if (curve == NULL) {
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-
|
||
|
- key = EVP_EC_gen(curve);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+ if (curve == NULL) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Failed to get curve name");
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
|
||
|
- if (key == NULL) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- BN_CTX_free(ctx);
|
||
|
+ key = EVP_EC_gen(curve);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- group = EC_KEY_get0_group(key);
|
||
|
-
|
||
|
- EC_KEY_generate_key(key);
|
||
|
+ if (key == NULL) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Failed to generate key");
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
|
||
|
- pubkey=EC_KEY_get0_public_key(key);
|
||
|
- len = EC_POINT_point2oct(group,pubkey,POINT_CONVERSION_UNCOMPRESSED,
|
||
|
- NULL,0,ctx);
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ group = EC_KEY_get0_group(key);
|
||
|
|
||
|
- client_pubkey = ssh_string_new(len);
|
||
|
- if (client_pubkey == NULL) {
|
||
|
- BN_CTX_free(ctx);
|
||
|
- EC_KEY_free(key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
+ EC_KEY_generate_key(key);
|
||
|
|
||
|
- EC_POINT_point2oct(group,pubkey,POINT_CONVERSION_UNCOMPRESSED,
|
||
|
- ssh_string_data(client_pubkey),len,ctx);
|
||
|
- BN_CTX_free(ctx);
|
||
|
+ point = EC_KEY_get0_public_key(key);
|
||
|
#else
|
||
|
- rc = EVP_PKEY_todata(key, EVP_PKEY_PUBLIC_KEY, &out_params);
|
||
|
- if (rc != 1) {
|
||
|
- EVP_PKEY_free(key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
+ rc = EVP_PKEY_todata(key, EVP_PKEY_PUBLIC_KEY, &out_params);
|
||
|
+ if (rc != 1) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Failed to export public key");
|
||
|
+ EVP_PKEY_free(key);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
|
||
|
- pubkey_param = OSSL_PARAM_locate_const(out_params, OSSL_PKEY_PARAM_PUB_KEY);
|
||
|
- if (pubkey_param == NULL) {
|
||
|
- EVP_PKEY_free(key);
|
||
|
- OSSL_PARAM_free(out_params);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
+ pubkey_param = OSSL_PARAM_locate_const(out_params, OSSL_PKEY_PARAM_PUB_KEY);
|
||
|
+ if (pubkey_param == NULL) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Failed to find public key");
|
||
|
+ EVP_PKEY_free(key);
|
||
|
+ OSSL_PARAM_free(out_params);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
|
||
|
- rc = OSSL_PARAM_get_octet_string_ptr(pubkey_param,
|
||
|
- (const void**)&pubkey,
|
||
|
- &pubkey_len);
|
||
|
- if (rc != 1) {
|
||
|
- OSSL_PARAM_free(out_params);
|
||
|
- EVP_PKEY_free(key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
+ rc = OSSL_PARAM_get_octet_string_ptr(pubkey_param,
|
||
|
+ (const void**)&pubkey,
|
||
|
+ &pubkey_len);
|
||
|
+ OSSL_PARAM_free(out_params);
|
||
|
+ if (rc != 1) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Failed to read public key");
|
||
|
+ EVP_PKEY_free(key);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
|
||
|
- client_pubkey = ssh_string_new(pubkey_len);
|
||
|
- if (client_pubkey == NULL) {
|
||
|
- OSSL_PARAM_free(out_params);
|
||
|
- EVP_PKEY_free(key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
+ /* Convert the data to low-level representation */
|
||
|
+ nid = pki_key_ecgroup_name_to_nid(curve);
|
||
|
+ group = EC_GROUP_new_by_curve_name_ex(NULL, NULL, nid);
|
||
|
+ point = EC_POINT_new(group);
|
||
|
+ rc = EC_POINT_oct2point(group, (EC_POINT *)point, pubkey, pubkey_len, NULL);
|
||
|
+ if (group == NULL || point == NULL || rc != 1) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Failed to export public key");
|
||
|
+ EVP_PKEY_free(key);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
|
||
|
- memcpy(ssh_string_data(client_pubkey), pubkey, pubkey_len);
|
||
|
- OSSL_PARAM_free(out_params);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-
|
||
|
- rc = ssh_buffer_add_ssh_string(session->out_buffer,client_pubkey);
|
||
|
- if (rc < 0) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- EC_KEY_free(key);
|
||
|
+ pubkey_string = pki_key_make_ecpoint_string(group, point);
|
||
|
+ if (pubkey_string == NULL) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Failed to convert public key");
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ EC_KEY_free(key);
|
||
|
#else
|
||
|
- EVP_PKEY_free(key);
|
||
|
+ EVP_PKEY_free(key);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
- SSH_STRING_FREE(client_pubkey);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+ session->next_crypto->ecdh_privkey = key;
|
||
|
+ return pubkey_string;
|
||
|
+}
|
||
|
|
||
|
- session->next_crypto->ecdh_privkey = key;
|
||
|
- session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
||
|
+/** @internal
|
||
|
+ * @brief Starts ecdh-sha2-nistp256 key exchange
|
||
|
+ */
|
||
|
+int ssh_client_ecdh_init(ssh_session session)
|
||
|
+{
|
||
|
+ ssh_string client_pubkey = NULL;
|
||
|
+ int rc;
|
||
|
|
||
|
- /* register the packet callbacks */
|
||
|
- ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks);
|
||
|
- session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||
|
+ rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT);
|
||
|
+ if (rc < 0) {
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
|
||
|
- rc = ssh_packet_send(session);
|
||
|
+ client_pubkey = ssh_ecdh_generate(session);
|
||
|
+ if (client_pubkey == NULL) {
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
|
||
|
- return rc;
|
||
|
+ rc = ssh_buffer_add_ssh_string(session->out_buffer, client_pubkey);
|
||
|
+ if (rc < 0) {
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
||
|
+
|
||
|
+ /* register the packet callbacks */
|
||
|
+ ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks);
|
||
|
+ session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||
|
+
|
||
|
+ rc = ssh_packet_send(session);
|
||
|
+
|
||
|
+ return rc;
|
||
|
}
|
||
|
|
||
|
-int ecdh_build_k(ssh_session session) {
|
||
|
+int ecdh_build_k(ssh_session session)
|
||
|
+{
|
||
|
struct ssh_crypto_struct *next_crypto = session->next_crypto;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
- #if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
const EC_GROUP *group = EC_KEY_get0_group(next_crypto->ecdh_privkey);
|
||
|
- EC_POINT *pubkey;
|
||
|
- void *buffer;
|
||
|
+ EC_POINT *pubkey = NULL;
|
||
|
+ void *buffer = NULL;
|
||
|
int rc;
|
||
|
int len = (EC_GROUP_get_degree(group) + 7) / 8;
|
||
|
bignum_CTX ctx = bignum_ctx_new();
|
||
|
@@ -292,11 +257,13 @@ int ecdh_build_k(ssh_session session) {
|
||
|
bignum_bin2bn(buffer, len, &next_crypto->shared_secret);
|
||
|
free(buffer);
|
||
|
#else
|
||
|
+ const char *curve = NULL;
|
||
|
EVP_PKEY *pubkey = NULL;
|
||
|
void *secret = NULL;
|
||
|
size_t secret_len;
|
||
|
int rc;
|
||
|
- OSSL_PARAM params[2];
|
||
|
+ OSSL_PARAM params[3];
|
||
|
+ ssh_string peer_pubkey = NULL;
|
||
|
EVP_PKEY_CTX *dh_ctx = EVP_PKEY_CTX_new_from_pkey(NULL,
|
||
|
next_crypto->ecdh_privkey,
|
||
|
NULL);
|
||
|
@@ -324,15 +291,18 @@ int ecdh_build_k(ssh_session session) {
|
||
|
}
|
||
|
|
||
|
if (session->server) {
|
||
|
- params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
|
||
|
- ssh_string_data(next_crypto->ecdh_client_pubkey),
|
||
|
- ssh_string_len(next_crypto->ecdh_client_pubkey));
|
||
|
+ peer_pubkey = next_crypto->ecdh_client_pubkey;
|
||
|
} else {
|
||
|
- params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
|
||
|
- ssh_string_data(next_crypto->ecdh_server_pubkey),
|
||
|
- ssh_string_len(next_crypto->ecdh_server_pubkey));
|
||
|
+ peer_pubkey = next_crypto->ecdh_server_pubkey;
|
||
|
}
|
||
|
- params[1] = OSSL_PARAM_construct_end();
|
||
|
+ params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
|
||
|
+ ssh_string_data(peer_pubkey),
|
||
|
+ ssh_string_len(peer_pubkey));
|
||
|
+ curve = ecdh_kex_type_to_curve(next_crypto->kex_type);
|
||
|
+ params[1] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
|
||
|
+ (char *)curve,
|
||
|
+ strlen(curve));
|
||
|
+ params[2] = OSSL_PARAM_construct_end();
|
||
|
|
||
|
rc = EVP_PKEY_fromdata(pubkey_ctx, &pubkey, EVP_PKEY_PUBLIC_KEY, params);
|
||
|
if (rc != 1) {
|
||
|
@@ -374,11 +344,7 @@ int ecdh_build_k(ssh_session session) {
|
||
|
free(secret);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
if (next_crypto->shared_secret == NULL) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
EC_KEY_free(next_crypto->ecdh_privkey);
|
||
|
#else
|
||
|
EVP_PKEY_free(next_crypto->ecdh_privkey);
|
||
|
@@ -386,11 +352,7 @@ int ecdh_build_k(ssh_session session) {
|
||
|
next_crypto->ecdh_privkey = NULL;
|
||
|
return -1;
|
||
|
}
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
EC_KEY_free(next_crypto->ecdh_privkey);
|
||
|
#else
|
||
|
EVP_PKEY_free(next_crypto->ecdh_privkey);
|
||
|
@@ -413,29 +375,11 @@ int ecdh_build_k(ssh_session session) {
|
||
|
/** @brief Handle a SSH_MSG_KEXDH_INIT packet (server) and send a
|
||
|
* SSH_MSG_KEXDH_REPLY
|
||
|
*/
|
||
|
-SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||
|
+SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init)
|
||
|
+{
|
||
|
/* ECDH keys */
|
||
|
- ssh_string q_c_string;
|
||
|
- ssh_string q_s_string;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- EC_KEY *ecdh_key;
|
||
|
- const EC_GROUP *group;
|
||
|
- const EC_POINT *ecdh_pubkey;
|
||
|
- bignum_CTX ctx;
|
||
|
- int curve;
|
||
|
- int len;
|
||
|
-#else
|
||
|
- EVP_PKEY *ecdh_key = NULL;
|
||
|
- const void *pubkey_ptr = NULL;
|
||
|
- size_t len;
|
||
|
- OSSL_PARAM *params = NULL;
|
||
|
- const OSSL_PARAM *pubkey = NULL;
|
||
|
- const char *curve = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+ ssh_string q_c_string = NULL;
|
||
|
+ ssh_string q_s_string = NULL;
|
||
|
/* SSH host keys (rsa,dsa,ecdsa) */
|
||
|
ssh_key privkey;
|
||
|
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||
|
@@ -445,125 +389,22 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||
|
(void)type;
|
||
|
(void)user;
|
||
|
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "Processing SSH_MSG_KEXDH_INIT");
|
||
|
+
|
||
|
ssh_packet_remove_callbacks(session, &ssh_ecdh_server_callbacks);
|
||
|
/* Extract the client pubkey from the init packet */
|
||
|
q_c_string = ssh_buffer_get_ssh_string(packet);
|
||
|
if (q_c_string == NULL) {
|
||
|
- ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
|
||
|
+ ssh_set_error(session, SSH_FATAL, "No Q_C ECC point in packet");
|
||
|
goto error;
|
||
|
}
|
||
|
session->next_crypto->ecdh_client_pubkey = q_c_string;
|
||
|
|
||
|
- curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- if (curve == SSH_ERROR) {
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-#else
|
||
|
- if (curve == NULL) {
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- ecdh_key = EC_KEY_new_by_curve_name(curve);
|
||
|
-#else
|
||
|
- ecdh_key = EVP_EC_gen(curve);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
- if (ecdh_key == NULL) {
|
||
|
- ssh_set_error_oom(session);
|
||
|
- goto error;
|
||
|
- }
|
||
|
-
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- /* Build server's keypair */
|
||
|
- ctx = BN_CTX_new();
|
||
|
- if (ctx == NULL) {
|
||
|
- EC_KEY_free(ecdh_key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-
|
||
|
- group = EC_KEY_get0_group(ecdh_key);
|
||
|
- EC_KEY_generate_key(ecdh_key);
|
||
|
-
|
||
|
- ecdh_pubkey = EC_KEY_get0_public_key(ecdh_key);
|
||
|
- len = EC_POINT_point2oct(group,
|
||
|
- ecdh_pubkey,
|
||
|
- POINT_CONVERSION_UNCOMPRESSED,
|
||
|
- NULL,
|
||
|
- 0,
|
||
|
- ctx);
|
||
|
-#else
|
||
|
- rc = EVP_PKEY_todata(ecdh_key, EVP_PKEY_PUBLIC_KEY, ¶ms);
|
||
|
- if (rc != 1) {
|
||
|
- EVP_PKEY_free(ecdh_key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-
|
||
|
- pubkey = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||
|
- if (pubkey == NULL) {
|
||
|
- OSSL_PARAM_free(params);
|
||
|
- EVP_PKEY_free(ecdh_key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-
|
||
|
- rc = OSSL_PARAM_get_octet_string_ptr(pubkey, &pubkey_ptr, &len);
|
||
|
- if (rc != 1) {
|
||
|
- OSSL_PARAM_free(params);
|
||
|
- EVP_PKEY_free(ecdh_key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
- q_s_string = ssh_string_new(len);
|
||
|
+ q_s_string = ssh_ecdh_generate(session);
|
||
|
if (q_s_string == NULL) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- EC_KEY_free(ecdh_key);
|
||
|
- BN_CTX_free(ctx);
|
||
|
-#else
|
||
|
- EVP_PKEY_free(ecdh_key);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- EC_POINT_point2oct(group,
|
||
|
- ecdh_pubkey,
|
||
|
- POINT_CONVERSION_UNCOMPRESSED,
|
||
|
- ssh_string_data(q_s_string),
|
||
|
- len,
|
||
|
- ctx);
|
||
|
- BN_CTX_free(ctx);
|
||
|
-#else
|
||
|
- if (memcpy(ssh_string_data(q_s_string), pubkey_ptr, len)) {
|
||
|
- OSSL_PARAM_free(params);
|
||
|
- EVP_PKEY_free(ecdh_key);
|
||
|
- return SSH_ERROR;
|
||
|
- }
|
||
|
-
|
||
|
- OSSL_PARAM_free(params);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-
|
||
|
- session->next_crypto->ecdh_privkey = ecdh_key;
|
||
|
session->next_crypto->ecdh_server_pubkey = q_s_string;
|
||
|
|
||
|
/* build k and session_id */
|
||
|
diff --git a/src/legacy.c b/src/legacy.c
|
||
|
index 7b165dbe..4c2c0052 100644
|
||
|
--- a/src/legacy.c
|
||
|
+++ b/src/legacy.c
|
||
|
@@ -83,20 +83,20 @@ int ssh_userauth_pubkey(ssh_session session,
|
||
|
key->type = privatekey->type;
|
||
|
key->type_c = ssh_key_type_to_char(key->type);
|
||
|
key->flags = SSH_KEY_FLAG_PRIVATE|SSH_KEY_FLAG_PUBLIC;
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
key->dsa = privatekey->dsa_priv;
|
||
|
key->rsa = privatekey->rsa_priv;
|
||
|
#else
|
||
|
key->key = privatekey->key_priv;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
rc = ssh_userauth_publickey(session, username, key);
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
key->dsa = NULL;
|
||
|
key->rsa = NULL;
|
||
|
#else
|
||
|
key->key = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
ssh_key_free(key);
|
||
|
|
||
|
return rc;
|
||
|
@@ -362,22 +362,14 @@ void publickey_free(ssh_public_key key) {
|
||
|
#ifdef HAVE_LIBGCRYPT
|
||
|
gcry_sexp_release(key->dsa_pub);
|
||
|
#elif defined HAVE_LIBCRYPTO
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- DSA_free(key->dsa_pub);
|
||
|
-#else
|
||
|
EVP_PKEY_free(key->key_pub);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
#endif /* HAVE_LIBGCRYPT */
|
||
|
break;
|
||
|
case SSH_KEYTYPE_RSA:
|
||
|
#ifdef HAVE_LIBGCRYPT
|
||
|
gcry_sexp_release(key->rsa_pub);
|
||
|
#elif defined HAVE_LIBCRYPTO
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- RSA_free(key->rsa_pub);
|
||
|
-#else
|
||
|
EVP_PKEY_free(key->key_pub);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
#elif defined HAVE_LIBMBEDCRYPTO
|
||
|
mbedtls_pk_free(key->rsa_pub);
|
||
|
SAFE_FREE(key->rsa_pub);
|
||
|
@@ -403,20 +395,20 @@ ssh_public_key publickey_from_privatekey(ssh_private_key prv) {
|
||
|
privkey->type = prv->type;
|
||
|
privkey->type_c = ssh_key_type_to_char(privkey->type);
|
||
|
privkey->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
privkey->dsa = prv->dsa_priv;
|
||
|
privkey->rsa = prv->rsa_priv;
|
||
|
#else
|
||
|
privkey->key = prv->key_priv;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
privkey->dsa = NULL;
|
||
|
privkey->rsa = NULL;
|
||
|
#else
|
||
|
privkey->key = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
ssh_key_free(privkey);
|
||
|
if (rc < 0) {
|
||
|
return NULL;
|
||
|
@@ -462,7 +454,7 @@ ssh_private_key privatekey_from_file(ssh_session session,
|
||
|
}
|
||
|
|
||
|
privkey->type = key->type;
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
privkey->dsa_priv = key->dsa;
|
||
|
privkey->rsa_priv = key->rsa;
|
||
|
|
||
|
@@ -472,7 +464,7 @@ ssh_private_key privatekey_from_file(ssh_session session,
|
||
|
privkey->key_priv = key->key;
|
||
|
|
||
|
key->key = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
ssh_key_free(key);
|
||
|
|
||
|
@@ -494,12 +486,7 @@ void privatekey_free(ssh_private_key prv) {
|
||
|
gcry_sexp_release(prv->dsa_priv);
|
||
|
gcry_sexp_release(prv->rsa_priv);
|
||
|
#elif defined HAVE_LIBCRYPTO
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- DSA_free(prv->dsa_priv);
|
||
|
- RSA_free(prv->rsa_priv);
|
||
|
-#else
|
||
|
EVP_PKEY_free(prv->key_priv);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
#elif defined HAVE_LIBMBEDCRYPTO
|
||
|
mbedtls_pk_free(prv->rsa_priv);
|
||
|
SAFE_FREE(prv->rsa_priv);
|
||
|
@@ -564,7 +551,7 @@ ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) {
|
||
|
pubkey->type = key->type;
|
||
|
pubkey->type_c = key->type_c;
|
||
|
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
pubkey->dsa_pub = key->dsa;
|
||
|
key->dsa = NULL;
|
||
|
pubkey->rsa_pub = key->rsa;
|
||
|
@@ -572,7 +559,7 @@ ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) {
|
||
|
#else
|
||
|
pubkey->key_pub = key->key;
|
||
|
key->key = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
ssh_key_free(key);
|
||
|
|
||
|
@@ -596,24 +583,24 @@ ssh_string publickey_to_string(ssh_public_key pubkey) {
|
||
|
key->type = pubkey->type;
|
||
|
key->type_c = pubkey->type_c;
|
||
|
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
key->dsa = pubkey->dsa_pub;
|
||
|
key->rsa = pubkey->rsa_pub;
|
||
|
#else
|
||
|
key->key = pubkey->key_pub;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
rc = ssh_pki_export_pubkey_blob(key, &key_blob);
|
||
|
if (rc < 0) {
|
||
|
key_blob = NULL;
|
||
|
}
|
||
|
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
key->dsa = NULL;
|
||
|
key->rsa = NULL;
|
||
|
#else
|
||
|
key->key = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
ssh_key_free(key);
|
||
|
|
||
|
return key_blob;
|
||
|
diff --git a/src/libcrypto-compat.c b/src/libcrypto-compat.c
|
||
|
deleted file mode 100644
|
||
|
index 33b8dffd..00000000
|
||
|
--- a/src/libcrypto-compat.c
|
||
|
+++ /dev/null
|
||
|
@@ -1,305 +0,0 @@
|
||
|
-/*
|
||
|
- * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||
|
- *
|
||
|
- * Licensed under the OpenSSL license (the "License"). You may not use
|
||
|
- * this file except in compliance with the License. You can obtain a copy
|
||
|
- * in the file LICENSE in the source distribution or at
|
||
|
- * https://www.openssl.org/source/license.html
|
||
|
- */
|
||
|
-
|
||
|
-#include "config.h"
|
||
|
-
|
||
|
-#include <string.h>
|
||
|
-#include "libcrypto-compat.h"
|
||
|
-
|
||
|
-int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
|
||
|
-{
|
||
|
- /* If the fields n and e in r are NULL, the corresponding input
|
||
|
- * parameters MUST be non-NULL for n and e. d may be
|
||
|
- * left NULL (in case only the public key is used).
|
||
|
- */
|
||
|
- if ((r->n == NULL && n == NULL)
|
||
|
- || (r->e == NULL && e == NULL))
|
||
|
- return 0;
|
||
|
-
|
||
|
- if (n != NULL) {
|
||
|
- BN_free(r->n);
|
||
|
- r->n = n;
|
||
|
- }
|
||
|
- if (e != NULL) {
|
||
|
- BN_free(r->e);
|
||
|
- r->e = e;
|
||
|
- }
|
||
|
- if (d != NULL) {
|
||
|
- BN_free(r->d);
|
||
|
- r->d = d;
|
||
|
- }
|
||
|
-
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
|
||
|
-{
|
||
|
- /* If the fields p and q in r are NULL, the corresponding input
|
||
|
- * parameters MUST be non-NULL.
|
||
|
- */
|
||
|
- if ((r->p == NULL && p == NULL)
|
||
|
- || (r->q == NULL && q == NULL))
|
||
|
- return 0;
|
||
|
-
|
||
|
- if (p != NULL) {
|
||
|
- BN_free(r->p);
|
||
|
- r->p = p;
|
||
|
- }
|
||
|
- if (q != NULL) {
|
||
|
- BN_free(r->q);
|
||
|
- r->q = q;
|
||
|
- }
|
||
|
-
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
|
||
|
-{
|
||
|
- /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
|
||
|
- * parameters MUST be non-NULL.
|
||
|
- */
|
||
|
- if ((r->dmp1 == NULL && dmp1 == NULL)
|
||
|
- || (r->dmq1 == NULL && dmq1 == NULL)
|
||
|
- || (r->iqmp == NULL && iqmp == NULL))
|
||
|
- return 0;
|
||
|
-
|
||
|
- if (dmp1 != NULL) {
|
||
|
- BN_free(r->dmp1);
|
||
|
- r->dmp1 = dmp1;
|
||
|
- }
|
||
|
- if (dmq1 != NULL) {
|
||
|
- BN_free(r->dmq1);
|
||
|
- r->dmq1 = dmq1;
|
||
|
- }
|
||
|
- if (iqmp != NULL) {
|
||
|
- BN_free(r->iqmp);
|
||
|
- r->iqmp = iqmp;
|
||
|
- }
|
||
|
-
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-void RSA_get0_key(const RSA *r,
|
||
|
- const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
|
||
|
-{
|
||
|
- if (n != NULL)
|
||
|
- *n = r->n;
|
||
|
- if (e != NULL)
|
||
|
- *e = r->e;
|
||
|
- if (d != NULL)
|
||
|
- *d = r->d;
|
||
|
-}
|
||
|
-
|
||
|
-void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
|
||
|
-{
|
||
|
- if (p != NULL)
|
||
|
- *p = r->p;
|
||
|
- if (q != NULL)
|
||
|
- *q = r->q;
|
||
|
-}
|
||
|
-
|
||
|
-void RSA_get0_crt_params(const RSA *r,
|
||
|
- const BIGNUM **dmp1, const BIGNUM **dmq1,
|
||
|
- const BIGNUM **iqmp)
|
||
|
-{
|
||
|
- if (dmp1 != NULL)
|
||
|
- *dmp1 = r->dmp1;
|
||
|
- if (dmq1 != NULL)
|
||
|
- *dmq1 = r->dmq1;
|
||
|
- if (iqmp != NULL)
|
||
|
- *iqmp = r->iqmp;
|
||
|
-}
|
||
|
-
|
||
|
-void DSA_get0_pqg(const DSA *d,
|
||
|
- const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
|
||
|
-{
|
||
|
- if (p != NULL)
|
||
|
- *p = d->p;
|
||
|
- if (q != NULL)
|
||
|
- *q = d->q;
|
||
|
- if (g != NULL)
|
||
|
- *g = d->g;
|
||
|
-}
|
||
|
-
|
||
|
-int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||
|
-{
|
||
|
- /* If the fields p, q and g in d are NULL, the corresponding input
|
||
|
- * parameters MUST be non-NULL.
|
||
|
- */
|
||
|
- if ((d->p == NULL && p == NULL)
|
||
|
- || (d->q == NULL && q == NULL)
|
||
|
- || (d->g == NULL && g == NULL))
|
||
|
- return 0;
|
||
|
-
|
||
|
- if (p != NULL) {
|
||
|
- BN_free(d->p);
|
||
|
- d->p = p;
|
||
|
- }
|
||
|
- if (q != NULL) {
|
||
|
- BN_free(d->q);
|
||
|
- d->q = q;
|
||
|
- }
|
||
|
- if (g != NULL) {
|
||
|
- BN_free(d->g);
|
||
|
- d->g = g;
|
||
|
- }
|
||
|
-
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-void DSA_get0_key(const DSA *d,
|
||
|
- const BIGNUM **pub_key, const BIGNUM **priv_key)
|
||
|
-{
|
||
|
- if (pub_key != NULL)
|
||
|
- *pub_key = d->pub_key;
|
||
|
- if (priv_key != NULL)
|
||
|
- *priv_key = d->priv_key;
|
||
|
-}
|
||
|
-
|
||
|
-int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
|
||
|
-{
|
||
|
- /* If the field pub_key in d is NULL, the corresponding input
|
||
|
- * parameters MUST be non-NULL. The priv_key field may
|
||
|
- * be left NULL.
|
||
|
- */
|
||
|
- if (d->pub_key == NULL && pub_key == NULL)
|
||
|
- return 0;
|
||
|
-
|
||
|
- if (pub_key != NULL) {
|
||
|
- BN_free(d->pub_key);
|
||
|
- d->pub_key = pub_key;
|
||
|
- }
|
||
|
- if (priv_key != NULL) {
|
||
|
- BN_free(d->priv_key);
|
||
|
- d->priv_key = priv_key;
|
||
|
- }
|
||
|
-
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
||
|
-{
|
||
|
- if (pr != NULL)
|
||
|
- *pr = sig->r;
|
||
|
- if (ps != NULL)
|
||
|
- *ps = sig->s;
|
||
|
-}
|
||
|
-
|
||
|
-int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
|
||
|
-{
|
||
|
- if (r == NULL || s == NULL)
|
||
|
- return 0;
|
||
|
- BN_clear_free(sig->r);
|
||
|
- BN_clear_free(sig->s);
|
||
|
- sig->r = r;
|
||
|
- sig->s = s;
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
||
|
-{
|
||
|
- if (pr != NULL)
|
||
|
- *pr = sig->r;
|
||
|
- if (ps != NULL)
|
||
|
- *ps = sig->s;
|
||
|
-}
|
||
|
-
|
||
|
-int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
|
||
|
-{
|
||
|
- if (r == NULL || s == NULL)
|
||
|
- return 0;
|
||
|
- BN_clear_free(sig->r);
|
||
|
- BN_clear_free(sig->s);
|
||
|
- sig->r = r;
|
||
|
- sig->s = s;
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-EVP_MD_CTX *EVP_MD_CTX_new(void)
|
||
|
-{
|
||
|
- EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX));
|
||
|
- if (ctx != NULL) {
|
||
|
- EVP_MD_CTX_init(ctx);
|
||
|
- }
|
||
|
- return ctx;
|
||
|
-}
|
||
|
-
|
||
|
-void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
||
|
-{
|
||
|
- EVP_MD_CTX_cleanup(ctx);
|
||
|
- OPENSSL_free(ctx);
|
||
|
-}
|
||
|
-
|
||
|
-void DH_get0_pqg(const DH *dh,
|
||
|
- const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
|
||
|
-{
|
||
|
- if (p) {
|
||
|
- *p = dh->p;
|
||
|
- }
|
||
|
- if (q) {
|
||
|
- *q = NULL;
|
||
|
- }
|
||
|
- if (g) {
|
||
|
- *g = dh->g;
|
||
|
- }
|
||
|
-}
|
||
|
-
|
||
|
-int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||
|
-{
|
||
|
- if (p) {
|
||
|
- if (dh->p) {
|
||
|
- BN_free(dh->p);
|
||
|
- }
|
||
|
- dh->p = p;
|
||
|
- }
|
||
|
- if (g) {
|
||
|
- if (dh->g) {
|
||
|
- BN_free(dh->g);
|
||
|
- }
|
||
|
- dh->g = g;
|
||
|
- }
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-void DH_get0_key(const DH *dh,
|
||
|
- const BIGNUM **pub_key, const BIGNUM **priv_key)
|
||
|
-{
|
||
|
- if (pub_key) {
|
||
|
- *pub_key = dh->pub_key;
|
||
|
- }
|
||
|
- if (priv_key) {
|
||
|
- *priv_key = dh->priv_key;
|
||
|
- }
|
||
|
-}
|
||
|
-
|
||
|
-int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
||
|
-{
|
||
|
- if (pub_key) {
|
||
|
- if (dh->pub_key) {
|
||
|
- BN_free(dh->pub_key);
|
||
|
- }
|
||
|
- dh->pub_key = pub_key;
|
||
|
- }
|
||
|
- if (priv_key) {
|
||
|
- if (dh->priv_key) {
|
||
|
- BN_free(dh->priv_key);
|
||
|
- }
|
||
|
- dh->priv_key = priv_key;
|
||
|
- }
|
||
|
- return 1;
|
||
|
-}
|
||
|
-
|
||
|
-const char *OpenSSL_version(int type)
|
||
|
-{
|
||
|
- return SSLeay_version(type);
|
||
|
-}
|
||
|
-unsigned long OpenSSL_version_num(void)
|
||
|
-{
|
||
|
- return SSLeay();
|
||
|
-}
|
||
|
diff --git a/src/libcrypto-compat.h b/src/libcrypto-compat.h
|
||
|
index 48e30bd1..0f2dc184 100644
|
||
|
--- a/src/libcrypto-compat.h
|
||
|
+++ b/src/libcrypto-compat.h
|
||
|
@@ -7,47 +7,8 @@
|
||
|
#define NISTP384 "P-384"
|
||
|
#define NISTP521 "P-521"
|
||
|
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||
|
-
|
||
|
-#include <openssl/rsa.h>
|
||
|
-#include <openssl/dsa.h>
|
||
|
-#include <openssl/ecdsa.h>
|
||
|
-#include <openssl/dh.h>
|
||
|
-#include <openssl/evp.h>
|
||
|
-#include <openssl/hmac.h>
|
||
|
-#include <openssl/bn.h>
|
||
|
-
|
||
|
-int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
|
||
|
-int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
|
||
|
-int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp);
|
||
|
-void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d);
|
||
|
-void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
|
||
|
-void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp);
|
||
|
-
|
||
|
-void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
|
||
|
-int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
|
||
|
-void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key);
|
||
|
-int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
|
||
|
-
|
||
|
-void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
|
||
|
-int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
|
||
|
-
|
||
|
-void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
|
||
|
-int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
|
||
|
-
|
||
|
-EVP_MD_CTX *EVP_MD_CTX_new(void);
|
||
|
-void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
|
||
|
-
|
||
|
-void DH_get0_pqg(const DH *dh,
|
||
|
- const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
|
||
|
-int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
|
||
|
-void DH_get0_key(const DH *dh,
|
||
|
- const BIGNUM **pub_key, const BIGNUM **priv_key);
|
||
|
-int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
|
||
|
-
|
||
|
-const char *OpenSSL_version(int type);
|
||
|
-unsigned long OpenSSL_version_num(void);
|
||
|
-
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#define EVP_PKEY_eq EVP_PKEY_cmp
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
#endif /* LIBCRYPTO_COMPAT_H */
|
||
|
diff --git a/src/libcrypto.c b/src/libcrypto.c
|
||
|
index 4f945d90..7b9ffc00 100644
|
||
|
--- a/src/libcrypto.c
|
||
|
+++ b/src/libcrypto.c
|
||
|
@@ -85,7 +85,6 @@
|
||
|
|
||
|
static int libcrypto_initialized = 0;
|
||
|
|
||
|
-static ENGINE *engine = NULL;
|
||
|
|
||
|
void ssh_reseed(void){
|
||
|
#ifndef _WIN32
|
||
|
@@ -95,6 +94,9 @@ void ssh_reseed(void){
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
+#ifndef WITH_PKCS11_PROVIDER
|
||
|
+static ENGINE *engine = NULL;
|
||
|
+
|
||
|
ENGINE *pki_get_engine(void)
|
||
|
{
|
||
|
int ok;
|
||
|
@@ -124,6 +126,7 @@ ENGINE *pki_get_engine(void)
|
||
|
}
|
||
|
return engine;
|
||
|
}
|
||
|
+#endif /* WITH_PKCS11_PROVIDER */
|
||
|
|
||
|
#ifdef HAVE_OPENSSL_EVP_KDF_CTX
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
@@ -1460,57 +1463,59 @@ int evp_build_pkey(const char* name, OSSL_PARAM_BLD *param_bld,
|
||
|
*
|
||
|
* @return 0 on success, -1 on error
|
||
|
*/
|
||
|
-static int evp_dup_pkey(const char* name, const ssh_key key, int demote,
|
||
|
- ssh_key new_key)
|
||
|
+static int
|
||
|
+evp_dup_pkey(const char *name, const ssh_key key, int demote, ssh_key new_key)
|
||
|
{
|
||
|
int rc;
|
||
|
- EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
|
||
|
+ EVP_PKEY_CTX *ctx = NULL;
|
||
|
OSSL_PARAM *params = NULL;
|
||
|
|
||
|
- if (ctx == NULL) {
|
||
|
- return -1;
|
||
|
- }
|
||
|
-
|
||
|
- if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) {
|
||
|
- rc = EVP_PKEY_todata(key->key, EVP_PKEY_KEYPAIR, ¶ms);
|
||
|
+ /* The simple case -- just reference the existing key */
|
||
|
+ if (!demote || (key->flags & SSH_KEY_FLAG_PRIVATE) == 0) {
|
||
|
+ rc = EVP_PKEY_up_ref(key->key);
|
||
|
if (rc != 1) {
|
||
|
- EVP_PKEY_CTX_free(ctx);
|
||
|
return -1;
|
||
|
}
|
||
|
+ new_key->key = key->key;
|
||
|
+ return SSH_OK;
|
||
|
+ }
|
||
|
|
||
|
- rc = EVP_PKEY_fromdata_init(ctx);
|
||
|
- if (rc != 1) {
|
||
|
- EVP_PKEY_CTX_free(ctx);
|
||
|
- OSSL_PARAM_free(params);
|
||
|
- return -1;
|
||
|
- }
|
||
|
+ /* demote == 1 */
|
||
|
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
|
||
|
+ if (ctx == NULL) {
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
|
||
|
- rc = EVP_PKEY_fromdata(ctx, &(new_key->key), EVP_PKEY_KEYPAIR, params);
|
||
|
- if (rc != 1) {
|
||
|
- EVP_PKEY_CTX_free(ctx);
|
||
|
- OSSL_PARAM_free(params);
|
||
|
- return -1;
|
||
|
- }
|
||
|
- } else {
|
||
|
- rc = EVP_PKEY_todata(key->key, EVP_PKEY_PUBLIC_KEY, ¶ms);
|
||
|
- if (rc != 1) {
|
||
|
- EVP_PKEY_CTX_free(ctx);
|
||
|
- return -1;
|
||
|
- }
|
||
|
+ rc = EVP_PKEY_todata(key->key, EVP_PKEY_PUBLIC_KEY, ¶ms);
|
||
|
+ if (rc != 1) {
|
||
|
+ EVP_PKEY_CTX_free(ctx);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
|
||
|
- rc = EVP_PKEY_fromdata_init(ctx);
|
||
|
- if (rc != 1) {
|
||
|
+ if (strcmp(name, "EC") == 0) {
|
||
|
+ OSSL_PARAM *locate_param = NULL;
|
||
|
+ /* For ECC keys provided by engine or provider, we need to have the
|
||
|
+ * explicit public part available, otherwise the key will not be
|
||
|
+ * usable */
|
||
|
+ locate_param = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||
|
+ if (locate_param == NULL) {
|
||
|
EVP_PKEY_CTX_free(ctx);
|
||
|
OSSL_PARAM_free(params);
|
||
|
return -1;
|
||
|
}
|
||
|
+ }
|
||
|
+ rc = EVP_PKEY_fromdata_init(ctx);
|
||
|
+ if (rc != 1) {
|
||
|
+ EVP_PKEY_CTX_free(ctx);
|
||
|
+ OSSL_PARAM_free(params);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
|
||
|
- rc = EVP_PKEY_fromdata(ctx, &(new_key->key), EVP_PKEY_PUBLIC_KEY, params);
|
||
|
- if (rc != 1) {
|
||
|
- EVP_PKEY_CTX_free(ctx);
|
||
|
- OSSL_PARAM_free(params);
|
||
|
- return -1;
|
||
|
- }
|
||
|
+ rc = EVP_PKEY_fromdata(ctx, &(new_key->key), EVP_PKEY_PUBLIC_KEY, params);
|
||
|
+ if (rc != 1) {
|
||
|
+ EVP_PKEY_CTX_free(ctx);
|
||
|
+ OSSL_PARAM_free(params);
|
||
|
+ return -1;
|
||
|
}
|
||
|
|
||
|
OSSL_PARAM_free(params);
|
||
|
@@ -1535,4 +1540,54 @@ int evp_dup_ecdsa_pkey(const ssh_key key, ssh_key new_key, int demote)
|
||
|
}
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
+ssh_string
|
||
|
+pki_key_make_ecpoint_string(const EC_GROUP *g, const EC_POINT *p)
|
||
|
+{
|
||
|
+ ssh_string s = NULL;
|
||
|
+ size_t len;
|
||
|
+
|
||
|
+ len = EC_POINT_point2oct(g,
|
||
|
+ p,
|
||
|
+ POINT_CONVERSION_UNCOMPRESSED,
|
||
|
+ NULL,
|
||
|
+ 0,
|
||
|
+ NULL);
|
||
|
+ if (len == 0) {
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ s = ssh_string_new(len);
|
||
|
+ if (s == NULL) {
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ len = EC_POINT_point2oct(g,
|
||
|
+ p,
|
||
|
+ POINT_CONVERSION_UNCOMPRESSED,
|
||
|
+ ssh_string_data(s),
|
||
|
+ ssh_string_len(s),
|
||
|
+ NULL);
|
||
|
+ if (len != ssh_string_len(s)) {
|
||
|
+ SSH_STRING_FREE(s);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ return s;
|
||
|
+}
|
||
|
+
|
||
|
+int pki_key_ecgroup_name_to_nid(const char *group)
|
||
|
+{
|
||
|
+ if (strcmp(group, NISTP256) == 0 ||
|
||
|
+ strcmp(group, "secp256r1") == 0 ||
|
||
|
+ strcmp(group, "prime256v1") == 0) {
|
||
|
+ return NID_X9_62_prime256v1;
|
||
|
+ } else if (strcmp(group, NISTP384) == 0 ||
|
||
|
+ strcmp(group, "secp384r1") == 0) {
|
||
|
+ return NID_secp384r1;
|
||
|
+ } else if (strcmp(group, NISTP521) == 0 ||
|
||
|
+ strcmp(group, "secp521r1") == 0) {
|
||
|
+ return NID_secp521r1;
|
||
|
+ }
|
||
|
+ return -1;
|
||
|
+}
|
||
|
#endif /* LIBCRYPTO */
|
||
|
diff --git a/src/pki.c b/src/pki.c
|
||
|
index a7c84c5e..b606ae99 100644
|
||
|
--- a/src/pki.c
|
||
|
+++ b/src/pki.c
|
||
|
@@ -1114,7 +1114,7 @@ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key)
|
||
|
pub->type = tmp->type;
|
||
|
pub->type_c = tmp->type_c;
|
||
|
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
pub->dsa_pub = tmp->dsa;
|
||
|
tmp->dsa = NULL;
|
||
|
pub->rsa_pub = tmp->rsa;
|
||
|
@@ -1122,7 +1122,7 @@ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key)
|
||
|
#else
|
||
|
pub->key_pub = tmp->key;
|
||
|
tmp->key = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
ssh_key_free(tmp);
|
||
|
|
||
|
@@ -1140,12 +1140,12 @@ ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key)
|
||
|
}
|
||
|
|
||
|
privkey->type = key->type;
|
||
|
-#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+#ifndef HAVE_LIBCRYPTO
|
||
|
privkey->dsa_priv = key->dsa;
|
||
|
privkey->rsa_priv = key->rsa;
|
||
|
#else
|
||
|
privkey->key_priv = key->key;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+#endif /* HAVE_LIBCRYPTO */
|
||
|
|
||
|
return privkey;
|
||
|
}
|
||
|
diff --git a/src/pki_crypto.c b/src/pki_crypto.c
|
||
|
index 5b0d7ded..d3e98ba6 100644
|
||
|
--- a/src/pki_crypto.c
|
||
|
+++ b/src/pki_crypto.c
|
||
|
@@ -42,6 +42,10 @@
|
||
|
#include <openssl/params.h>
|
||
|
#include <openssl/core_names.h>
|
||
|
#include <openssl/param_build.h>
|
||
|
+#if defined(WITH_PKCS11_URI) && defined(WITH_PKCS11_PROVIDER)
|
||
|
+#include <openssl/store.h>
|
||
|
+#include <openssl/provider.h>
|
||
|
+#endif
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
#ifdef HAVE_OPENSSL_EC_H
|
||
|
@@ -91,37 +95,20 @@ void pki_key_clean(ssh_key key)
|
||
|
{
|
||
|
if (key == NULL)
|
||
|
return;
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- DSA_free(key->dsa);
|
||
|
- key->dsa = NULL;
|
||
|
- RSA_free(key->rsa);
|
||
|
- key->rsa = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-#ifdef HAVE_OPENSSL_ECC
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Move whole HAVE_OPENSSL_ECC into #if < 0x3 above
|
||
|
- */
|
||
|
-#if 1
|
||
|
- EC_KEY_free(key->ecdsa);
|
||
|
- key->ecdsa = NULL;
|
||
|
-#endif
|
||
|
-#endif /* HAVE_OPENSSL_ECC */
|
||
|
EVP_PKEY_free(key->key);
|
||
|
key->key = NULL;
|
||
|
}
|
||
|
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
static int pki_key_ecdsa_to_nid(EC_KEY *k)
|
||
|
{
|
||
|
const EC_GROUP *g = EC_KEY_get0_group(k);
|
||
|
int nid;
|
||
|
|
||
|
+ if (g == NULL) {
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
nid = EC_GROUP_get_curve_name(g);
|
||
|
if (nid) {
|
||
|
return nid;
|
||
|
@@ -133,34 +120,22 @@ static int pki_key_ecdsa_to_nid(EC_KEY *k)
|
||
|
static int pki_key_ecdsa_to_nid(EVP_PKEY *k)
|
||
|
{
|
||
|
char gname[25] = { 0 };
|
||
|
- int nid, rc;
|
||
|
-
|
||
|
- rc = EVP_PKEY_get_utf8_string_param(k, "group", gname, 25, NULL);
|
||
|
- if (rc != 1)
|
||
|
- return -1;
|
||
|
+ int rc;
|
||
|
|
||
|
- if (strcmp(gname, NISTP256) == 0
|
||
|
- || strcmp(gname, "secp256r1") == 0
|
||
|
- || strcmp(gname, "prime256v1") == 0) {
|
||
|
- nid = NID_X9_62_prime256v1;
|
||
|
- } else if (strcmp(gname, NISTP384) == 0
|
||
|
- || strcmp(gname, "secp384r1") == 0) {
|
||
|
- nid = NID_secp384r1;
|
||
|
- } else if (strcmp(gname, NISTP521) == 0
|
||
|
- || strcmp(gname, "secp521r1") == 0) {
|
||
|
- nid = NID_secp521r1;
|
||
|
- } else
|
||
|
+ rc = EVP_PKEY_get_utf8_string_param(k,
|
||
|
+ OSSL_PKEY_PARAM_GROUP_NAME,
|
||
|
+ gname,
|
||
|
+ 25,
|
||
|
+ NULL);
|
||
|
+ if (rc != 1) {
|
||
|
return -1;
|
||
|
+ }
|
||
|
|
||
|
- return nid;
|
||
|
+ return pki_key_ecgroup_name_to_nid(gname);
|
||
|
}
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
static enum ssh_keytypes_e pki_key_ecdsa_to_key_type(EC_KEY *k)
|
||
|
#else
|
||
|
static enum ssh_keytypes_e pki_key_ecdsa_to_key_type(EVP_PKEY *k)
|
||
|
@@ -227,160 +202,139 @@ int pki_key_ecdsa_nid_from_name(const char *name)
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
-static ssh_string make_ecpoint_string(const EC_GROUP *g,
|
||
|
- const EC_POINT *p)
|
||
|
-{
|
||
|
- ssh_string s;
|
||
|
- size_t len;
|
||
|
-
|
||
|
- len = EC_POINT_point2oct(g,
|
||
|
- p,
|
||
|
- POINT_CONVERSION_UNCOMPRESSED,
|
||
|
- NULL,
|
||
|
- 0,
|
||
|
- NULL);
|
||
|
- if (len == 0) {
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- s = ssh_string_new(len);
|
||
|
- if (s == NULL) {
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- len = EC_POINT_point2oct(g,
|
||
|
- p,
|
||
|
- POINT_CONVERSION_UNCOMPRESSED,
|
||
|
- ssh_string_data(s),
|
||
|
- ssh_string_len(s),
|
||
|
- NULL);
|
||
|
- if (len != ssh_string_len(s)) {
|
||
|
- SSH_STRING_FREE(s);
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- return s;
|
||
|
-}
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-
|
||
|
int pki_privkey_build_ecdsa(ssh_key key, int nid, ssh_string e, ssh_string exp)
|
||
|
{
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+ int rc = 0;
|
||
|
+ BIGNUM *bexp = NULL;
|
||
|
+
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
EC_POINT *p = NULL;
|
||
|
const EC_GROUP *g = NULL;
|
||
|
- int ok;
|
||
|
- BIGNUM *bexp = NULL;
|
||
|
+ EC_KEY *ecdsa = NULL;
|
||
|
#else
|
||
|
- int rc;
|
||
|
- const BIGNUM *expb;
|
||
|
const char *group_name = OSSL_EC_curve_nid2name(nid);
|
||
|
OSSL_PARAM_BLD *param_bld = NULL;
|
||
|
|
||
|
if (group_name == NULL) {
|
||
|
return -1;
|
||
|
}
|
||
|
- expb = ssh_make_string_bn(exp);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
+ bexp = ssh_make_string_bn(exp);
|
||
|
+ if (bexp == NULL) {
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
key->ecdsa_nid = nid;
|
||
|
key->type_c = pki_key_ecdsa_nid_to_name(nid);
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||
|
- if (key->ecdsa == NULL) {
|
||
|
- return -1;
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||
|
+ if (ecdsa == NULL) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
}
|
||
|
|
||
|
- g = EC_KEY_get0_group(key->ecdsa);
|
||
|
+ g = EC_KEY_get0_group(ecdsa);
|
||
|
|
||
|
p = EC_POINT_new(g);
|
||
|
if (p == NULL) {
|
||
|
- return -1;
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
}
|
||
|
|
||
|
- ok = EC_POINT_oct2point(g,
|
||
|
+ rc = EC_POINT_oct2point(g,
|
||
|
p,
|
||
|
ssh_string_data(e),
|
||
|
ssh_string_len(e),
|
||
|
NULL);
|
||
|
- if (!ok) {
|
||
|
- EC_POINT_free(p);
|
||
|
- return -1;
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
}
|
||
|
|
||
|
/* EC_KEY_set_public_key duplicates p */
|
||
|
- ok = EC_KEY_set_public_key(key->ecdsa, p);
|
||
|
- EC_POINT_free(p);
|
||
|
- if (!ok) {
|
||
|
- return -1;
|
||
|
+ rc = EC_KEY_set_public_key(ecdsa, p);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
}
|
||
|
|
||
|
- bexp = ssh_make_string_bn(exp);
|
||
|
- if (bexp == NULL) {
|
||
|
- EC_KEY_free(key->ecdsa);
|
||
|
- return -1;
|
||
|
- }
|
||
|
/* EC_KEY_set_private_key duplicates exp */
|
||
|
- ok = EC_KEY_set_private_key(key->ecdsa, bexp);
|
||
|
- BN_free(bexp);
|
||
|
- if (!ok) {
|
||
|
- EC_KEY_free(key->ecdsa);
|
||
|
- return -1;
|
||
|
+ rc = EC_KEY_set_private_key(ecdsa, bexp);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
}
|
||
|
|
||
|
- return 0;
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
+ if (key->key == NULL) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* ecdsa will be freed when the EVP_PKEY key->key is freed */
|
||
|
+ rc = EVP_PKEY_assign_EC_KEY(key->key, ecdsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
+ /* ssh_key is now the owner of this memory */
|
||
|
+ ecdsa = NULL;
|
||
|
+
|
||
|
+ /* set rc to 0 if everything went well */
|
||
|
+ rc = 0;
|
||
|
+
|
||
|
+cleanup:
|
||
|
+ EC_KEY_free(ecdsa);
|
||
|
+ EC_POINT_free(p);
|
||
|
+ BN_free(bexp);
|
||
|
+ return rc;
|
||
|
#else
|
||
|
param_bld = OSSL_PARAM_BLD_new();
|
||
|
- if (param_bld == NULL)
|
||
|
- goto err;
|
||
|
+ if (param_bld == NULL){
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
|
||
|
rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_PKEY_PARAM_GROUP_NAME,
|
||
|
group_name, strlen(group_name));
|
||
|
- if (rc != 1)
|
||
|
- goto err;
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
+
|
||
|
rc = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
|
||
|
ssh_string_data(e), ssh_string_len(e));
|
||
|
- if (rc != 1)
|
||
|
- goto err;
|
||
|
- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, expb);
|
||
|
- if (rc != 1)
|
||
|
- goto err;
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, bexp);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = -1;
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
|
||
|
rc = evp_build_pkey("EC", param_bld, &(key->key), EVP_PKEY_KEYPAIR);
|
||
|
- OSSL_PARAM_BLD_free(param_bld);
|
||
|
|
||
|
- return rc;
|
||
|
-err:
|
||
|
+cleanup:
|
||
|
OSSL_PARAM_BLD_free(param_bld);
|
||
|
- return -1;
|
||
|
+ BN_free(bexp);
|
||
|
+ return rc;
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
}
|
||
|
|
||
|
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
|
||
|
{
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+ int rc;
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
EC_POINT *p = NULL;
|
||
|
const EC_GROUP *g = NULL;
|
||
|
+ EC_KEY *ecdsa = NULL;
|
||
|
int ok;
|
||
|
#else
|
||
|
- int rc;
|
||
|
const char *group_name = OSSL_EC_curve_nid2name(nid);
|
||
|
OSSL_PARAM_BLD *param_bld;
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
@@ -388,20 +342,17 @@ int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
|
||
|
key->ecdsa_nid = nid;
|
||
|
key->type_c = pki_key_ecdsa_nid_to_name(nid);
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
- #if 1
|
||
|
- key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||
|
- if (key->ecdsa == NULL) {
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||
|
+ if (ecdsa == NULL) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
- g = EC_KEY_get0_group(key->ecdsa);
|
||
|
+ g = EC_KEY_get0_group(ecdsa);
|
||
|
|
||
|
p = EC_POINT_new(g);
|
||
|
if (p == NULL) {
|
||
|
+ EC_KEY_free(ecdsa);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
@@ -411,14 +362,28 @@ int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
|
||
|
ssh_string_len(e),
|
||
|
NULL);
|
||
|
if (!ok) {
|
||
|
+ EC_KEY_free(ecdsa);
|
||
|
EC_POINT_free(p);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/* EC_KEY_set_public_key duplicates p */
|
||
|
- ok = EC_KEY_set_public_key(key->ecdsa, p);
|
||
|
+ ok = EC_KEY_set_public_key(ecdsa, p);
|
||
|
EC_POINT_free(p);
|
||
|
if (!ok) {
|
||
|
+ EC_KEY_free(ecdsa);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
+ if (key->key == NULL) {
|
||
|
+ EC_KEY_free(ecdsa);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_EC_KEY(key->key, ecdsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ EC_KEY_free(ecdsa);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
@@ -472,8 +437,9 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
const BIGNUM *p = NULL, *q = NULL, *g = NULL,
|
||
|
*pub_key = NULL, *priv_key = NULL;
|
||
|
BIGNUM *np, *nq, *ng, *npub_key, *npriv_key;
|
||
|
- new->dsa = DSA_new();
|
||
|
- if (new->dsa == NULL) {
|
||
|
+ DSA *new_dsa = DSA_new();
|
||
|
+ const DSA *key_dsa = EVP_PKEY_get0_DSA(key->key);
|
||
|
+ if (new_dsa == NULL) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
@@ -484,11 +450,12 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
* pub_key = public key y = g^x
|
||
|
* priv_key = private key x
|
||
|
*/
|
||
|
- DSA_get0_pqg(key->dsa, &p, &q, &g);
|
||
|
+ DSA_get0_pqg(key_dsa, &p, &q, &g);
|
||
|
np = BN_dup(p);
|
||
|
nq = BN_dup(q);
|
||
|
ng = BN_dup(g);
|
||
|
if (np == NULL || nq == NULL || ng == NULL) {
|
||
|
+ DSA_free(new_dsa);
|
||
|
BN_free(np);
|
||
|
BN_free(nq);
|
||
|
BN_free(ng);
|
||
|
@@ -496,38 +463,58 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
}
|
||
|
|
||
|
/* Memory management of np, nq and ng is transferred to DSA object */
|
||
|
- rc = DSA_set0_pqg(new->dsa, np, nq, ng);
|
||
|
+ rc = DSA_set0_pqg(new_dsa, np, nq, ng);
|
||
|
if (rc == 0) {
|
||
|
+ DSA_free(new_dsa);
|
||
|
BN_free(np);
|
||
|
BN_free(nq);
|
||
|
BN_free(ng);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
- DSA_get0_key(key->dsa, &pub_key, &priv_key);
|
||
|
+ DSA_get0_key(key_dsa, &pub_key, &priv_key);
|
||
|
npub_key = BN_dup(pub_key);
|
||
|
if (npub_key == NULL) {
|
||
|
+ DSA_free(new_dsa);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* Memory management of npubkey is transferred to DSA object */
|
||
|
- rc = DSA_set0_key(new->dsa, npub_key, NULL);
|
||
|
+ rc = DSA_set0_key(new_dsa, npub_key, NULL);
|
||
|
if (rc == 0) {
|
||
|
+ DSA_free(new_dsa);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) {
|
||
|
npriv_key = BN_dup(priv_key);
|
||
|
if (npriv_key == NULL) {
|
||
|
+ DSA_free(new_dsa);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* Memory management of npriv_key is transferred to DSA object */
|
||
|
- rc = DSA_set0_key(new->dsa, NULL, npriv_key);
|
||
|
+ rc = DSA_set0_key(new_dsa, NULL, npriv_key);
|
||
|
if (rc == 0) {
|
||
|
+ DSA_free(new_dsa);
|
||
|
goto fail;
|
||
|
}
|
||
|
}
|
||
|
+
|
||
|
+ new->key = EVP_PKEY_new();
|
||
|
+ if (new->key == NULL) {
|
||
|
+ DSA_free(new_dsa);
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_DSA(new->key, new_dsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ EVP_PKEY_free(new->key);
|
||
|
+ DSA_free(new_dsa);
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ new_dsa = NULL;
|
||
|
#else
|
||
|
rc = evp_dup_dsa_pkey(key, new, demote);
|
||
|
if (rc != SSH_OK) {
|
||
|
@@ -541,6 +528,8 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
const BIGNUM *n = NULL, *e = NULL, *d = NULL;
|
||
|
BIGNUM *nn, *ne, *nd;
|
||
|
+ RSA *new_rsa = NULL;
|
||
|
+ const RSA *key_rsa = EVP_PKEY_get0_RSA(key->key);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
|
||
|
#ifdef WITH_PKCS11_URI
|
||
|
/* Take the PKCS#11 keys as they are */
|
||
|
@@ -554,8 +543,8 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
}
|
||
|
#endif /* WITH_PKCS11_URI */
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- new->rsa = RSA_new();
|
||
|
- if (new->rsa == NULL) {
|
||
|
+ new_rsa = RSA_new();
|
||
|
+ if (new_rsa == NULL) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
@@ -569,18 +558,20 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
* dmq1 = d mod (q-1)
|
||
|
* iqmp = q^-1 mod p
|
||
|
*/
|
||
|
- RSA_get0_key(key->rsa, &n, &e, &d);
|
||
|
+ RSA_get0_key(key_rsa, &n, &e, &d);
|
||
|
nn = BN_dup(n);
|
||
|
ne = BN_dup(e);
|
||
|
if (nn == NULL || ne == NULL) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
BN_free(nn);
|
||
|
BN_free(ne);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* Memory management of nn and ne is transferred to RSA object */
|
||
|
- rc = RSA_set0_key(new->rsa, nn, ne, NULL);
|
||
|
+ rc = RSA_set0_key(new_rsa, nn, ne, NULL);
|
||
|
if (rc == 0) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
BN_free(nn);
|
||
|
BN_free(ne);
|
||
|
goto fail;
|
||
|
@@ -593,43 +584,48 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
|
||
|
nd = BN_dup(d);
|
||
|
if (nd == NULL) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* Memory management of nd is transferred to RSA object */
|
||
|
- rc = RSA_set0_key(new->rsa, NULL, NULL, nd);
|
||
|
+ rc = RSA_set0_key(new_rsa, NULL, NULL, nd);
|
||
|
if (rc == 0) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* p, q, dmp1, dmq1 and iqmp may be NULL in private keys, but the
|
||
|
* RSA operations are much faster when these values are available.
|
||
|
*/
|
||
|
- RSA_get0_factors(key->rsa, &p, &q);
|
||
|
+ RSA_get0_factors(key_rsa, &p, &q);
|
||
|
if (p != NULL && q != NULL) { /* need to set both of them */
|
||
|
np = BN_dup(p);
|
||
|
nq = BN_dup(q);
|
||
|
if (np == NULL || nq == NULL) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
BN_free(np);
|
||
|
BN_free(nq);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* Memory management of np and nq is transferred to RSA object */
|
||
|
- rc = RSA_set0_factors(new->rsa, np, nq);
|
||
|
+ rc = RSA_set0_factors(new_rsa, np, nq);
|
||
|
if (rc == 0) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
BN_free(np);
|
||
|
BN_free(nq);
|
||
|
goto fail;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- RSA_get0_crt_params(key->rsa, &dmp1, &dmq1, &iqmp);
|
||
|
+ RSA_get0_crt_params(key_rsa, &dmp1, &dmq1, &iqmp);
|
||
|
if (dmp1 != NULL || dmq1 != NULL || iqmp != NULL) {
|
||
|
ndmp1 = BN_dup(dmp1);
|
||
|
ndmq1 = BN_dup(dmq1);
|
||
|
niqmp = BN_dup(iqmp);
|
||
|
if (ndmp1 == NULL || ndmq1 == NULL || niqmp == NULL) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
BN_free(ndmp1);
|
||
|
BN_free(ndmq1);
|
||
|
BN_free(niqmp);
|
||
|
@@ -638,8 +634,9 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
|
||
|
/* Memory management of ndmp1, ndmq1 and niqmp is transferred
|
||
|
* to RSA object */
|
||
|
- rc = RSA_set0_crt_params(new->rsa, ndmp1, ndmq1, niqmp);
|
||
|
+ rc = RSA_set0_crt_params(new_rsa, ndmp1, ndmq1, niqmp);
|
||
|
if (rc == 0) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
BN_free(ndmp1);
|
||
|
BN_free(ndmq1);
|
||
|
BN_free(niqmp);
|
||
|
@@ -647,6 +644,21 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
+
|
||
|
+ new->key = EVP_PKEY_new();
|
||
|
+ if (new->key == NULL) {
|
||
|
+ RSA_free(new_rsa);
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_RSA(new->key, new_rsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ EVP_PKEY_free(new->key);
|
||
|
+ RSA_free(new_rsa);
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ new_rsa = NULL;
|
||
|
#else
|
||
|
rc = evp_dup_rsa_pkey(key, new, demote);
|
||
|
if (rc != SSH_OK) {
|
||
|
@@ -668,44 +680,56 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||
|
goto fail;
|
||
|
}
|
||
|
new->key = key->key;
|
||
|
- rc = EC_KEY_up_ref(key->ecdsa);
|
||
|
- if (rc != 1) {
|
||
|
- goto fail;
|
||
|
- }
|
||
|
- new->ecdsa = key->ecdsa;
|
||
|
return new;
|
||
|
}
|
||
|
#endif /* WITH_PKCS11_URI */
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
/* privkey -> pubkey */
|
||
|
if (demote && ssh_key_is_private(key)) {
|
||
|
- const EC_POINT *p;
|
||
|
+ const EC_POINT *p = NULL;
|
||
|
+ EC_KEY *new_ecdsa = NULL, *old_ecdsa = NULL;
|
||
|
int ok;
|
||
|
|
||
|
- new->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||
|
- if (new->ecdsa == NULL) {
|
||
|
+ new_ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||
|
+ if (new_ecdsa == NULL) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
- p = EC_KEY_get0_public_key(key->ecdsa);
|
||
|
+ old_ecdsa = EVP_PKEY_get0_EC_KEY(key->key);
|
||
|
+ if (old_ecdsa == NULL) {
|
||
|
+ EC_KEY_free(new_ecdsa);
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ p = EC_KEY_get0_public_key(old_ecdsa);
|
||
|
if (p == NULL) {
|
||
|
+ EC_KEY_free(new_ecdsa);
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ ok = EC_KEY_set_public_key(new_ecdsa, p);
|
||
|
+ if (ok != 1) {
|
||
|
+ EC_KEY_free(new_ecdsa);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
- ok = EC_KEY_set_public_key(new->ecdsa, p);
|
||
|
- if (!ok) {
|
||
|
+ new->key = EVP_PKEY_new();
|
||
|
+ if (new->key == NULL) {
|
||
|
+ EC_KEY_free(new_ecdsa);
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ ok = EVP_PKEY_assign_EC_KEY(new->key, new_ecdsa);
|
||
|
+ if (ok != 1) {
|
||
|
+ EC_KEY_free(new_ecdsa);
|
||
|
goto fail;
|
||
|
}
|
||
|
} else {
|
||
|
- rc = EC_KEY_up_ref(key->ecdsa);
|
||
|
+ rc = EVP_PKEY_up_ref(key->key);
|
||
|
if (rc != 1) {
|
||
|
goto fail;
|
||
|
}
|
||
|
- new->ecdsa = key->ecdsa;
|
||
|
+ new->key = key->key;
|
||
|
}
|
||
|
#else
|
||
|
rc = evp_dup_ecdsa_pkey(key, new, demote);
|
||
|
@@ -736,7 +760,8 @@ fail:
|
||
|
int pki_key_generate_rsa(ssh_key key, int parameter){
|
||
|
int rc;
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- BIGNUM *e;
|
||
|
+ BIGNUM *e = NULL;
|
||
|
+ RSA *key_rsa = NULL;
|
||
|
#else
|
||
|
OSSL_PARAM params[3];
|
||
|
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
|
||
|
@@ -745,15 +770,34 @@ int pki_key_generate_rsa(ssh_key key, int parameter){
|
||
|
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
e = BN_new();
|
||
|
- key->rsa = RSA_new();
|
||
|
+ key_rsa = RSA_new();
|
||
|
+ if (key_rsa == NULL) {
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
|
||
|
BN_set_word(e, 65537);
|
||
|
- rc = RSA_generate_key_ex(key->rsa, parameter, e, NULL);
|
||
|
+ rc = RSA_generate_key_ex(key_rsa, parameter, e, NULL);
|
||
|
|
||
|
BN_free(e);
|
||
|
|
||
|
- if (rc <= 0 || key->rsa == NULL)
|
||
|
+ if (rc <= 0 || key_rsa == NULL) {
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
+ if (key->key == NULL) {
|
||
|
+ RSA_free(key_rsa);
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_RSA(key->key, key_rsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ RSA_free(key_rsa);
|
||
|
+ EVP_PKEY_free(key->key);
|
||
|
return SSH_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ key_rsa = NULL;
|
||
|
#else
|
||
|
key->key = NULL;
|
||
|
|
||
|
@@ -785,11 +829,11 @@ int pki_key_generate_rsa(ssh_key key, int parameter){
|
||
|
int pki_key_generate_dss(ssh_key key, int parameter){
|
||
|
int rc;
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- key->dsa = DSA_new();
|
||
|
- if (key->dsa == NULL) {
|
||
|
+ DSA *key_dsa = DSA_new();
|
||
|
+ if (key_dsa == NULL) {
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
- rc = DSA_generate_parameters_ex(key->dsa,
|
||
|
+ rc = DSA_generate_parameters_ex(key_dsa,
|
||
|
parameter,
|
||
|
NULL, /* seed */
|
||
|
0, /* seed_len */
|
||
|
@@ -797,16 +841,29 @@ int pki_key_generate_dss(ssh_key key, int parameter){
|
||
|
NULL, /* h_ret */
|
||
|
NULL); /* cb */
|
||
|
if (rc != 1) {
|
||
|
- DSA_free(key->dsa);
|
||
|
- key->dsa = NULL;
|
||
|
+ DSA_free(key_dsa);
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
- rc = DSA_generate_key(key->dsa);
|
||
|
+ rc = DSA_generate_key(key_dsa);
|
||
|
if (rc != 1) {
|
||
|
- DSA_free(key->dsa);
|
||
|
- key->dsa=NULL;
|
||
|
+ DSA_free(key_dsa);
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
+ if (key->key == NULL) {
|
||
|
+ DSA_free(key_dsa);
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_DSA(key->key, key_dsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ DSA_free(key_dsa);
|
||
|
+ EVP_PKEY_free(key->key);
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ key_dsa = NULL;
|
||
|
#else
|
||
|
OSSL_PARAM params[3];
|
||
|
EVP_PKEY *param_key = NULL;
|
||
|
@@ -871,12 +928,10 @@ int pki_key_generate_dss(ssh_key key, int parameter){
|
||
|
}
|
||
|
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
-int pki_key_generate_ecdsa(ssh_key key, int parameter) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+int pki_key_generate_ecdsa(ssh_key key, int parameter)
|
||
|
+{
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ EC_KEY *ecdsa = NULL;
|
||
|
int ok;
|
||
|
#else
|
||
|
const char *group_name = NULL;
|
||
|
@@ -885,33 +940,21 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter) {
|
||
|
case 256:
|
||
|
key->ecdsa_nid = NID_X9_62_prime256v1;
|
||
|
key->type = SSH_KEYTYPE_ECDSA_P256;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
group_name = NISTP256;
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
break;
|
||
|
case 384:
|
||
|
key->ecdsa_nid = NID_secp384r1;
|
||
|
key->type = SSH_KEYTYPE_ECDSA_P384;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
group_name = NISTP384;
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
break;
|
||
|
case 521:
|
||
|
key->ecdsa_nid = NID_secp521r1;
|
||
|
key->type = SSH_KEYTYPE_ECDSA_P521;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
group_name = NISTP521;
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
break;
|
||
|
@@ -920,35 +963,37 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter) {
|
||
|
"generation", parameter);
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||
|
- if (key->ecdsa == NULL) {
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||
|
+ if (ecdsa == NULL) {
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
-#else
|
||
|
- key->key = EVP_EC_gen(group_name);
|
||
|
+ ok = EC_KEY_generate_key(ecdsa);
|
||
|
+ if (!ok) {
|
||
|
+ EC_KEY_free(ecdsa);
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ EC_KEY_set_asn1_flag(ecdsa, OPENSSL_EC_NAMED_CURVE);
|
||
|
+
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
if (key->key == NULL) {
|
||
|
+ EC_KEY_free(ecdsa);
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- ok = EC_KEY_generate_key(key->ecdsa);
|
||
|
- if (!ok) {
|
||
|
- EC_KEY_free(key->ecdsa);
|
||
|
+ ok = EVP_PKEY_assign_EC_KEY(key->key, ecdsa);
|
||
|
+ if (ok != 1) {
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
|
||
|
- EC_KEY_set_asn1_flag(key->ecdsa, OPENSSL_EC_NAMED_CURVE);
|
||
|
+#else
|
||
|
+ key->key = EVP_EC_gen(group_name);
|
||
|
+ if (key->key == NULL) {
|
||
|
+ return SSH_ERROR;
|
||
|
+ }
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
+
|
||
|
return SSH_OK;
|
||
|
}
|
||
|
#endif /* HAVE_OPENSSL_ECC */
|
||
|
@@ -960,104 +1005,34 @@ int pki_key_compare(const ssh_key k1,
|
||
|
const ssh_key k2,
|
||
|
enum ssh_keycmp_e what)
|
||
|
{
|
||
|
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
int rc;
|
||
|
(void) what;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
switch (k1->type) {
|
||
|
- case SSH_KEYTYPE_DSS:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- {
|
||
|
- const BIGNUM *p1, *p2, *q1, *q2, *g1, *g2,
|
||
|
- *pub_key1, *pub_key2, *priv_key1, *priv_key2;
|
||
|
- if (DSA_size(k1->dsa) != DSA_size(k2->dsa)) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- DSA_get0_pqg(k1->dsa, &p1, &q1, &g1);
|
||
|
- DSA_get0_pqg(k2->dsa, &p2, &q2, &g2);
|
||
|
- if (bignum_cmp(p1, p2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- if (bignum_cmp(q1, q2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- if (bignum_cmp(g1, g2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- DSA_get0_key(k1->dsa, &pub_key1, &priv_key1);
|
||
|
- DSA_get0_key(k2->dsa, &pub_key2, &priv_key2);
|
||
|
- if (bignum_cmp(pub_key1, pub_key2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
-
|
||
|
- if (what == SSH_KEY_CMP_PRIVATE) {
|
||
|
- if (bignum_cmp(priv_key1, priv_key2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- }
|
||
|
- break;
|
||
|
- }
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
- case SSH_KEYTYPE_RSA:
|
||
|
- case SSH_KEYTYPE_RSA1:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- {
|
||
|
- const BIGNUM *e1, *e2, *n1, *n2, *p1, *p2, *q1, *q2;
|
||
|
- if (RSA_size(k1->rsa) != RSA_size(k2->rsa)) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- RSA_get0_key(k1->rsa, &n1, &e1, NULL);
|
||
|
- RSA_get0_key(k2->rsa, &n2, &e2, NULL);
|
||
|
- if (bignum_cmp(e1, e2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- if (bignum_cmp(n1, n2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
-
|
||
|
- if (what == SSH_KEY_CMP_PRIVATE) {
|
||
|
- RSA_get0_factors(k1->rsa, &p1, &q1);
|
||
|
- RSA_get0_factors(k2->rsa, &p2, &q2);
|
||
|
- if (bignum_cmp(p1, p2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
-
|
||
|
- if (bignum_cmp(q1, q2) != 0) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- }
|
||
|
- break;
|
||
|
- }
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * delete this part of #if because it gets done below EC
|
||
|
- */
|
||
|
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- rc = EVP_PKEY_eq(k1->key, k2->key);
|
||
|
- if (rc != 1) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
- break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
case SSH_KEYTYPE_ECDSA_P256:
|
||
|
case SSH_KEYTYPE_ECDSA_P384:
|
||
|
case SSH_KEYTYPE_ECDSA_P521:
|
||
|
case SSH_KEYTYPE_SK_ECDSA:
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
{
|
||
|
- const EC_POINT *p1 = EC_KEY_get0_public_key(k1->ecdsa);
|
||
|
- const EC_POINT *p2 = EC_KEY_get0_public_key(k2->ecdsa);
|
||
|
- const EC_GROUP *g1 = EC_KEY_get0_group(k1->ecdsa);
|
||
|
- const EC_GROUP *g2 = EC_KEY_get0_group(k2->ecdsa);
|
||
|
+ const EC_KEY *ec1 = EVP_PKEY_get0_EC_KEY(k1->key);
|
||
|
+ const EC_KEY *ec2 = EVP_PKEY_get0_EC_KEY(k2->key);
|
||
|
+ const EC_POINT *p1 = NULL;
|
||
|
+ const EC_POINT *p2 = NULL;
|
||
|
+ const EC_GROUP *g1 = NULL;
|
||
|
+ const EC_GROUP *g2 = NULL;
|
||
|
+
|
||
|
+ if (ec1 == NULL || ec2 == NULL) {
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ p1 = EC_KEY_get0_public_key(ec1);
|
||
|
+ p2 = EC_KEY_get0_public_key(ec2);
|
||
|
+ g1 = EC_KEY_get0_group(ec1);
|
||
|
+ g2 = EC_KEY_get0_group(ec2);
|
||
|
|
||
|
- if (p1 == NULL || p2 == NULL) {
|
||
|
+ if (p1 == NULL || p2 == NULL || g1 == NULL || g2 == NULL) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
@@ -1070,8 +1045,8 @@ int pki_key_compare(const ssh_key k1,
|
||
|
}
|
||
|
|
||
|
if (what == SSH_KEY_CMP_PRIVATE) {
|
||
|
- if (bignum_cmp(EC_KEY_get0_private_key(k1->ecdsa),
|
||
|
- EC_KEY_get0_private_key(k2->ecdsa))) {
|
||
|
+ if (bignum_cmp(EC_KEY_get0_private_key(ec1),
|
||
|
+ EC_KEY_get0_private_key(ec2))) {
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
@@ -1079,17 +1054,14 @@ int pki_key_compare(const ssh_key k1,
|
||
|
}
|
||
|
#endif /* HAVE_OPENSSL_ECC */
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * else
|
||
|
- */
|
||
|
-#if 0
|
||
|
+ case SSH_KEYTYPE_DSS:
|
||
|
+ case SSH_KEYTYPE_RSA:
|
||
|
+ case SSH_KEYTYPE_RSA1:
|
||
|
rc = EVP_PKEY_eq(k1->key, k2->key);
|
||
|
if (rc != 1) {
|
||
|
return 1;
|
||
|
}
|
||
|
break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
case SSH_KEYTYPE_ED25519:
|
||
|
case SSH_KEYTYPE_SK_ED25519:
|
||
|
/* ed25519 keys handled globally */
|
||
|
@@ -1118,65 +1090,11 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
|
||
|
|
||
|
switch (key->type) {
|
||
|
case SSH_KEYTYPE_DSS:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- pkey = EVP_PKEY_new();
|
||
|
- if (pkey == NULL) {
|
||
|
- goto err;
|
||
|
- }
|
||
|
-
|
||
|
- rc = EVP_PKEY_set1_DSA(pkey, key->dsa);
|
||
|
- break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
case SSH_KEYTYPE_RSA:
|
||
|
case SSH_KEYTYPE_RSA1:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- pkey = EVP_PKEY_new();
|
||
|
- if (pkey == NULL) {
|
||
|
- goto err;
|
||
|
- }
|
||
|
-
|
||
|
- rc = EVP_PKEY_set1_RSA(pkey, key->rsa);
|
||
|
- break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Delete this part, because it is done below HAVE_ECC
|
||
|
- */
|
||
|
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- rc = EVP_PKEY_up_ref(key->key);
|
||
|
- if (rc != 1) {
|
||
|
- goto err;
|
||
|
- }
|
||
|
- pkey = key->key;
|
||
|
-
|
||
|
- /* Mark the operation as successful as for the other key types */
|
||
|
- rc = 1;
|
||
|
-
|
||
|
- break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
- case SSH_KEYTYPE_ECDSA_P256:
|
||
|
- case SSH_KEYTYPE_ECDSA_P384:
|
||
|
- case SSH_KEYTYPE_ECDSA_P521:
|
||
|
-#ifdef HAVE_ECC
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- pkey = EVP_PKEY_new();
|
||
|
- if (pkey == NULL) {
|
||
|
- goto err;
|
||
|
- }
|
||
|
-
|
||
|
- rc = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
|
||
|
- break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-#endif /* HAVE_ECC */
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
+ case SSH_KEYTYPE_ECDSA_P256:
|
||
|
+ case SSH_KEYTYPE_ECDSA_P384:
|
||
|
+ case SSH_KEYTYPE_ECDSA_P521:
|
||
|
rc = EVP_PKEY_up_ref(key->key);
|
||
|
if (rc != 1) {
|
||
|
goto err;
|
||
|
@@ -1187,7 +1105,6 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
|
||
|
rc = 1;
|
||
|
|
||
|
break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
case SSH_KEYTYPE_ED25519:
|
||
|
#ifdef HAVE_OPENSSL_ED25519
|
||
|
/* In OpenSSL, the input is the private key seed only, which means
|
||
|
@@ -1282,14 +1199,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||
|
{
|
||
|
BIO *mem = NULL;
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- DSA *dsa = NULL;
|
||
|
- RSA *rsa = NULL;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-#ifdef HAVE_OPENSSL_ECC
|
||
|
EC_KEY *ecdsa = NULL;
|
||
|
-#else
|
||
|
- void *ecdsa = NULL;
|
||
|
-#endif /* HAVE_OPENSSL_ECC */
|
||
|
+#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
#ifdef HAVE_OPENSSL_ED25519
|
||
|
uint8_t *ed25519 = NULL;
|
||
|
#else
|
||
|
@@ -1324,37 +1235,15 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||
|
}
|
||
|
switch (EVP_PKEY_base_id(pkey)) {
|
||
|
case EVP_PKEY_DSA:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- dsa = EVP_PKEY_get1_DSA(pkey);
|
||
|
- if (dsa == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_WARN,
|
||
|
- "Parsing private key: %s",
|
||
|
- ERR_error_string(ERR_get_error(),NULL));
|
||
|
- goto fail;
|
||
|
- }
|
||
|
-#endif
|
||
|
type = SSH_KEYTYPE_DSS;
|
||
|
break;
|
||
|
case EVP_PKEY_RSA:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- rsa = EVP_PKEY_get1_RSA(pkey);
|
||
|
- if (rsa == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_WARN,
|
||
|
- "Parsing private key: %s",
|
||
|
- ERR_error_string(ERR_get_error(),NULL));
|
||
|
- goto fail;
|
||
|
- }
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
type = SSH_KEYTYPE_RSA;
|
||
|
break;
|
||
|
case EVP_PKEY_EC:
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- ecdsa = EVP_PKEY_get1_EC_KEY(pkey);
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ ecdsa = EVP_PKEY_get0_EC_KEY(pkey);
|
||
|
if (ecdsa == NULL) {
|
||
|
SSH_LOG(SSH_LOG_WARN,
|
||
|
"Parsing private key: %s",
|
||
|
@@ -1365,11 +1254,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||
|
|
||
|
/* pki_privatekey_type_from_string always returns P256 for ECDSA
|
||
|
* keys, so we need to figure out the correct type here */
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
type = pki_key_ecdsa_to_key_type(ecdsa);
|
||
|
#else
|
||
|
type = pki_key_ecdsa_to_key_type(pkey);
|
||
|
@@ -1379,10 +1264,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Remove these three lines
|
||
|
- */
|
||
|
break;
|
||
|
#endif /* HAVE_OPENSSL_ECC */
|
||
|
#ifdef HAVE_OPENSSL_ED25519
|
||
|
@@ -1438,25 +1319,12 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||
|
key->type = type;
|
||
|
key->type_c = ssh_key_type_to_char(type);
|
||
|
key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- key->dsa = dsa;
|
||
|
- key->rsa = rsa;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
key->key = pkey;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Move key->ecdsa line into the #if above this
|
||
|
- */
|
||
|
- key->ecdsa = ecdsa;
|
||
|
key->ed25519_privkey = ed25519;
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
if (is_ecdsa_key_type(key->type)) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ key->ecdsa_nid = pki_key_ecdsa_to_nid(ecdsa);
|
||
|
#else
|
||
|
key->ecdsa_nid = pki_key_ecdsa_to_nid(key->key);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
@@ -1467,17 +1335,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||
|
fail:
|
||
|
EVP_PKEY_free(pkey);
|
||
|
ssh_key_free(key);
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- DSA_free(dsa);
|
||
|
- RSA_free(rsa);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Move HAVE_OPENSSL_ECC #ifdef inside the #if above
|
||
|
- */
|
||
|
-#ifdef HAVE_OPENSSL_ECC
|
||
|
- EC_KEY_free(ecdsa);
|
||
|
-#endif
|
||
|
#ifdef HAVE_OPENSSL_ED25519
|
||
|
SAFE_FREE(ed25519);
|
||
|
#endif
|
||
|
@@ -1499,8 +1356,8 @@ int pki_privkey_build_dss(ssh_key key,
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
#else
|
||
|
- key->dsa = DSA_new();
|
||
|
- if (key->dsa == NULL) {
|
||
|
+ DSA *key_dsa = DSA_new();
|
||
|
+ if (key_dsa == NULL) {
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
@@ -1518,20 +1375,31 @@ int pki_privkey_build_dss(ssh_key key,
|
||
|
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
/* Memory management of bp, qq and bg is transferred to DSA object */
|
||
|
- rc = DSA_set0_pqg(key->dsa, bp, bq, bg);
|
||
|
+ rc = DSA_set0_pqg(key_dsa, bp, bq, bg);
|
||
|
if (rc == 0) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* Memory management of bpub_key and bpriv_key is transferred to DSA object */
|
||
|
- rc = DSA_set0_key(key->dsa, bpub_key, bpriv_key);
|
||
|
+ rc = DSA_set0_key(key_dsa, bpub_key, bpriv_key);
|
||
|
if (rc == 0) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
+ if (key->key == NULL) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_DSA(key->key, key_dsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
return SSH_OK;
|
||
|
fail:
|
||
|
- DSA_free(key->dsa);
|
||
|
+ EVP_PKEY_free(key->key);
|
||
|
+ DSA_free(key_dsa);
|
||
|
return SSH_ERROR;
|
||
|
#else
|
||
|
rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, bp);
|
||
|
@@ -1587,8 +1455,8 @@ int pki_pubkey_build_dss(ssh_key key,
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
#else
|
||
|
- key->dsa = DSA_new();
|
||
|
- if (key->dsa == NULL) {
|
||
|
+ DSA *key_dsa = DSA_new();
|
||
|
+ if (key_dsa == NULL) {
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
@@ -1605,20 +1473,31 @@ int pki_pubkey_build_dss(ssh_key key,
|
||
|
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
/* Memory management of bp, bq and bg is transferred to DSA object */
|
||
|
- rc = DSA_set0_pqg(key->dsa, bp, bq, bg);
|
||
|
+ rc = DSA_set0_pqg(key_dsa, bp, bq, bg);
|
||
|
if (rc == 0) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* Memory management of npub_key is transferred to DSA object */
|
||
|
- rc = DSA_set0_key(key->dsa, bpub_key, NULL);
|
||
|
+ rc = DSA_set0_key(key_dsa, bpub_key, NULL);
|
||
|
if (rc == 0) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
+ if (key->key == NULL) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_DSA(key->key, key_dsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
return SSH_OK;
|
||
|
fail:
|
||
|
- DSA_free(key->dsa);
|
||
|
+ EVP_PKEY_free(key->key);
|
||
|
+ DSA_free(key_dsa);
|
||
|
return SSH_ERROR;
|
||
|
#else
|
||
|
rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, bp);
|
||
|
@@ -1659,20 +1538,25 @@ int pki_privkey_build_rsa(ssh_key key,
|
||
|
ssh_string n,
|
||
|
ssh_string e,
|
||
|
ssh_string d,
|
||
|
- UNUSED_PARAM(ssh_string iqmp),
|
||
|
+ ssh_string iqmp,
|
||
|
ssh_string p,
|
||
|
ssh_string q)
|
||
|
{
|
||
|
int rc;
|
||
|
- BIGNUM *be, *bn, *bd/*, *biqmp*/, *bp, *bq;
|
||
|
+ BIGNUM *be = NULL, *bn = NULL, *bd = NULL;
|
||
|
+ BIGNUM *biqmp = NULL, *bp = NULL, *bq = NULL;
|
||
|
+ BIGNUM *aux = NULL, *d_consttime = NULL;
|
||
|
+ BIGNUM *bdmq1 = NULL, *bdmp1 = NULL;
|
||
|
+ BN_CTX *ctx = NULL;
|
||
|
+
|
||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new();
|
||
|
if (param_bld == NULL) {
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
#else
|
||
|
- key->rsa = RSA_new();
|
||
|
- if (key->rsa == NULL) {
|
||
|
+ RSA *key_rsa = RSA_new();
|
||
|
+ if (key_rsa == NULL) {
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
@@ -1680,7 +1564,7 @@ int pki_privkey_build_rsa(ssh_key key,
|
||
|
bn = ssh_make_string_bn(n);
|
||
|
be = ssh_make_string_bn(e);
|
||
|
bd = ssh_make_string_bn(d);
|
||
|
- /*biqmp = ssh_make_string_bn(iqmp);*/
|
||
|
+ biqmp = ssh_make_string_bn(iqmp);
|
||
|
bp = ssh_make_string_bn(p);
|
||
|
bq = ssh_make_string_bn(q);
|
||
|
if (be == NULL || bn == NULL || bd == NULL ||
|
||
|
@@ -1689,15 +1573,42 @@ int pki_privkey_build_rsa(ssh_key key,
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
+ /* Calculate remaining CRT parameters for OpenSSL to be happy
|
||
|
+ * taken from OpenSSH */
|
||
|
+ if ((ctx = BN_CTX_new()) == NULL) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+ if ((aux = BN_new()) == NULL ||
|
||
|
+ (bdmq1 = BN_new()) == NULL ||
|
||
|
+ (bdmp1 = BN_new()) == NULL) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+ if ((d_consttime = BN_dup(bd)) == NULL) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+ BN_set_flags(aux, BN_FLG_CONSTTIME);
|
||
|
+ BN_set_flags(d_consttime, BN_FLG_CONSTTIME);
|
||
|
+
|
||
|
+ if ((BN_sub(aux, bq, BN_value_one()) == 0) ||
|
||
|
+ (BN_mod(bdmq1, d_consttime, aux, ctx) == 0) ||
|
||
|
+ (BN_sub(aux, bp, BN_value_one()) == 0) ||
|
||
|
+ (BN_mod(bdmp1, d_consttime, aux, ctx) == 0)) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
/* Memory management of be, bn and bd is transferred to RSA object */
|
||
|
- rc = RSA_set0_key(key->rsa, bn, be, bd);
|
||
|
+ rc = RSA_set0_key(key_rsa, bn, be, bd);
|
||
|
if (rc == 0) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
/* Memory management of bp and bq is transferred to RSA object */
|
||
|
- rc = RSA_set0_factors(key->rsa, bp, bq);
|
||
|
+ rc = RSA_set0_factors(key_rsa, bp, bq);
|
||
|
if (rc == 0) {
|
||
|
goto fail;
|
||
|
}
|
||
|
@@ -1705,13 +1616,30 @@ int pki_privkey_build_rsa(ssh_key key,
|
||
|
/* p, q, dmp1, dmq1 and iqmp may be NULL in private keys, but the RSA
|
||
|
* operations are much faster when these values are available.
|
||
|
* https://www.openssl.org/docs/man1.0.2/crypto/rsa.html
|
||
|
+ * And OpenSSL fails to export these keys to PEM if these are missing:
|
||
|
+ * https://github.com/openssl/openssl/issues/21826
|
||
|
*/
|
||
|
- /* RSA_set0_crt_params(key->rsa, biqmp, NULL, NULL);
|
||
|
- TODO calculate missing crt_params */
|
||
|
+ rc = RSA_set0_crt_params(key_rsa, bdmp1, bdmq1, biqmp);
|
||
|
+ if (rc == 0) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+ bignum_safe_free(aux);
|
||
|
+ bignum_safe_free(d_consttime);
|
||
|
+
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
+ if (key->key == NULL) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_RSA(key->key, key_rsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
|
||
|
return SSH_OK;
|
||
|
fail:
|
||
|
- RSA_free(key->rsa);
|
||
|
+ RSA_free(key_rsa);
|
||
|
+ EVP_PKEY_free(key->key);
|
||
|
return SSH_ERROR;
|
||
|
#else
|
||
|
rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, bn);
|
||
|
@@ -1730,6 +1658,36 @@ fail:
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
+ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_FACTOR1, bp);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_FACTOR2, bq);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_EXPONENT1, bdmp1);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_EXPONENT2, bdmq1);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, biqmp);
|
||
|
+ if (rc != 1) {
|
||
|
+ rc = SSH_ERROR;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
rc = evp_build_pkey("RSA", param_bld, &(key->key), EVP_PKEY_KEYPAIR);
|
||
|
if (rc != SSH_OK) {
|
||
|
rc = SSH_ERROR;
|
||
|
@@ -1755,7 +1713,13 @@ fail:
|
||
|
bignum_safe_free(bd);
|
||
|
bignum_safe_free(bp);
|
||
|
bignum_safe_free(bq);
|
||
|
+ bignum_safe_free(biqmp);
|
||
|
|
||
|
+ bignum_safe_free(aux);
|
||
|
+ bignum_safe_free(d_consttime);
|
||
|
+ bignum_safe_free(bdmp1);
|
||
|
+ bignum_safe_free(bdmq1);
|
||
|
+ BN_CTX_free(ctx);
|
||
|
return rc;
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
}
|
||
|
@@ -1771,8 +1735,8 @@ int pki_pubkey_build_rsa(ssh_key key,
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
#else
|
||
|
- key->rsa = RSA_new();
|
||
|
- if (key->rsa == NULL) {
|
||
|
+ RSA *key_rsa = RSA_new();
|
||
|
+ if (key_rsa == NULL) {
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
@@ -1786,14 +1750,25 @@ int pki_pubkey_build_rsa(ssh_key key,
|
||
|
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
/* Memory management of bn and be is transferred to RSA object */
|
||
|
- rc = RSA_set0_key(key->rsa, bn, be, NULL);
|
||
|
+ rc = RSA_set0_key(key_rsa, bn, be, NULL);
|
||
|
if (rc == 0) {
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
+ key->key = EVP_PKEY_new();
|
||
|
+ if (key->key == NULL) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc = EVP_PKEY_assign_RSA(key->key, key_rsa);
|
||
|
+ if (rc != 1) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
return SSH_OK;
|
||
|
fail:
|
||
|
- RSA_free(key->rsa);
|
||
|
+ EVP_PKEY_free(key->key);
|
||
|
+ RSA_free(key_rsa);
|
||
|
return SSH_ERROR;
|
||
|
#else
|
||
|
rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, bn);
|
||
|
@@ -1866,8 +1841,9 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||
|
case SSH_KEYTYPE_DSS: {
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
const BIGNUM *bp, *bq, *bg, *bpub_key;
|
||
|
- DSA_get0_pqg(key->dsa, &bp, &bq, &bg);
|
||
|
- DSA_get0_key(key->dsa, &bpub_key, NULL);
|
||
|
+ const DSA *key_dsa = EVP_PKEY_get0_DSA(key->key);
|
||
|
+ DSA_get0_pqg(key_dsa, &bp, &bq, &bg);
|
||
|
+ DSA_get0_key(key_dsa, &bpub_key, NULL);
|
||
|
#else
|
||
|
const OSSL_PARAM *out_param = NULL;
|
||
|
rc = EVP_PKEY_todata(key->key, EVP_PKEY_PUBLIC_KEY, ¶ms);
|
||
|
@@ -1970,7 +1946,8 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||
|
case SSH_KEYTYPE_RSA1: {
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
const BIGNUM *be, *bn;
|
||
|
- RSA_get0_key(key->rsa, &bn, &be, NULL);
|
||
|
+ const RSA *key_rsa = EVP_PKEY_get0_RSA(key->key);
|
||
|
+ RSA_get0_key(key_rsa, &bn, &be, NULL);
|
||
|
#else
|
||
|
const OSSL_PARAM *out_param = NULL;
|
||
|
rc = EVP_PKEY_todata(key->key, EVP_PKEY_PUBLIC_KEY, ¶ms);
|
||
|
@@ -2043,14 +2020,16 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||
|
case SSH_KEYTYPE_SK_ECDSA:
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
{
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
+ EC_GROUP *group = NULL;
|
||
|
+ EC_POINT *point = NULL;
|
||
|
const void *pubkey;
|
||
|
size_t pubkey_len;
|
||
|
- OSSL_PARAM *params = NULL, *locate_param = NULL;
|
||
|
+ OSSL_PARAM *locate_param = NULL;
|
||
|
+#else
|
||
|
+ const EC_GROUP *group = NULL;
|
||
|
+ const EC_POINT *point = NULL;
|
||
|
+ EC_KEY *ec = NULL;
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
type_s = ssh_string_from_char(pki_key_ecdsa_nid_to_char(key->ecdsa_nid));
|
||
|
@@ -2066,25 +2045,29 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ ec = EVP_PKEY_get0_EC_KEY(key->key);
|
||
|
+ if (ec == NULL) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
#ifdef WITH_PKCS11_URI
|
||
|
- if (ssh_key_is_private(key) && !EC_KEY_get0_public_key(key->ecdsa)) {
|
||
|
- SSH_LOG(SSH_LOG_INFO, "It is mandatory to have separate public"
|
||
|
- " ECDSA key objects in the PKCS #11 device. Unlike RSA,"
|
||
|
- " ECDSA public keys cannot be derived from their private keys.");
|
||
|
- goto fail;
|
||
|
- }
|
||
|
+ if (ssh_key_is_private(key) && !EC_KEY_get0_public_key(ec)) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "It is mandatory to have separate"
|
||
|
+ " public ECDSA key objects in the PKCS #11 device."
|
||
|
+ " Unlike RSA, ECDSA public keys cannot be derived"
|
||
|
+ " from their private keys.");
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
#endif /* WITH_PKCS11_URI */
|
||
|
- e = make_ecpoint_string(EC_KEY_get0_group(key->ecdsa),
|
||
|
- EC_KEY_get0_public_key(key->ecdsa));
|
||
|
+ group = EC_KEY_get0_group(ec);
|
||
|
+ point = EC_KEY_get0_public_key(ec);
|
||
|
+ if (group == NULL || point == NULL) {
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+ e = pki_key_make_ecpoint_string(group, point);
|
||
|
#else
|
||
|
rc = EVP_PKEY_todata(key->key, EVP_PKEY_PUBLIC_KEY, ¶ms);
|
||
|
if (rc < 0) {
|
||
|
- OSSL_PARAM_free(params);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
@@ -2101,47 +2084,36 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||
|
|
||
|
rc = OSSL_PARAM_get_octet_string_ptr(locate_param, &pubkey, &pubkey_len);
|
||
|
if (rc != 1) {
|
||
|
- OSSL_PARAM_free(params);
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+ /* Convert the data to low-level representation */
|
||
|
+ group = EC_GROUP_new_by_curve_name_ex(NULL, NULL, key->ecdsa_nid);
|
||
|
+ point = EC_POINT_new(group);
|
||
|
+ rc = EC_POINT_oct2point(group, point, pubkey, pubkey_len, NULL);
|
||
|
+ if (group == NULL || point == NULL || rc != 1) {
|
||
|
+ EC_GROUP_free(group);
|
||
|
+ EC_POINT_free(point);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
- e = ssh_string_new(pubkey_len);
|
||
|
+ e = pki_key_make_ecpoint_string(group, point);
|
||
|
+ EC_GROUP_free(group);
|
||
|
+ EC_POINT_free(point);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
if (e == NULL) {
|
||
|
SSH_BUFFER_FREE(buffer);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
- if (memcpy(ssh_string_data(e), pubkey, pubkey_len) == NULL) {
|
||
|
- OSSL_PARAM_free(params);
|
||
|
- goto fail;
|
||
|
- }
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
rc = ssh_buffer_add_ssh_string(buffer, e);
|
||
|
if (rc < 0) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
- OSSL_PARAM_free(params);
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
ssh_string_burn(e);
|
||
|
SSH_STRING_FREE(e);
|
||
|
e = NULL;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
OSSL_PARAM_free(params);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
|
||
|
@@ -2415,12 +2387,14 @@ static int pki_signature_from_rsa_blob(const ssh_key pubkey,
|
||
|
size_t len = ssh_string_len(sig_blob);
|
||
|
|
||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- if (pubkey->rsa == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_WARN, "Pubkey RSA field NULL");
|
||
|
+ const RSA *rsa = EVP_PKEY_get0_RSA(pubkey->key);
|
||
|
+
|
||
|
+ if (rsa == NULL) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE, "RSA field NULL");
|
||
|
goto errout;
|
||
|
}
|
||
|
|
||
|
- rsalen = RSA_size(pubkey->rsa);
|
||
|
+ rsalen = RSA_size(rsa);
|
||
|
#else
|
||
|
if (EVP_PKEY_get_base_id(pubkey->key) != EVP_PKEY_RSA) {
|
||
|
SSH_LOG(SSH_LOG_WARN, "Key has no RSA pubkey");
|
||
|
@@ -2851,60 +2825,14 @@ static const EVP_MD *pki_digest_to_md(enum ssh_digest_e hash_type)
|
||
|
static EVP_PKEY *pki_key_to_pkey(ssh_key key)
|
||
|
{
|
||
|
EVP_PKEY *pkey = NULL;
|
||
|
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
int rc = 0;
|
||
|
-#endif
|
||
|
|
||
|
switch (key->type) {
|
||
|
case SSH_KEYTYPE_DSS:
|
||
|
case SSH_KEYTYPE_DSS_CERT01:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- if (key->dsa == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_TRACE, "NULL key->dsa");
|
||
|
- goto error;
|
||
|
- }
|
||
|
- pkey = EVP_PKEY_new();
|
||
|
- if (pkey == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_TRACE, "Out of memory");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- EVP_PKEY_set1_DSA(pkey, key->dsa);
|
||
|
- break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
case SSH_KEYTYPE_RSA:
|
||
|
case SSH_KEYTYPE_RSA1:
|
||
|
case SSH_KEYTYPE_RSA_CERT01:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- if (key->rsa == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_TRACE, "NULL key->rsa");
|
||
|
- goto error;
|
||
|
- }
|
||
|
- pkey = EVP_PKEY_new();
|
||
|
- if (pkey == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_TRACE, "Out of memory");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- EVP_PKEY_set1_RSA(pkey, key->rsa);
|
||
|
- break;
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Remove this #else part from here
|
||
|
- */
|
||
|
-#else
|
||
|
- if (key->key == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_TRACE, "NULL key->key");
|
||
|
- goto error;
|
||
|
- }
|
||
|
- rc = EVP_PKEY_up_ref(key->key);
|
||
|
- if (rc != 1) {
|
||
|
- SSH_LOG(SSH_LOG_TRACE, "Failed to reference EVP_PKEY");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
- pkey = key->key;
|
||
|
- break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
case SSH_KEYTYPE_ECDSA_P256:
|
||
|
case SSH_KEYTYPE_ECDSA_P384:
|
||
|
case SSH_KEYTYPE_ECDSA_P521:
|
||
|
@@ -2913,43 +2841,17 @@ static EVP_PKEY *pki_key_to_pkey(ssh_key key)
|
||
|
case SSH_KEYTYPE_ECDSA_P521_CERT01:
|
||
|
case SSH_KEYTYPE_SK_ECDSA:
|
||
|
case SSH_KEYTYPE_SK_ECDSA_CERT01:
|
||
|
-# if defined(HAVE_OPENSSL_ECC)
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- if (key->ecdsa == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_TRACE, "NULL key->ecdsa");
|
||
|
- goto error;
|
||
|
- }
|
||
|
- pkey = EVP_PKEY_new();
|
||
|
- if (pkey == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_TRACE, "Out of memory");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
|
||
|
- break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
-# endif
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||
|
- */
|
||
|
-#if 0
|
||
|
if (key->key == NULL) {
|
||
|
SSH_LOG(SSH_LOG_TRACE, "NULL key->key");
|
||
|
goto error;
|
||
|
}
|
||
|
- rc = EVP_PKEY_uo_ref(key->key);
|
||
|
+ rc = EVP_PKEY_up_ref(key->key);
|
||
|
if (rc != 1) {
|
||
|
SSH_LOG(SSH_LOG_TRACE, "Failed to reference EVP_PKEY");
|
||
|
return NULL;
|
||
|
}
|
||
|
pkey = key->key;
|
||
|
break;
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
case SSH_KEYTYPE_ED25519:
|
||
|
case SSH_KEYTYPE_ED25519_CERT01:
|
||
|
case SSH_KEYTYPE_SK_ED25519:
|
||
|
@@ -3437,15 +3339,19 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
|
||
|
#endif /* HAVE_OPENSSL_ED25519 */
|
||
|
|
||
|
#ifdef WITH_PKCS11_URI
|
||
|
+#ifdef WITH_PKCS11_PROVIDER
|
||
|
+static bool pkcs11_provider_failed = false;
|
||
|
+#endif
|
||
|
+
|
||
|
/**
|
||
|
* @internal
|
||
|
*
|
||
|
- * @brief Populate the public/private ssh_key from the engine with
|
||
|
+ * @brief Populate the public/private ssh_key from the engine/provider with
|
||
|
* PKCS#11 URIs as the look up.
|
||
|
*
|
||
|
* @param[in] uri_name The PKCS#11 URI
|
||
|
* @param[in] nkey The ssh-key context for
|
||
|
- * the key loaded from the engine.
|
||
|
+ * the key loaded from the engine/provider.
|
||
|
* @param[in] key_type The type of the key used. Public/Private.
|
||
|
*
|
||
|
* @return SSH_OK if ssh-key is valid; SSH_ERROR otherwise.
|
||
|
@@ -3454,22 +3360,14 @@ int pki_uri_import(const char *uri_name,
|
||
|
ssh_key *nkey,
|
||
|
enum ssh_key_e key_type)
|
||
|
{
|
||
|
- ENGINE *engine = NULL;
|
||
|
EVP_PKEY *pkey = NULL;
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- RSA *rsa = NULL;
|
||
|
-#endif
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Move HAVE_OPENSSL_ECC #ifdef into #if above
|
||
|
- */
|
||
|
-#ifdef HAVE_OPENSSL_ECC
|
||
|
- EC_KEY *ecdsa = NULL;
|
||
|
-#else
|
||
|
- void *ecdsa = NULL;
|
||
|
-#endif
|
||
|
ssh_key key = NULL;
|
||
|
enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN;
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L && HAVE_OPENSSL_ECC
|
||
|
+ EC_KEY *ecdsa = NULL;
|
||
|
+#endif
|
||
|
+#ifndef WITH_PKCS11_PROVIDER
|
||
|
+ ENGINE *engine = NULL;
|
||
|
|
||
|
/* Do the init only once */
|
||
|
engine = pki_get_engine();
|
||
|
@@ -3484,7 +3382,7 @@ int pki_uri_import(const char *uri_name,
|
||
|
if (pkey == NULL) {
|
||
|
SSH_LOG(SSH_LOG_WARN,
|
||
|
"Could not load key: %s",
|
||
|
- ERR_error_string(ERR_get_error(),NULL));
|
||
|
+ ERR_error_string(ERR_get_error(), NULL));
|
||
|
goto fail;
|
||
|
}
|
||
|
break;
|
||
|
@@ -3493,7 +3391,7 @@ int pki_uri_import(const char *uri_name,
|
||
|
if (pkey == NULL) {
|
||
|
SSH_LOG(SSH_LOG_WARN,
|
||
|
"Could not load key: %s",
|
||
|
- ERR_error_string(ERR_get_error(),NULL));
|
||
|
+ ERR_error_string(ERR_get_error(), NULL));
|
||
|
goto fail;
|
||
|
}
|
||
|
break;
|
||
|
@@ -3502,6 +3400,72 @@ int pki_uri_import(const char *uri_name,
|
||
|
"Invalid key type: %d", key_type);
|
||
|
goto fail;
|
||
|
}
|
||
|
+#else /* WITH_PKCS11_PROVIDER */
|
||
|
+ OSSL_STORE_CTX *store = NULL;
|
||
|
+ OSSL_STORE_INFO *info = NULL;
|
||
|
+ int rv, expect_type = OSSL_STORE_INFO_PKEY;
|
||
|
+
|
||
|
+ /* The provider can be either configured in openssl.cnf or dynamically
|
||
|
+ * loaded, assuming it does not need any special configuration */
|
||
|
+ if (OSSL_PROVIDER_available(NULL, "pkcs11") == 0 &&
|
||
|
+ !pkcs11_provider_failed) {
|
||
|
+ OSSL_PROVIDER *pkcs11_provider = NULL;
|
||
|
+
|
||
|
+ pkcs11_provider = OSSL_PROVIDER_try_load(NULL, "pkcs11", 1);
|
||
|
+ if (pkcs11_provider == NULL) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE,
|
||
|
+ "Failed to initialize provider: %s",
|
||
|
+ ERR_error_string(ERR_get_error(), NULL));
|
||
|
+ /* Do not attempt to load it again */
|
||
|
+ pkcs11_provider_failed = true;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ store = OSSL_STORE_open(uri_name, NULL, NULL, NULL, NULL);
|
||
|
+ if (store == NULL) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE,
|
||
|
+ "Failed to open OpenSSL store: %s",
|
||
|
+ ERR_error_string(ERR_get_error(), NULL));
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+ if (key_type == SSH_KEY_PUBLIC) {
|
||
|
+ expect_type = OSSL_STORE_INFO_PUBKEY;
|
||
|
+ }
|
||
|
+ rv = OSSL_STORE_expect(store, expect_type);
|
||
|
+ if (rv != 1) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE,
|
||
|
+ "Failed to set the store preference. Ignoring the error: %s",
|
||
|
+ ERR_error_string(ERR_get_error(), NULL));
|
||
|
+ }
|
||
|
+
|
||
|
+ for (info = OSSL_STORE_load(store);
|
||
|
+ info != NULL;
|
||
|
+ info = OSSL_STORE_load(store)) {
|
||
|
+ int ossl_type = OSSL_STORE_INFO_get_type(info);
|
||
|
+
|
||
|
+ if (ossl_type == OSSL_STORE_INFO_PUBKEY && key_type == SSH_KEY_PUBLIC) {
|
||
|
+ pkey = OSSL_STORE_INFO_get1_PUBKEY(info);
|
||
|
+ break;
|
||
|
+ } else if (ossl_type == OSSL_STORE_INFO_PKEY &&
|
||
|
+ key_type == SSH_KEY_PRIVATE) {
|
||
|
+ pkey = OSSL_STORE_INFO_get1_PKEY(info);
|
||
|
+ break;
|
||
|
+ } else {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE,
|
||
|
+ "Ignoring object not matching our type: %d",
|
||
|
+ ossl_type);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ OSSL_STORE_close(store);
|
||
|
+ if (pkey == NULL) {
|
||
|
+ SSH_LOG(SSH_LOG_TRACE,
|
||
|
+ "No key found in the pkcs11 store: %s",
|
||
|
+ ERR_error_string(ERR_get_error(), NULL));
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
+
|
||
|
+#endif /* WITH_PKCS11_PROVIDER */
|
||
|
|
||
|
key = ssh_key_new();
|
||
|
if (key == NULL) {
|
||
|
@@ -3510,25 +3474,12 @@ int pki_uri_import(const char *uri_name,
|
||
|
|
||
|
switch (EVP_PKEY_base_id(pkey)) {
|
||
|
case EVP_PKEY_RSA:
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- rsa = EVP_PKEY_get1_RSA(pkey);
|
||
|
- if (rsa == NULL) {
|
||
|
- SSH_LOG(SSH_LOG_WARN,
|
||
|
- "Parsing pub key: %s",
|
||
|
- ERR_error_string(ERR_get_error(),NULL));
|
||
|
- goto fail;
|
||
|
- }
|
||
|
-#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
type = SSH_KEYTYPE_RSA;
|
||
|
break;
|
||
|
case EVP_PKEY_EC:
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- ecdsa = EVP_PKEY_get1_EC_KEY(pkey);
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ ecdsa = EVP_PKEY_get0_EC_KEY(pkey);
|
||
|
if (ecdsa == NULL) {
|
||
|
SSH_LOG(SSH_LOG_WARN,
|
||
|
"Parsing pub key: %s",
|
||
|
@@ -3562,22 +3513,10 @@ int pki_uri_import(const char *uri_name,
|
||
|
if (key_type == SSH_KEY_PRIVATE) {
|
||
|
key->flags |= SSH_KEY_FLAG_PRIVATE;
|
||
|
}
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- key->rsa = rsa;
|
||
|
-#endif
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Move line key->ecdsa into #if above
|
||
|
- */
|
||
|
- key->ecdsa = ecdsa;
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
if (is_ecdsa_key_type(key->type)) {
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
- key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
+ key->ecdsa_nid = pki_key_ecdsa_to_nid(ecdsa);
|
||
|
#else
|
||
|
key->ecdsa_nid = pki_key_ecdsa_to_nid(key->key);
|
||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||
|
@@ -3591,16 +3530,6 @@ int pki_uri_import(const char *uri_name,
|
||
|
fail:
|
||
|
EVP_PKEY_free(pkey);
|
||
|
ssh_key_free(key);
|
||
|
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- RSA_free(rsa);
|
||
|
-#endif
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * Move HAVE_OPENSSL_ECC #ifdef into #if above
|
||
|
- */
|
||
|
-#ifdef HAVE_OPENSSL_ECC
|
||
|
- EC_KEY_free(ecdsa);
|
||
|
-#endif
|
||
|
|
||
|
return SSH_ERROR;
|
||
|
}
|
||
|
diff --git a/src/wrapper.c b/src/wrapper.c
|
||
|
index d317dc4c..bf949ea9 100644
|
||
|
--- a/src/wrapper.c
|
||
|
+++ b/src/wrapper.c
|
||
|
@@ -177,13 +177,9 @@ void crypto_free(struct ssh_crypto_struct *crypto)
|
||
|
#ifdef HAVE_ECDH
|
||
|
SAFE_FREE(crypto->ecdh_client_pubkey);
|
||
|
SAFE_FREE(crypto->ecdh_server_pubkey);
|
||
|
- if(crypto->ecdh_privkey != NULL){
|
||
|
+ if (crypto->ecdh_privkey != NULL) {
|
||
|
#ifdef HAVE_OPENSSL_ECC
|
||
|
-/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||
|
- * https://github.com/openssl/openssl/pull/16624
|
||
|
- * #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
- */
|
||
|
-#if 1
|
||
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||
|
EC_KEY_free(crypto->ecdh_privkey);
|
||
|
#else
|
||
|
EVP_PKEY_free(crypto->ecdh_privkey);
|
||
|
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
|
||
|
index f5c30061..93d1250f 100644
|
||
|
--- a/tests/CMakeLists.txt
|
||
|
+++ b/tests/CMakeLists.txt
|
||
|
@@ -183,6 +183,16 @@ if (CLIENT_TESTING OR SERVER_TESTING)
|
||
|
if (NOT SOFTHSM_FOUND)
|
||
|
message(SEND_ERROR "Could not find softhsm module!")
|
||
|
endif (NOT SOFTHSM_FOUND)
|
||
|
+ if (WITH_PKCS11_PROVIDER)
|
||
|
+ find_package(PkgConfig)
|
||
|
+ if (PKG_CONFIG_FOUND)
|
||
|
+ pkg_check_modules(P11_KIT p11-kit-1)
|
||
|
+ if (P11_KIT_FOUND)
|
||
|
+ pkg_get_variable(P11_MODULE_PATH p11-kit-1 p11_module_path)
|
||
|
+ set(P11_KIT_CLIENT ${P11_MODULE_PATH}/p11-kit-client.so)
|
||
|
+ endif (P11_KIT_FOUND)
|
||
|
+ endif (PKG_CONFIG_FOUND)
|
||
|
+ endif (WITH_PKCS11_PROVIDER)
|
||
|
endif (WITH_PKCS11_URI)
|
||
|
|
||
|
find_program(SSH_EXECUTABLE NAMES ssh)
|
||
|
@@ -296,12 +306,14 @@ if (CLIENT_TESTING OR SERVER_TESTING)
|
||
|
file(COPY keys/certauth/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||
|
file(COPY keys/certauth/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||
|
file(COPY keys/certauth/id_rsa-cert.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||
|
+endif ()
|
||
|
|
||
|
+if (WITH_PKCS11_URI)
|
||
|
#Copy the script to setup PKCS11 tokens
|
||
|
file(COPY pkcs11/setup-softhsm-tokens.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pkcs11 FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
|
||
|
+endif (WITH_PKCS11_URI)
|
||
|
|
||
|
- message(STATUS "TORTURE_ENVIRONMENT=${TORTURE_ENVIRONMENT}")
|
||
|
-endif ()
|
||
|
+message(STATUS "TORTURE_ENVIRONMENT=${TORTURE_ENVIRONMENT}")
|
||
|
|
||
|
configure_file(tests_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/tests_config.h)
|
||
|
|
||
|
diff --git a/tests/client/torture_auth_pkcs11.c b/tests/client/torture_auth_pkcs11.c
|
||
|
index e75fea0e..2537d2d8 100644
|
||
|
--- a/tests/client/torture_auth_pkcs11.c
|
||
|
+++ b/tests/client/torture_auth_pkcs11.c
|
||
|
@@ -39,9 +39,8 @@
|
||
|
#define LIBSSH_ECDSA_256_TESTKEY "id_pkcs11_ecdsa_256"
|
||
|
#define LIBSSH_ECDSA_384_TESTKEY "id_pkcs11_ecdsa_384"
|
||
|
#define LIBSSH_ECDSA_521_TESTKEY "id_pkcs11_ecdsa_521"
|
||
|
-#define SOFTHSM_CONF "softhsm.conf"
|
||
|
|
||
|
-const char template[] = "temp_dir_XXXXXX";
|
||
|
+const char template[] = "/tmp/temp_dir_XXXXXX";
|
||
|
|
||
|
struct pki_st {
|
||
|
char *temp_dir;
|
||
|
@@ -109,7 +108,6 @@ static int setup_session(void **state)
|
||
|
struct torture_state *s = *state;
|
||
|
struct pki_st *test_state = NULL;
|
||
|
int rc;
|
||
|
- char conf_path[1024] = {0};
|
||
|
char keys_dir[1024] = {0};
|
||
|
char *temp_dir;
|
||
|
|
||
|
@@ -134,9 +132,6 @@ static int setup_session(void **state)
|
||
|
|
||
|
test_state->keys_dir = strdup(keys_dir);
|
||
|
|
||
|
- snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", test_state->temp_dir);
|
||
|
- setenv("SOFTHSM2_CONF", conf_path, 1);
|
||
|
-
|
||
|
setup_tokens(state, LIBSSH_RSA_TESTKEY, "rsa");
|
||
|
setup_tokens(state, LIBSSH_ECDSA_256_TESTKEY, "ecdsa256");
|
||
|
setup_tokens(state, LIBSSH_ECDSA_384_TESTKEY, "ecdsa384");
|
||
|
@@ -160,7 +155,7 @@ static int sshd_teardown(void **state) {
|
||
|
struct pki_st *test_state = s->private_data;
|
||
|
int rc;
|
||
|
|
||
|
- unsetenv("SOFTHSM2_CONF");
|
||
|
+ torture_cleanup_tokens(test_state->temp_dir);
|
||
|
|
||
|
rc = torture_change_dir(test_state->orig_dir);
|
||
|
assert_int_equal(rc, 0);
|
||
|
diff --git a/tests/pkcs11/setup-softhsm-tokens.sh b/tests/pkcs11/setup-softhsm-tokens.sh
|
||
|
index ae316c7a..bd8e0944 100755
|
||
|
--- a/tests/pkcs11/setup-softhsm-tokens.sh
|
||
|
+++ b/tests/pkcs11/setup-softhsm-tokens.sh
|
||
|
@@ -5,8 +5,10 @@
|
||
|
TESTDIR=$1
|
||
|
PRIVKEY=$2
|
||
|
OBJNAME=$3
|
||
|
+TOKENLABEL=$3 # yeah. The same as object label
|
||
|
LOADPUBLIC=$4
|
||
|
LIBSOFTHSM_PATH=$5
|
||
|
+P11_KIT_CLIENT=$6
|
||
|
shift 5
|
||
|
|
||
|
PUBKEY="$PRIVKEY.pub"
|
||
|
@@ -15,24 +17,27 @@ echo "TESTDIR: $TESTDIR"
|
||
|
echo "PRIVKEY: $PRIVKEY"
|
||
|
echo "PUBKEY: $PUBKEY"
|
||
|
echo "OBJNAME: $OBJNAME"
|
||
|
+echo "TOKENLABEL: $TOKENLABEL"
|
||
|
echo "LOADPUBLIC: $LOADPUBLIC"
|
||
|
|
||
|
-# Create temporary directory for tokens
|
||
|
-install -d -m 0755 "$TESTDIR/db"
|
||
|
+if [ ! -d "$TESTDIR/db" ]; then
|
||
|
+ # Create temporary directory for tokens
|
||
|
+ install -d -m 0755 "$TESTDIR/db"
|
||
|
|
||
|
-# Create SoftHSM configuration file
|
||
|
-cat >"$TESTDIR/softhsm.conf" <<EOF
|
||
|
+ # Create SoftHSM configuration file
|
||
|
+ cat >"$TESTDIR/softhsm.conf" <<EOF
|
||
|
directories.tokendir = $TESTDIR/db
|
||
|
objectstore.backend = file
|
||
|
log.level = DEBUG
|
||
|
EOF
|
||
|
|
||
|
-export SOFTHSM2_CONF=$TESTDIR/softhsm.conf
|
||
|
+ cat "$TESTDIR/softhsm.conf"
|
||
|
+fi
|
||
|
|
||
|
-cat "$TESTDIR/softhsm.conf"
|
||
|
+export SOFTHSM2_CONF=$TESTDIR/softhsm.conf
|
||
|
|
||
|
-#init
|
||
|
-cmd="softhsm2-util --init-token --label $OBJNAME --free --pin 1234 --so-pin 1234"
|
||
|
+#init -- each object will have its own token
|
||
|
+cmd="softhsm2-util --init-token --label $TOKENLABEL --free --pin 1234 --so-pin 1234"
|
||
|
eval echo "$cmd"
|
||
|
out=$(eval "$cmd")
|
||
|
ret=$?
|
||
|
@@ -43,7 +48,7 @@ if [ $ret -ne 0 ]; then
|
||
|
fi
|
||
|
|
||
|
#load private key
|
||
|
-cmd="p11tool --provider $LIBSOFTHSM_PATH --write --load-privkey $PRIVKEY --label $OBJNAME --login --set-pin=1234 \"pkcs11:token=$OBJNAME\""
|
||
|
+cmd="p11tool --provider $LIBSOFTHSM_PATH --write --load-privkey $PRIVKEY --label $OBJNAME --login --set-pin=1234 \"pkcs11:token=$TOKENLABEL\""
|
||
|
eval echo "$cmd"
|
||
|
out=$(eval "$cmd")
|
||
|
ret=$?
|
||
|
@@ -59,7 +64,7 @@ ls -l "$TESTDIR"
|
||
|
|
||
|
if [ "$LOADPUBLIC" -ne 0 ]; then
|
||
|
#load public key
|
||
|
- cmd="p11tool --provider $LIBSOFTHSM_PATH --write --load-pubkey $PUBKEY --label $OBJNAME --login --set-pin=1234 \"pkcs11:token=$OBJNAME\""
|
||
|
+ cmd="p11tool --provider $LIBSOFTHSM_PATH --write --load-pubkey $PUBKEY --label $OBJNAME --login --set-pin=1234 \"pkcs11:token=$TOKENLABEL\""
|
||
|
eval echo "$cmd"
|
||
|
out=$(eval "$cmd")
|
||
|
ret=$?
|
||
|
@@ -70,7 +75,7 @@ if [ "$LOADPUBLIC" -ne 0 ]; then
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
-cmd="p11tool --list-all --login \"pkcs11:token=$OBJNAME\" --set-pin=1234"
|
||
|
+cmd="p11tool --list-all --login \"pkcs11:token=$TOKENLABEL\" --set-pin=1234"
|
||
|
eval echo "$cmd"
|
||
|
out=$(eval "$cmd")
|
||
|
ret=$?
|
||
|
@@ -81,4 +86,55 @@ if [ $ret -ne 0 ]; then
|
||
|
fi
|
||
|
echo "$out"
|
||
|
|
||
|
+# Skip the p11-kit if not needed
|
||
|
+if [ -z "$P11_KIT_CLIENT" ]; then
|
||
|
+ exit 0
|
||
|
+fi
|
||
|
+
|
||
|
+# when creating more keys, we need to restart the p11-kit
|
||
|
+# so it can pick up the new keys
|
||
|
+if [ -h "$TESTDIR/p11-kit-server.socket" ]; then
|
||
|
+ kill -9 $(cat $TESTDIR/p11-kit-server.pid)
|
||
|
+ rm $TESTDIR/p11-kit-server.socket
|
||
|
+fi
|
||
|
+
|
||
|
+# p11-kit complains if there is no runtime directory
|
||
|
+if [ -z "$XDG_RUNTIME_DIR" ]; then
|
||
|
+ export XDG_RUNTIME_DIR=$PWD
|
||
|
+fi
|
||
|
+
|
||
|
+# Start the p11-kit server
|
||
|
+cmd="p11-kit server --provider $LIBSOFTHSM_PATH pkcs11:"
|
||
|
+echo "$cmd"
|
||
|
+out=$(eval "$cmd")
|
||
|
+ret=$?
|
||
|
+if [ $ret -ne 0 ]; then
|
||
|
+ echo "Starting p11-kit server failed"
|
||
|
+ echo "$out"
|
||
|
+ exit 1
|
||
|
+fi
|
||
|
+eval $out
|
||
|
+
|
||
|
+# Symlink the p11-kit-server socket to "known place"
|
||
|
+P11_KIT_SERVER_ADDRESS_PATH=${P11_KIT_SERVER_ADDRESS:10}
|
||
|
+cmd="ln -s $P11_KIT_SERVER_ADDRESS_PATH $TESTDIR/p11-kit-server.socket"
|
||
|
+echo "$cmd"
|
||
|
+out=$(eval "$cmd")
|
||
|
+
|
||
|
+# Save the PID for the C code to clean up
|
||
|
+cmd="echo $P11_KIT_SERVER_PID > $TESTDIR/p11-kit-server.pid"
|
||
|
+echo "$cmd"
|
||
|
+out=$(eval "$cmd")
|
||
|
+
|
||
|
+cmd="pkcs11-tool -O --login --pin=1234 --module=$P11_KIT_CLIENT --token-label=$TOKENLABEL"
|
||
|
+echo "$cmd"
|
||
|
+out=$(eval "$cmd")
|
||
|
+ret=$?
|
||
|
+echo "$out"
|
||
|
+if [ $ret -ne 0 ]; then
|
||
|
+ echo "Failed to list keys through p11-kit remoting"
|
||
|
+ echo "$out"
|
||
|
+ exit 1
|
||
|
+fi
|
||
|
+
|
||
|
exit 0
|
||
|
diff --git a/tests/tests_config.h.cmake b/tests/tests_config.h.cmake
|
||
|
index a8147c44..92a08781 100644
|
||
|
--- a/tests/tests_config.h.cmake
|
||
|
+++ b/tests/tests_config.h.cmake
|
||
|
@@ -70,3 +70,4 @@
|
||
|
#cmakedefine WITH_TIMEOUT ${WITH_TIMEOUT}
|
||
|
#cmakedefine TIMEOUT_EXECUTABLE "${TIMEOUT_EXECUTABLE}"
|
||
|
#cmakedefine SOFTHSM2_LIBRARY "${SOFTHSM2_LIBRARY}"
|
||
|
+#cmakedefine P11_KIT_CLIENT "${P11_KIT_CLIENT}"
|
||
|
diff --git a/tests/torture.c b/tests/torture.c
|
||
|
index 6b2d5b7b..35f7d80b 100644
|
||
|
--- a/tests/torture.c
|
||
|
+++ b/tests/torture.c
|
||
|
@@ -1238,19 +1238,60 @@ void torture_setup_tokens(const char *temp_dir,
|
||
|
const char *load_public)
|
||
|
{
|
||
|
char token_setup_start_cmd[1024] = {0};
|
||
|
+ char socket_path[1204] = {0};
|
||
|
+ char conf_path[1024] = {0};
|
||
|
int rc;
|
||
|
|
||
|
- snprintf(token_setup_start_cmd, sizeof(token_setup_start_cmd),
|
||
|
- "%s/tests/pkcs11/setup-softhsm-tokens.sh %s %s %s %s %s",
|
||
|
- BINARYDIR,
|
||
|
- temp_dir,
|
||
|
- filename,
|
||
|
- object_name,
|
||
|
- load_public,
|
||
|
- SOFTHSM2_LIBRARY);
|
||
|
+ rc = snprintf(token_setup_start_cmd,
|
||
|
+ sizeof(token_setup_start_cmd),
|
||
|
+ "%s/tests/pkcs11/setup-softhsm-tokens.sh %s %s %s %s %s %s",
|
||
|
+ BINARYDIR,
|
||
|
+ temp_dir,
|
||
|
+ filename,
|
||
|
+ object_name,
|
||
|
+ load_public,
|
||
|
+ SOFTHSM2_LIBRARY,
|
||
|
+#ifdef WITH_PKCS11_PROVIDER
|
||
|
+ P11_KIT_CLIENT
|
||
|
+#else
|
||
|
+ ""
|
||
|
+#endif
|
||
|
+ );
|
||
|
+ assert_int_not_equal(rc, sizeof(token_setup_start_cmd));
|
||
|
|
||
|
rc = system(token_setup_start_cmd);
|
||
|
assert_return_code(rc, errno);
|
||
|
+
|
||
|
+#ifdef WITH_PKCS11_PROVIDER
|
||
|
+ rc = snprintf(socket_path,
|
||
|
+ sizeof(socket_path),
|
||
|
+ "unix:path=%s/p11-kit-server.socket",
|
||
|
+ temp_dir);
|
||
|
+ assert_int_not_equal(rc, sizeof(socket_path));
|
||
|
+ setenv("P11_KIT_SERVER_ADDRESS", socket_path, 1);
|
||
|
+
|
||
|
+ setenv("PKCS11_PROVIDER_MODULE", P11_KIT_CLIENT, 1);
|
||
|
+ /* This is useful for debugging PKCS#11 calls */
|
||
|
+ // setenv("PKCS11SPY", P11_KIT_CLIENT, 1);
|
||
|
+ // setenv("PKCS11_PROVIDER_MODULE", "/usr/lib64/pkcs11-spy.so", 1);
|
||
|
+#else
|
||
|
+ snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", temp_dir);
|
||
|
+ setenv("SOFTHSM2_CONF", conf_path, 1);
|
||
|
+#endif /* WITH_PKCS11_PROVIDER */
|
||
|
+}
|
||
|
+
|
||
|
+void torture_cleanup_tokens(const char *temp_dir)
|
||
|
+{
|
||
|
+ char pidfile[1024] = {0};
|
||
|
+ int rc;
|
||
|
+ pid_t pid;
|
||
|
+
|
||
|
+#ifdef WITH_PKCS11_PROVIDER
|
||
|
+ snprintf(pidfile, sizeof(pidfile), "%s/p11-kit-server.pid", temp_dir);
|
||
|
+ torture_terminate_process(pidfile);
|
||
|
+#else
|
||
|
+ unsetenv("SOFTHSM2_CONF");
|
||
|
+#endif /* WITH_PKCS11_PROVIDER */
|
||
|
}
|
||
|
#endif /* WITH_PKCS11_URI */
|
||
|
|
||
|
diff --git a/tests/torture.h b/tests/torture.h
|
||
|
index 498acf60..36f28f38 100644
|
||
|
--- a/tests/torture.h
|
||
|
+++ b/tests/torture.h
|
||
|
@@ -135,6 +135,7 @@ void torture_setup_tokens(const char *temp_dir,
|
||
|
const char *filename,
|
||
|
const char object_name[],
|
||
|
const char *load_public);
|
||
|
+void torture_cleanup_tokens(const char *temp_dir);
|
||
|
#endif /* WITH_PKCS11_URI */
|
||
|
|
||
|
void torture_reset_config(ssh_session session);
|
||
|
diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt
|
||
|
index f85da72b..58c5b6d7 100644
|
||
|
--- a/tests/unittests/CMakeLists.txt
|
||
|
+++ b/tests/unittests/CMakeLists.txt
|
||
|
@@ -76,6 +76,7 @@ if (UNIX AND NOT WIN32)
|
||
|
torture_pki_rsa_uri
|
||
|
torture_pki_ecdsa_uri
|
||
|
)
|
||
|
+ list(APPEND TORTURE_UNIT_ENVIRONMENT PKCS11_PROVIDER_DEBUG=file:/tmp/p11prov-debug.log)
|
||
|
endif()
|
||
|
|
||
|
if (HAVE_ECC)
|
||
|
diff --git a/tests/unittests/torture_pki_ecdsa_uri.c b/tests/unittests/torture_pki_ecdsa_uri.c
|
||
|
index 038780db..a2bdae8f 100644
|
||
|
--- a/tests/unittests/torture_pki_ecdsa_uri.c
|
||
|
+++ b/tests/unittests/torture_pki_ecdsa_uri.c
|
||
|
@@ -31,7 +31,7 @@
|
||
|
#define PUB_URI_FMT_384_INVALID_TOKEN "pkcs11:token=ecdsa521;object=ecdsa384;type=public"
|
||
|
#define PUB_URI_FMT_521_INVALID_OBJECT "pkcs11:token=ecdsa521;object=ecdsa384;type=public"
|
||
|
|
||
|
-const char template[] = "temp_dir_XXXXXX";
|
||
|
+const char template[] = "/tmp/temp_dir_XXXXXX";
|
||
|
const unsigned char INPUT[] = "1234567890123456789012345678901234567890"
|
||
|
"123456789012345678901234";
|
||
|
struct pki_st {
|
||
|
@@ -80,7 +80,6 @@ static int setup_directory_structure(void **state)
|
||
|
struct pki_st *test_state = NULL;
|
||
|
char *temp_dir;
|
||
|
int rc;
|
||
|
- char conf_path[1024] = {0};
|
||
|
|
||
|
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
|
||
|
assert_non_null(test_state);
|
||
|
@@ -100,9 +99,6 @@ static int setup_directory_structure(void **state)
|
||
|
|
||
|
*state = test_state;
|
||
|
|
||
|
- snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", test_state->temp_dir);
|
||
|
- setenv("SOFTHSM2_CONF", conf_path, 1);
|
||
|
-
|
||
|
setup_tokens_ecdsa(state, 256, "ecdsa256", "1");
|
||
|
setup_tokens_ecdsa(state, 384, "ecdsa384", "1");
|
||
|
setup_tokens_ecdsa(state, 521, "ecdsa521", "1");
|
||
|
@@ -118,7 +114,7 @@ static int teardown_directory_structure(void **state)
|
||
|
struct pki_st *test_state = *state;
|
||
|
int rc;
|
||
|
|
||
|
- unsetenv("SOFTHSM2_CONF");
|
||
|
+ torture_cleanup_tokens(test_state->temp_dir);
|
||
|
|
||
|
rc = torture_change_dir(test_state->orig_dir);
|
||
|
assert_int_equal(rc, 0);
|
||
|
diff --git a/tests/unittests/torture_pki_rsa_uri.c b/tests/unittests/torture_pki_rsa_uri.c
|
||
|
index 1d15db6d..d0325def 100644
|
||
|
--- a/tests/unittests/torture_pki_rsa_uri.c
|
||
|
+++ b/tests/unittests/torture_pki_rsa_uri.c
|
||
|
@@ -13,11 +13,10 @@
|
||
|
|
||
|
#define LIBSSH_RSA_TESTKEY "libssh_testkey.id_rsa"
|
||
|
#define LIBSSH_RSA_TESTKEY_PASSPHRASE "libssh_testkey_passphrase.id_rsa"
|
||
|
-#define SOFTHSM_CONF "softhsm.conf"
|
||
|
#define PUB_URI_FMT "pkcs11:token=%s;object=%s;type=public"
|
||
|
#define PRIV_URI_FMT "pkcs11:token=%s;object=%s;type=private?pin-value=%s"
|
||
|
|
||
|
-const char template[] = "temp_dir_XXXXXX";
|
||
|
+const char template[] = "/tmp/temp_dir_XXXXXX";
|
||
|
const unsigned char INPUT[] = "1234567890123456789012345678901234567890"
|
||
|
"123456789012345678901234";
|
||
|
struct pki_st {
|
||
|
@@ -33,7 +32,6 @@ struct pki_st {
|
||
|
|
||
|
static int setup_tokens(void **state)
|
||
|
{
|
||
|
- char conf_path[1024] = {0};
|
||
|
char keys_path[1024] = {0};
|
||
|
char keys_path_pub[1024] = {0};
|
||
|
char *cwd = NULL;
|
||
|
@@ -85,10 +83,6 @@ static int setup_tokens(void **state)
|
||
|
|
||
|
torture_setup_tokens(cwd, keys_path, obj_tempname, "1");
|
||
|
|
||
|
- snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", cwd);
|
||
|
-
|
||
|
- setenv("SOFTHSM2_CONF", conf_path, 1);
|
||
|
-
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -126,6 +120,8 @@ static int teardown_directory_structure(void **state)
|
||
|
struct pki_st *test_state = *state;
|
||
|
int rc;
|
||
|
|
||
|
+ torture_cleanup_tokens(test_state->temp_dir);
|
||
|
+
|
||
|
rc = torture_change_dir(test_state->orig_dir);
|
||
|
assert_int_equal(rc, 0);
|
||
|
|
||
|
@@ -142,8 +138,6 @@ static int teardown_directory_structure(void **state)
|
||
|
SAFE_FREE(test_state->pub_uri_invalid_token);
|
||
|
SAFE_FREE(test_state);
|
||
|
|
||
|
- unsetenv("SOFTHSM2_CONF");
|
||
|
-
|
||
|
return 0;
|
||
|
}
|
||
|
|