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:
@@ -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__)
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user