diff options
author | Jakub Jelen <jjelen@redhat.com> | 2019-05-23 11:30:06 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2019-06-12 10:41:24 +0200 |
commit | 0ce1e84d9046d680ae65cd650a9d4557f203baef (patch) | |
tree | c9184dcdc7db714f8620494e5ea8d5b719bb4d47 /src/pki_crypto.c | |
parent | ee456104f16b29d5fe0245e6e2ba026450db0fe8 (diff) | |
download | libssh-0ce1e84d9046d680ae65cd650a9d4557f203baef.tar.gz libssh-0ce1e84d9046d680ae65cd650a9d4557f203baef.tar.xz libssh-0ce1e84d9046d680ae65cd650a9d4557f203baef.zip |
pki_crypto: Use the new OpenSSL API to write new PKCS#8 PEM files
Since OpenSSL 1.0.0, the "traditional" PEM format was deprecated
in favor of the PKCS#8 PEM files which is more standardized,
more secure and does not depend on the MD5 hash, which is not
available for example in FIPS mode.
This requires using the new EVP_PKEY API for reading private key
blobs.
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'src/pki_crypto.c')
-rw-r--r-- | src/pki_crypto.c | 119 |
1 files changed, 46 insertions, 73 deletions
diff --git a/src/pki_crypto.c b/src/pki_crypto.c index ef0f7c16..f1e5fce0 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -719,9 +719,10 @@ ssh_string pki_private_key_to_pem(const ssh_key key, ssh_auth_callback auth_fn, void *auth_data) { - ssh_string blob; - BUF_MEM *buf; - BIO *mem; + ssh_string blob = NULL; + BUF_MEM *buf = NULL; + BIO *mem = NULL; + EVP_PKEY *pkey = NULL; int rc; mem = BIO_new(BIO_s_mem()); @@ -729,88 +730,29 @@ ssh_string pki_private_key_to_pem(const ssh_key key, return NULL; } + pkey = EVP_PKEY_new(); + if (pkey == NULL) { + goto err; + } + switch (key->type) { case SSH_KEYTYPE_DSS: - if (passphrase == NULL) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - rc = PEM_write_bio_DSAPrivateKey(mem, - key->dsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - pem_get_password, - &pgp); - } else { - rc = PEM_write_bio_DSAPrivateKey(mem, - key->dsa, - EVP_aes_128_cbc(), - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ - (void*) passphrase); - } - if (rc != 1) { - goto err; - } + rc = EVP_PKEY_set1_DSA(pkey, key->dsa); break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: - if (passphrase == NULL) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - rc = PEM_write_bio_RSAPrivateKey(mem, - key->rsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - pem_get_password, - &pgp); - } else { - rc = PEM_write_bio_RSAPrivateKey(mem, - key->rsa, - EVP_aes_128_cbc(), - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ - (void*) passphrase); - } - if (rc != 1) { - goto err; - } + rc = EVP_PKEY_set1_RSA(pkey, key->rsa); break; #ifdef HAVE_ECC case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P521: - if (passphrase == NULL) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - rc = PEM_write_bio_ECPrivateKey(mem, - key->ecdsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - pem_get_password, - &pgp); - } else { - rc = PEM_write_bio_ECPrivateKey(mem, - key->ecdsa, - EVP_aes_128_cbc(), - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ - (void*) passphrase); - } - if (rc != 1) { - goto err; - } + rc = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); break; #endif case SSH_KEYTYPE_ED25519: - BIO_free(mem); SSH_LOG(SSH_LOG_WARN, "PEM output not supported for key type ssh-ed25519"); - return NULL; + goto err; case SSH_KEYTYPE_DSS_CERT01: case SSH_KEYTYPE_RSA_CERT01: case SSH_KEYTYPE_ECDSA_P256_CERT01: @@ -819,9 +761,38 @@ ssh_string pki_private_key_to_pem(const ssh_key key, case SSH_KEYTYPE_ED25519_CERT01: case SSH_KEYTYPE_UNKNOWN: default: - BIO_free(mem); SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", key->type); - return NULL; + goto err; + } + if (rc != 1) { + SSH_LOG(SSH_LOG_WARN, "Failed to initialize EVP_PKEY structure"); + goto err; + } + + if (passphrase == NULL) { + struct pem_get_password_struct pgp = { auth_fn, auth_data }; + + rc = PEM_write_bio_PrivateKey(mem, + pkey, + NULL, /* cipher */ + NULL, /* kstr */ + 0, /* klen */ + pem_get_password, + &pgp); + } else { + rc = PEM_write_bio_PrivateKey(mem, + pkey, + EVP_aes_128_cbc(), + NULL, /* kstr */ + 0, /* klen */ + NULL, /* auth_fn */ + (void*) passphrase); + } + EVP_PKEY_free(pkey); + pkey = NULL; + + if (rc != 1) { + goto err; } BIO_get_mem_ptr(mem, &buf); @@ -835,7 +806,9 @@ ssh_string pki_private_key_to_pem(const ssh_key key, BIO_free(mem); return blob; + err: + EVP_PKEY_free(pkey); BIO_free(mem); return NULL; } |