diff --git a/include/libssh/pki_priv.h b/include/libssh/pki_priv.h index 7963984d..580956da 100644 --- a/include/libssh/pki_priv.h +++ b/include/libssh/pki_priv.h @@ -40,6 +40,7 @@ int pki_key_ecdsa_nid_from_name(const char *name); ssh_key pki_key_dup(const ssh_key key, int demote); int pki_key_generate_rsa(ssh_key key, int parameter); int pki_key_generate_dss(ssh_key key, int parameter); +int pki_key_generate_ecdsa(ssh_key key, int parameter); int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what); diff --git a/src/pki.c b/src/pki.c index 0d17050c..1ebc84a2 100644 --- a/src/pki.c +++ b/src/pki.c @@ -870,7 +870,7 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) * @param[in] parameter Parameter to the creation of key: * rsa : length of the key in bits (e.g. 1024, 2048, 4096) * dsa : length of the key in bits (e.g. 1024, 2048, 3072) - * ecdsa : not implemented + * ecdsa : bits of the key (e.g. 256, 384, 512) * @param[out] pkey A pointer to store the private key. You need to free the * memory. * @return SSH_OK on success, SSH_ERROR on error. @@ -881,6 +881,11 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter, ssh_key *pkey){ int rc; ssh_key key = ssh_key_new(); + + key->type = type; + key->type_c = ssh_key_type_to_char(type); + key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; + switch(type){ case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: @@ -894,12 +899,16 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter, goto error; break; case SSH_KEYTYPE_ECDSA: +#ifdef HAVE_ECC + rc = pki_key_generate_ecdsa(key, parameter); + if(rc == SSH_ERROR) + goto error; + break; +#endif case SSH_KEYTYPE_UNKNOWN: goto error; } - key->type = type; - key->type_c = ssh_key_type_to_char(type); - key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; + *pkey = key; return SSH_OK; error: diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 10b4150e..e07008cc 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -403,6 +403,40 @@ int pki_key_generate_dss(ssh_key key, int parameter){ return SSH_OK; } +int pki_key_generate_ecdsa(ssh_key key, int parameter) { + int nid; + int ok; + + switch (parameter) { + case 384: + nid = NID_secp384r1; + case 512: + nid = NID_secp521r1; + case 256: + default: + nid = NID_X9_62_prime256v1; + } + + 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); + if (key->ecdsa == NULL) { + return SSH_ERROR; + } + + ok = EC_KEY_generate_key(key->ecdsa); + if (!ok) { + EC_KEY_free(key->ecdsa); + return SSH_ERROR; + } + + EC_KEY_set_asn1_flag(key->ecdsa, OPENSSL_EC_NAMED_CURVE); + + return SSH_OK; +} + int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what)