mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-29 01:03:57 +03:00
pki_crypto: Use the new OpenSSL API to read PEM files
This allows the use of the new PKCS#8 PEM files and does not limit libssh to using only the "traditional" PEM files, that are not default in OpenSSL since 1.0.0 and which do not work at all in FIPS mode. Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
0ce1e84d90
commit
167aa8bc6c
@@ -816,96 +816,68 @@ err:
|
||||
ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data) {
|
||||
void *auth_data)
|
||||
{
|
||||
BIO *mem = NULL;
|
||||
DSA *dsa = NULL;
|
||||
RSA *rsa = NULL;
|
||||
ed25519_privkey *ed25519 = NULL;
|
||||
ssh_key key = NULL;
|
||||
enum ssh_keytypes_e type;
|
||||
enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN;
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
EC_KEY *ecdsa = NULL;
|
||||
#else
|
||||
void *ecdsa = NULL;
|
||||
#endif
|
||||
|
||||
type = pki_privatekey_type_from_string(b64_key);
|
||||
if (type == SSH_KEYTYPE_UNKNOWN) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key.");
|
||||
return NULL;
|
||||
}
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
mem = BIO_new_mem_buf((void*)b64_key, -1);
|
||||
|
||||
switch (type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
if (passphrase == NULL) {
|
||||
if (auth_fn) {
|
||||
struct pem_get_password_struct pgp = { auth_fn, auth_data };
|
||||
|
||||
dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, pem_get_password, &pgp);
|
||||
pkey = PEM_read_bio_PrivateKey(mem, NULL, pem_get_password, &pgp);
|
||||
} else {
|
||||
/* openssl uses its own callback to get the passphrase here */
|
||||
dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, NULL);
|
||||
pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, (void *) passphrase);
|
||||
pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, (void *) passphrase);
|
||||
}
|
||||
|
||||
BIO_free(mem);
|
||||
|
||||
if (pkey == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Parsing private key: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
return NULL;
|
||||
}
|
||||
switch (EVP_PKEY_base_id(pkey)) {
|
||||
case EVP_PKEY_DSA:
|
||||
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));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = SSH_KEYTYPE_DSS;
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
if (passphrase == NULL) {
|
||||
if (auth_fn) {
|
||||
struct pem_get_password_struct pgp = { auth_fn, auth_data };
|
||||
|
||||
rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, pem_get_password, &pgp);
|
||||
} else {
|
||||
/* openssl uses its own callback to get the passphrase here */
|
||||
rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, (void *) passphrase);
|
||||
}
|
||||
|
||||
BIO_free(mem);
|
||||
|
||||
case EVP_PKEY_RSA:
|
||||
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));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = SSH_KEYTYPE_RSA;
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA_P256:
|
||||
case SSH_KEYTYPE_ECDSA_P384:
|
||||
case SSH_KEYTYPE_ECDSA_P521:
|
||||
case EVP_PKEY_EC:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
if (passphrase == NULL) {
|
||||
if (auth_fn) {
|
||||
struct pem_get_password_struct pgp = { auth_fn, auth_data };
|
||||
|
||||
ecdsa = PEM_read_bio_ECPrivateKey(mem, NULL, pem_get_password, &pgp);
|
||||
} else {
|
||||
/* openssl uses its own callback to get the passphrase here */
|
||||
ecdsa = PEM_read_bio_ECPrivateKey(mem, NULL, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
ecdsa = PEM_read_bio_ECPrivateKey(mem, NULL, NULL, (void *) passphrase);
|
||||
}
|
||||
|
||||
BIO_free(mem);
|
||||
|
||||
ecdsa = EVP_PKEY_get1_EC_KEY(pkey);
|
||||
if (ecdsa == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Parsing private key: %s",
|
||||
@@ -923,20 +895,13 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
/* Cannot open ed25519 keys with libcrypto */
|
||||
case SSH_KEYTYPE_DSS_CERT01:
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
case SSH_KEYTYPE_ECDSA_P256_CERT01:
|
||||
case SSH_KEYTYPE_ECDSA_P384_CERT01:
|
||||
case SSH_KEYTYPE_ECDSA_P521_CERT01:
|
||||
case SSH_KEYTYPE_ED25519_CERT01:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
BIO_free(mem);
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type);
|
||||
default:
|
||||
EVP_PKEY_free(pkey);
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d",
|
||||
EVP_PKEY_base_id(pkey));
|
||||
return NULL;
|
||||
}
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
key = ssh_key_new();
|
||||
if (key == NULL) {
|
||||
|
||||
Reference in New Issue
Block a user