1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-08 19:02:06 +03:00

pki: Add support to import ecdsa private keys.

This commit is contained in:
Andreas Schneider
2011-12-27 21:22:19 +01:00
parent b4823252ca
commit ea74a12b70
3 changed files with 58 additions and 0 deletions

View File

@@ -26,6 +26,8 @@
#define RSA_HEADER_END "-----END RSA PRIVATE KEY-----" #define RSA_HEADER_END "-----END RSA PRIVATE KEY-----"
#define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----" #define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
#define DSA_HEADER_END "-----END DSA PRIVATE KEY-----" #define DSA_HEADER_END "-----END DSA PRIVATE KEY-----"
#define ECDSA_HEADER_BEGIN "-----BEGIN EC PRIVATE KEY-----"
#define ECDSA_HEADER_END "-----END EC PRIVATE KEY-----"
#define ssh_pki_log(...) \ #define ssh_pki_log(...) \
_ssh_pki_log(__FUNCTION__, __VA_ARGS__) _ssh_pki_log(__FUNCTION__, __VA_ARGS__)

View File

@@ -91,6 +91,10 @@ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey) {
return SSH_KEYTYPE_RSA; return SSH_KEYTYPE_RSA;
} }
if (strncmp(privkey, ECDSA_HEADER_BEGIN, strlen(ECDSA_HEADER_BEGIN)) == 0) {
return SSH_KEYTYPE_ECDSA;
}
return SSH_KEYTYPE_UNKNOWN; return SSH_KEYTYPE_UNKNOWN;
} }

View File

@@ -75,6 +75,21 @@ static int pem_get_password(char *buf, int size, int rwflag, void *userdata) {
return 0; 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 pki_key_dup(const ssh_key key, int demote)
{ {
ssh_key new; ssh_key new;
@@ -363,6 +378,11 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
RSA *rsa = NULL; RSA *rsa = NULL;
ssh_key key; ssh_key key;
enum ssh_keytypes_e type; enum ssh_keytypes_e type;
#ifdef HAVE_OPENSSL_ECC
EC_KEY *ecdsa = NULL;
#else
void *ecdsa = NULL;
#endif
/* needed for openssl initialization */ /* needed for openssl initialization */
if (ssh_init() < 0) { if (ssh_init() < 0) {
@@ -426,6 +446,30 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
break; break;
case SSH_KEYTYPE_ECDSA: 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: case SSH_KEYTYPE_UNKNOWN:
BIO_free(mem); BIO_free(mem);
ssh_pki_log("Unkown or invalid private key type %d", type); 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->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
key->dsa = dsa; key->dsa = dsa;
key->rsa = rsa; 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; return key;
fail: fail:
ssh_key_free(key); ssh_key_free(key);
DSA_free(dsa); DSA_free(dsa);
RSA_free(rsa); RSA_free(rsa);
EC_KEY_free(ecdsa);
return NULL; return NULL;
} }