aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2011-12-27 21:22:19 +0100
committerAndreas Schneider <asn@cryptomilk.org>2012-02-04 18:37:03 +0100
commitea74a12b70549113039ef61fc89ae84b08a05bcd (patch)
tree1783b124f5f70ec8649414f44915b71a6e2e6c8f /src
parentb4823252ca1acd819a2133e7b261dc474ebcde1c (diff)
downloadlibssh-ea74a12b70549113039ef61fc89ae84b08a05bcd.tar.gz
libssh-ea74a12b70549113039ef61fc89ae84b08a05bcd.tar.xz
libssh-ea74a12b70549113039ef61fc89ae84b08a05bcd.zip
pki: Add support to import ecdsa private keys.
Diffstat (limited to 'src')
-rw-r--r--src/pki.c4
-rw-r--r--src/pki_crypto.c52
2 files changed, 56 insertions, 0 deletions
diff --git a/src/pki.c b/src/pki.c
index 2b720d33..00bca82e 100644
--- a/src/pki.c
+++ b/src/pki.c
@@ -91,6 +91,10 @@ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey) {
return SSH_KEYTYPE_RSA;
}
+ if (strncmp(privkey, ECDSA_HEADER_BEGIN, strlen(ECDSA_HEADER_BEGIN)) == 0) {
+ return SSH_KEYTYPE_ECDSA;
+ }
+
return SSH_KEYTYPE_UNKNOWN;
}
diff --git a/src/pki_crypto.c b/src/pki_crypto.c
index ca7a5b21..62a6dcc3 100644
--- a/src/pki_crypto.c
+++ b/src/pki_crypto.c
@@ -75,6 +75,21 @@ static int pem_get_password(char *buf, int size, int rwflag, void *userdata) {
return 0;
}
+#ifdef HAVE_OPENSSL_ECC
+static int pki_key_ecdsa_to_nid(EC_KEY *k)
+{
+ const EC_GROUP *g = EC_KEY_get0_group(k);
+ int nid;
+
+ nid = EC_GROUP_get_curve_name(g);
+ if (nid) {
+ return nid;
+ }
+
+ return -1;
+}
+#endif
+
ssh_key pki_key_dup(const ssh_key key, int demote)
{
ssh_key new;
@@ -363,6 +378,11 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
RSA *rsa = NULL;
ssh_key key;
enum ssh_keytypes_e type;
+#ifdef HAVE_OPENSSL_ECC
+ EC_KEY *ecdsa = NULL;
+#else
+ void *ecdsa = NULL;
+#endif
/* needed for openssl initialization */
if (ssh_init() < 0) {
@@ -426,6 +446,30 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
break;
case SSH_KEYTYPE_ECDSA:
+#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_pki_log("Parsing private key: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return NULL;
+ }
+
+ break;
+#endif
case SSH_KEYTYPE_UNKNOWN:
BIO_free(mem);
ssh_pki_log("Unkown or invalid private key type %d", type);
@@ -442,12 +486,20 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
key->dsa = dsa;
key->rsa = rsa;
+ key->ecdsa = ecdsa;
+#ifdef HAVE_OPENSSL_ECC
+ if (key->type == SSH_KEYTYPE_ECDSA) {
+ key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
+ key->type_c = pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
+ }
+#endif
return key;
fail:
ssh_key_free(key);
DSA_free(dsa);
RSA_free(rsa);
+ EC_KEY_free(ecdsa);
return NULL;
}