aboutsummaryrefslogtreecommitdiff
path: root/src/pki_crypto.c
diff options
context:
space:
mode:
authorJakub Jelen <jjelen@redhat.com>2019-05-23 11:34:41 +0200
committerAndreas Schneider <asn@cryptomilk.org>2019-06-12 10:41:24 +0200
commit167aa8bc6cdf2a3e12b18a567b98deee23559932 (patch)
treeb5f2a70f4a3fbf31d9ba81b855e18780f953dff5 /src/pki_crypto.c
parent0ce1e84d9046d680ae65cd650a9d4557f203baef (diff)
downloadlibssh-167aa8bc6cdf2a3e12b18a567b98deee23559932.tar.gz
libssh-167aa8bc6cdf2a3e12b18a567b98deee23559932.tar.xz
libssh-167aa8bc6cdf2a3e12b18a567b98deee23559932.zip
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>
Diffstat (limited to 'src/pki_crypto.c')
-rw-r--r--src/pki_crypto.c165
1 files changed, 65 insertions, 100 deletions
diff --git a/src/pki_crypto.c b/src/pki_crypto.c
index f1e5fce0..4274bf5b 100644
--- a/src/pki_crypto.c
+++ b/src/pki_crypto.c
@@ -816,127 +816,92 @@ 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);
- } else {
- /* openssl uses its own callback to get the passphrase here */
- dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, NULL);
- }
- } else {
- dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, (void *) passphrase);
- }
-
- BIO_free(mem);
-
- if (dsa == NULL) {
- SSH_LOG(SSH_LOG_WARN,
- "Parsing private key: %s",
- ERR_error_string(ERR_get_error(), NULL));
- return NULL;
- }
-
- 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);
- }
+ if (passphrase == NULL) {
+ if (auth_fn) {
+ struct pem_get_password_struct pgp = { auth_fn, auth_data };
- BIO_free(mem);
+ pkey = PEM_read_bio_PrivateKey(mem, NULL, pem_get_password, &pgp);
+ } else {
+ /* openssl uses its own callback to get the passphrase here */
+ pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL);
+ }
+ } else {
+ pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, (void *) passphrase);
+ }
- if (rsa == NULL) {
- SSH_LOG(SSH_LOG_WARN,
- "Parsing private key: %s",
- ERR_error_string(ERR_get_error(),NULL));
- return NULL;
- }
+ BIO_free(mem);
- break;
- case SSH_KEYTYPE_ECDSA_P256:
- case SSH_KEYTYPE_ECDSA_P384:
- case SSH_KEYTYPE_ECDSA_P521:
+ 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 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 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);
-
- if (ecdsa == NULL) {
- SSH_LOG(SSH_LOG_WARN,
- "Parsing private key: %s",
- ERR_error_string(ERR_get_error(), NULL));
- return NULL;
- }
+ ecdsa = EVP_PKEY_get1_EC_KEY(pkey);
+ if (ecdsa == NULL) {
+ SSH_LOG(SSH_LOG_WARN,
+ "Parsing private key: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return NULL;
+ }
- /* pki_privatekey_type_from_string always returns P256 for ECDSA
- * keys, so we need to figure out the correct type here */
- type = pki_key_ecdsa_to_key_type(ecdsa);
- if (type == SSH_KEYTYPE_UNKNOWN) {
- SSH_LOG(SSH_LOG_WARN, "Invalid private key.");
- goto fail;
- }
+ /* pki_privatekey_type_from_string always returns P256 for ECDSA
+ * keys, so we need to figure out the correct type here */
+ type = pki_key_ecdsa_to_key_type(ecdsa);
+ if (type == SSH_KEYTYPE_UNKNOWN) {
+ SSH_LOG(SSH_LOG_WARN, "Invalid private key.");
+ goto fail;
+ }
- break;
+ 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);
- return NULL;
+ 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) {