aboutsummaryrefslogtreecommitdiff
path: root/src/pki_crypto.c
diff options
context:
space:
mode:
authorJakub Jelen <jjelen@redhat.com>2019-05-23 11:30:06 +0200
committerAndreas Schneider <asn@cryptomilk.org>2019-06-12 10:41:24 +0200
commit0ce1e84d9046d680ae65cd650a9d4557f203baef (patch)
treec9184dcdc7db714f8620494e5ea8d5b719bb4d47 /src/pki_crypto.c
parentee456104f16b29d5fe0245e6e2ba026450db0fe8 (diff)
downloadlibssh-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.c119
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;
}