From a9dddd89aac97ff219475da56e950fb013f1208d Mon Sep 17 00:00:00 2001 From: Norbert Pocs Date: Thu, 23 Jun 2022 15:44:41 +0000 Subject: [PATCH] Use EVP_PKEY as a key type in key structs Merge multiple key variables into one variable. Signed-off-by: Norbert Pocs Reviewed-by: Jakub Jelen Reviewed-by: Andreas Schneider --- include/libssh/crypto.h | 8 ++++++ include/libssh/keys.h | 8 ++++++ include/libssh/pki.h | 8 +++++- src/auth.c | 8 ++++++ src/legacy.c | 53 ++++++++++++++++++++++++++++++++-- src/pki.c | 63 +++++++++++++++++++++++++++++------------ src/wrapper.c | 8 ++++++ 7 files changed, 134 insertions(+), 22 deletions(-) diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h index 2af55c9a..cc1ae56d 100644 --- a/include/libssh/crypto.h +++ b/include/libssh/crypto.h @@ -111,7 +111,15 @@ 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 EC_KEY *ecdh_privkey; +#else + EVP_PKEY *ecdh_privkey; +#endif /* OPENSSL_VERSION_NUMBER */ #elif defined HAVE_GCRYPT_ECC gcry_sexp_t ecdh_privkey; #elif defined HAVE_LIBMBEDCRYPTO diff --git a/include/libssh/keys.h b/include/libssh/keys.h index 7b138612..934189c2 100644 --- a/include/libssh/keys.h +++ b/include/libssh/keys.h @@ -32,8 +32,12 @@ 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; @@ -46,8 +50,12 @@ 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/pki.h b/include/libssh/pki.h index 722f47d9..78cd9d0b 100644 --- a/include/libssh/pki.h +++ b/include/libssh/pki.h @@ -65,14 +65,20 @@ struct ssh_key_struct { mbedtls_ecdsa_context *ecdsa; void *dsa; #elif defined(HAVE_LIBCRYPTO) +#if OPENSSL_VERSION_NUMBER < 0x30000000L DSA *dsa; RSA *rsa; - EVP_PKEY *key; /* Saving the OpenSSL context here to save time while converting*/ +#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 */ + EVP_PKEY *key; /* Saving the OpenSSL context here to save time while converting*/ #endif /* HAVE_LIBGCRYPT */ #ifdef HAVE_OPENSSL_ED25519 uint8_t *ed25519_pubkey; diff --git a/src/auth.c b/src/auth.c index 6343c6a9..aa3aa965 100644 --- a/src/auth.c +++ b/src/auth.c @@ -1406,13 +1406,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 key->dsa = publickey->dsa_pub; key->rsa = publickey->rsa_pub; +#else + key->key = publickey->key_pub; +#endif /* OPENSSL_VERSION_NUMBER */ rc = ssh_userauth_agent_publickey(session, username, key); +#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L key->dsa = NULL; key->rsa = NULL; +#else + key->key = NULL; +#endif /* OPENSSL_VERSION_NUMBER */ ssh_key_free(key); return rc; diff --git a/src/legacy.c b/src/legacy.c index 3b048a0e..7b165dbe 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -83,12 +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 key->dsa = privatekey->dsa_priv; key->rsa = privatekey->rsa_priv; +#else + key->key = privatekey->key_priv; +#endif /* OPENSSL_VERSION_NUMBER */ rc = ssh_userauth_publickey(session, username, key); +#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L key->dsa = NULL; key->rsa = NULL; +#else + key->key = NULL; +#endif /* OPENSSL_VERSION_NUMBER */ ssh_key_free(key); return rc; @@ -354,18 +362,26 @@ 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); -#endif +#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); -#endif +#endif /* HAVE_LIBGCRYPT */ break; default: break; @@ -387,12 +403,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 privkey->dsa = prv->dsa_priv; privkey->rsa = prv->rsa_priv; +#else + privkey->key = prv->key_priv; +#endif /* OPENSSL_VERSION_NUMBER */ rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); +#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L privkey->dsa = NULL; privkey->rsa = NULL; +#else + privkey->key = NULL; +#endif /* OPENSSL_VERSION_NUMBER */ ssh_key_free(privkey); if (rc < 0) { return NULL; @@ -438,11 +462,17 @@ ssh_private_key privatekey_from_file(ssh_session session, } privkey->type = key->type; +#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L privkey->dsa_priv = key->dsa; privkey->rsa_priv = key->rsa; key->dsa = NULL; key->rsa = NULL; +#else + privkey->key_priv = key->key; + + key->key = NULL; +#endif /* OPENSSL_VERSION_NUMBER */ ssh_key_free(key); @@ -464,12 +494,16 @@ 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); -#endif +#endif /* HAVE_LIBGCRYPT */ memset(prv, 0, sizeof(struct ssh_private_key_struct)); SAFE_FREE(prv); } @@ -530,10 +564,15 @@ 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 pubkey->dsa_pub = key->dsa; key->dsa = NULL; pubkey->rsa_pub = key->rsa; key->rsa = NULL; +#else + pubkey->key_pub = key->key; + key->key = NULL; +#endif /* OPENSSL_VERSION_NUMBER */ ssh_key_free(key); @@ -557,16 +596,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 key->dsa = pubkey->dsa_pub; key->rsa = pubkey->rsa_pub; +#else + key->key = pubkey->key_pub; +#endif /* OPENSSL_VERSION_NUMBER */ rc = ssh_pki_export_pubkey_blob(key, &key_blob); if (rc < 0) { key_blob = NULL; } +#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L key->dsa = NULL; key->rsa = NULL; +#else + key->key = NULL; +#endif /* OPENSSL_VERSION_NUMBER */ ssh_key_free(key); return key_blob; diff --git a/src/pki.c b/src/pki.c index 394b7045..cd186093 100644 --- a/src/pki.c +++ b/src/pki.c @@ -55,7 +55,7 @@ # undef unlink # define unlink _unlink # endif /* HAVE_IO_H */ -#endif +#endif /* _WIN32 */ #include "libssh/libssh.h" #include "libssh/session.h" @@ -69,7 +69,7 @@ #ifndef MAX_LINE_SIZE #define MAX_LINE_SIZE 4096 -#endif +#endif /* NOT MAX_LINE_SIZE */ #define PKCS11_URI "pkcs11:" @@ -117,7 +117,7 @@ const char *ssh_pki_key_ecdsa_name(const ssh_key key) return pki_key_ecdsa_nid_to_name(key->ecdsa_nid); #else return NULL; -#endif +#endif /* HAVE_ECC */ } /** @@ -157,10 +157,20 @@ void ssh_key_clean (ssh_key key) if(key->rsa) gcry_sexp_release(key->rsa); if(key->ecdsa) gcry_sexp_release(key->ecdsa); #elif defined HAVE_LIBCRYPTO +#if OPENSSL_VERSION_NUMBER < 0x30000000L if(key->dsa) DSA_free(key->dsa); if(key->rsa) RSA_free(key->rsa); +#else + if(key->key) EVP_PKEY_free(key->key); +#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_EC into #if < 0x3 above + */ +#if 1 if(key->ecdsa) EC_KEY_free(key->ecdsa); +#endif #endif /* HAVE_OPENSSL_ECC */ #elif defined HAVE_LIBMBEDCRYPTO if (key->rsa != NULL) { @@ -181,7 +191,7 @@ void ssh_key_clean (ssh_key key) explicit_bzero(key->ed25519_privkey, ED25519_KEY_LEN); #else explicit_bzero(key->ed25519_privkey, sizeof(ed25519_privkey)); -#endif +#endif /* HAVE_OPENSSL_ED25519 */ SAFE_FREE(key->ed25519_privkey); } SAFE_FREE(key->ed25519_pubkey); @@ -200,8 +210,16 @@ void ssh_key_clean (ssh_key key) key->type=SSH_KEYTYPE_UNKNOWN; key->ecdsa_nid = 0; key->type_c=NULL; +#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L key->dsa = NULL; key->rsa = NULL; +#else + key->key = NULL; +#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 #if OPENSSL_VERSION_NUMBER < 0x3 above + */ key->ecdsa = NULL; } @@ -399,7 +417,7 @@ int ssh_key_algorithm_allowed(ssh_session session, const char *type) return 0; } } -#endif +#endif /* WITH_SERVER */ else { SSH_LOG(SSH_LOG_WARN, "Session invalid: not set as client nor server"); return 0; @@ -760,14 +778,14 @@ void ssh_signature_free(ssh_signature sig) case SSH_KEYTYPE_DSS: #ifdef HAVE_LIBGCRYPT gcry_sexp_release(sig->dsa_sig); -#endif +#endif /* HAVE_LIBGCRYPT */ break; case SSH_KEYTYPE_RSA: #ifdef HAVE_LIBGCRYPT gcry_sexp_release(sig->rsa_sig); #elif defined HAVE_LIBMBEDCRYPTO SAFE_FREE(sig->rsa_sig); -#endif +#endif /* HAVE_LIBGCRYPT */ break; case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: @@ -778,14 +796,14 @@ void ssh_signature_free(ssh_signature sig) #elif defined HAVE_LIBMBEDCRYPTO bignum_safe_free(sig->ecdsa_sig.r); bignum_safe_free(sig->ecdsa_sig.s); -#endif +#endif /* HAVE_GCRYPT_ECC */ break; case SSH_KEYTYPE_ED25519: case SSH_KEYTYPE_SK_ED25519: #ifndef HAVE_OPENSSL_ED25519 /* When using OpenSSL, the signature is stored in sig->raw_sig */ SAFE_FREE(sig->ed25519_sig); -#endif +#endif /* HAVE_OPENSSL_ED25519 */ break; case SSH_KEYTYPE_DSS_CERT01: case SSH_KEYTYPE_RSA_CERT01: @@ -969,7 +987,7 @@ int ssh_pki_import_privkey_file(const char *filename, rc = pki_uri_import(filename, pkey, SSH_KEY_PRIVATE); return rc; } -#endif +#endif /* WITH_PKCS11_URI */ file = fopen(filename, "rb"); if (file == NULL) { @@ -1125,10 +1143,15 @@ 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 pub->dsa_pub = tmp->dsa; tmp->dsa = NULL; pub->rsa_pub = tmp->rsa; tmp->rsa = NULL; +#else + pub->key_pub = tmp->key; + tmp->key = NULL; +#endif /* OPENSSL_VERSION_NUMBER */ ssh_key_free(tmp); @@ -1146,8 +1169,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 privkey->dsa_priv = key->dsa; privkey->rsa_priv = key->rsa; +#else + privkey->key_priv = key->key; +#endif /* OPENSSL_VERSION_NUMBER */ return privkey; } @@ -1193,7 +1220,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, ssh_string_len(pubkey)); ssh_log_hexdump("privkey", ssh_string_data(privkey), ssh_string_len(privkey)); -#endif +#endif /* DEBUG_CRYPTO */ ssh_string_burn(p); SSH_STRING_FREE(p); ssh_string_burn(q); @@ -1234,7 +1261,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, ssh_string_len(iqmp)); ssh_log_hexdump("p", ssh_string_data(p), ssh_string_len(p)); ssh_log_hexdump("q", ssh_string_data(q), ssh_string_len(q)); -#endif +#endif /* DEBUG_CRYPTO */ ssh_string_burn(n); SSH_STRING_FREE(n); ssh_string_burn(e); @@ -1290,7 +1317,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, } } break; -#endif +#endif /* HAVE_ECC */ case SSH_KEYTYPE_ED25519: { ssh_string pubkey = NULL, privkey = NULL; @@ -1371,7 +1398,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, ssh_log_hexdump("p", ssh_string_data(p), ssh_string_len(p)); ssh_log_hexdump("q", ssh_string_data(q), ssh_string_len(q)); ssh_log_hexdump("g", ssh_string_data(g), ssh_string_len(g)); -#endif +#endif /* DEBUG_CRYPTO */ ssh_string_burn(p); SSH_STRING_FREE(p); ssh_string_burn(q); @@ -1401,7 +1428,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, #ifdef DEBUG_CRYPTO ssh_log_hexdump("e", ssh_string_data(e), ssh_string_len(e)); ssh_log_hexdump("n", ssh_string_data(n), ssh_string_len(n)); -#endif +#endif /* DEBUG_CRYPTO */ ssh_string_burn(e); SSH_STRING_FREE(e); ssh_string_burn(n); @@ -1462,7 +1489,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, } } break; -#endif +#endif /* HAVE_ECC */ case SSH_KEYTYPE_ED25519: case SSH_KEYTYPE_SK_ED25519: { @@ -1804,7 +1831,7 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) rc = pki_uri_import(filename, pkey, SSH_KEY_PUBLIC); return rc; } -#endif +#endif /* WITH_PKCS11_URI */ file = fopen(filename, "rb"); if (file == NULL) { @@ -2022,7 +2049,7 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter, goto error; } break; -#endif +#endif /* HAVE_ECC */ case SSH_KEYTYPE_ED25519: rc = pki_key_generate_ed25519(key); if (rc == SSH_ERROR) { diff --git a/src/wrapper.c b/src/wrapper.c index 52b911a2..805b8189 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -178,7 +178,15 @@ void crypto_free(struct ssh_crypto_struct *crypto) SAFE_FREE(crypto->ecdh_server_pubkey); 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 EC_KEY_free(crypto->ecdh_privkey); +#else + EVP_PKEY_free(crypto->ecdh_privkey); +#endif /* OPENSSL_VERSION_NUMBER */ #elif defined HAVE_GCRYPT_ECC gcry_sexp_release(crypto->ecdh_privkey); #endif