aboutsummaryrefslogtreecommitdiff
path: root/src/pki_crypto.c
diff options
context:
space:
mode:
authorBen Toews <mastahyeti@gmail.com>2019-03-12 10:25:49 -0600
committerAndreas Schneider <asn@cryptomilk.org>2019-04-17 10:21:42 +0200
commitb1f3cfec34c6a4acf779dac926535217d7312fba (patch)
tree30a095cf4be1dae2dc392599a2b6afaf9d0181e9 /src/pki_crypto.c
parent78f764b7c983e030f07ad162fa18a3c69aa4a973 (diff)
downloadlibssh-b1f3cfec34c6a4acf779dac926535217d7312fba.tar.gz
libssh-b1f3cfec34c6a4acf779dac926535217d7312fba.tar.xz
libssh-b1f3cfec34c6a4acf779dac926535217d7312fba.zip
libssh: deprecate SSH_KEYTYPE_ECDSA
This type is imprecise. We often need the ecdsa_nid in addition to the key type in order to do anything. We replace this singluar ECDSA type with one type per curve. Signed-off-by: Ben Toews <mastahyeti@gmail.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Diffstat (limited to 'src/pki_crypto.c')
-rw-r--r--src/pki_crypto.c116
1 files changed, 69 insertions, 47 deletions
diff --git a/src/pki_crypto.c b/src/pki_crypto.c
index c27e8184..d5dd3f63 100644
--- a/src/pki_crypto.c
+++ b/src/pki_crypto.c
@@ -92,6 +92,24 @@ static int pki_key_ecdsa_to_nid(EC_KEY *k)
return -1;
}
+static enum ssh_keytypes_e pki_key_ecdsa_to_key_type(EC_KEY *k)
+{
+ static int nid;
+
+ nid = pki_key_ecdsa_to_nid(k);
+
+ switch (nid) {
+ case NID_X9_62_prime256v1:
+ return SSH_KEYTYPE_ECDSA_P256;
+ case NID_secp384r1:
+ return SSH_KEYTYPE_ECDSA_P384;
+ case NID_secp521r1:
+ return SSH_KEYTYPE_ECDSA_P521;
+ default:
+ return SSH_KEYTYPE_UNKNOWN;
+ }
+}
+
const char *pki_key_ecdsa_nid_to_name(int nid)
{
switch (nid) {
@@ -451,7 +469,9 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
break;
}
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
new->ecdsa_nid = key->ecdsa_nid;
@@ -551,26 +571,24 @@ int pki_key_generate_dss(ssh_key key, int parameter){
#ifdef HAVE_OPENSSL_ECC
int pki_key_generate_ecdsa(ssh_key key, int parameter) {
- int nid;
int ok;
switch (parameter) {
case 384:
- nid = NID_secp384r1;
+ key->ecdsa_nid = NID_secp384r1;
+ key->type = SSH_KEYTYPE_ECDSA_P384;
break;
case 521:
- nid = NID_secp521r1;
+ key->ecdsa_nid = NID_secp521r1;
+ key->type = SSH_KEYTYPE_ECDSA_P521;
break;
case 256:
default:
- nid = NID_X9_62_prime256v1;
+ key->ecdsa_nid = NID_X9_62_prime256v1;
+ key->type = SSH_KEYTYPE_ECDSA_P256;
}
- key->ecdsa_nid = nid;
- key->type = SSH_KEYTYPE_ECDSA;
- key->type_c = pki_key_ecdsa_nid_to_name(nid);
-
- key->ecdsa = EC_KEY_new_by_curve_name(nid);
+ key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
if (key->ecdsa == NULL) {
return SSH_ERROR;
}
@@ -650,7 +668,9 @@ int pki_key_compare(const ssh_key k1,
}
break;
}
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
{
const EC_POINT *p1 = EC_KEY_get0_public_key(k1->ecdsa);
@@ -756,7 +776,9 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
}
break;
#ifdef HAVE_ECC
- case SSH_KEYTYPE_ECDSA:
+ 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 };
@@ -818,7 +840,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
DSA *dsa = NULL;
RSA *rsa = NULL;
ed25519_privkey *ed25519 = NULL;
- ssh_key key;
+ ssh_key key = NULL;
enum ssh_keytypes_e type;
#ifdef HAVE_OPENSSL_ECC
EC_KEY *ecdsa = NULL;
@@ -884,7 +906,9 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
}
break;
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
if (passphrase == NULL) {
if (auth_fn) {
@@ -908,12 +932,21 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
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;
+ }
+
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_UNKNOWN:
BIO_free(mem);
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type);
@@ -933,9 +966,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
key->ecdsa = ecdsa;
key->ed25519_privkey = ed25519;
#ifdef HAVE_OPENSSL_ECC
- if (key->type == SSH_KEYTYPE_ECDSA) {
+ if (is_ecdsa_key_type(key->type)) {
key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
- key->type_c = pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
}
#endif
@@ -1237,27 +1269,10 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
break;
}
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
- rc = ssh_buffer_reinit(buffer);
- if (rc < 0) {
- ssh_buffer_free(buffer);
- return NULL;
- }
-
- type_s = ssh_string_from_char(pki_key_ecdsa_nid_to_name(key->ecdsa_nid));
- if (type_s == NULL) {
- ssh_buffer_free(buffer);
- return NULL;
- }
-
- rc = ssh_buffer_add_ssh_string(buffer, type_s);
- ssh_string_free(type_s);
- if (rc < 0) {
- ssh_buffer_free(buffer);
- return NULL;
- }
-
type_s = ssh_string_from_char(pki_key_ecdsa_nid_to_char(key->ecdsa_nid));
if (type_s == NULL) {
ssh_buffer_free(buffer);
@@ -1461,7 +1476,9 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
case SSH_KEYTYPE_RSA1:
sig_blob = ssh_string_copy(sig->rsa_sig);
break;
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
{
ssh_string r;
@@ -1614,8 +1631,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
}
sig->type = type;
+ sig->type_c = ssh_key_signature_to_char(type, hash_type);
sig->hash_type = hash_type;
- sig->type_c = pubkey->type_c; /* for all types but RSA */
len = ssh_string_len(sig_blob);
@@ -1688,9 +1705,10 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
if (sig == NULL) {
return NULL;
}
- sig->type_c = ssh_key_signature_to_char(type, hash_type);
break;
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
sig->ecdsa_sig = ECDSA_SIG_new();
if (sig->ecdsa_sig == NULL) {
@@ -1874,7 +1892,9 @@ int pki_signature_verify(ssh_session session,
return SSH_ERROR;
}
break;
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
rc = ECDSA_do_verify(hash,
hlen,
@@ -1919,8 +1939,8 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
}
sig->type = privkey->type;
+ sig->type_c = ssh_key_signature_to_char(privkey->type, hash_type);
sig->hash_type = hash_type;
- sig->type_c = privkey->type_c;
switch(privkey->type) {
case SSH_KEYTYPE_DSS:
@@ -1942,7 +1962,6 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
break;
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
- sig->type_c = ssh_key_signature_to_char(privkey->type, hash_type);
sig->rsa_sig = _RSA_do_sign_hash(hash, hlen, privkey->rsa, hash_type);
if (sig->rsa_sig == NULL) {
ssh_signature_free(sig);
@@ -1950,7 +1969,9 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
}
sig->dsa_sig = NULL;
break;
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
sig->ecdsa_sig = ECDSA_do_sign(hash, hlen, privkey->ecdsa);
if (sig->ecdsa_sig == NULL) {
@@ -2005,7 +2026,7 @@ ssh_signature pki_do_sign_sessionid_hash(const ssh_key key,
}
sig->type = key->type;
- sig->type_c = key->type_c;
+ sig->type_c = ssh_key_signature_to_char(key->type, hash_type);
switch(key->type) {
case SSH_KEYTYPE_DSS:
@@ -2017,14 +2038,15 @@ ssh_signature pki_do_sign_sessionid_hash(const ssh_key key,
break;
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
- sig->type_c = ssh_key_signature_to_char(key->type, hash_type);
sig->rsa_sig = _RSA_do_sign_hash(hash, hlen, key->rsa, hash_type);
if (sig->rsa_sig == NULL) {
ssh_signature_free(sig);
return NULL;
}
break;
- case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_ECDSA_P256:
+ case SSH_KEYTYPE_ECDSA_P384:
+ case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_OPENSSL_ECC
sig->ecdsa_sig = ECDSA_do_sign(hash, hlen, key->ecdsa);
if (sig->ecdsa_sig == NULL) {