aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2011-12-30 11:02:06 +0100
committerAndreas Schneider <asn@cryptomilk.org>2012-02-04 18:37:04 +0100
commitb309dd8fb72d1deaa16536f6d3391711594bbca5 (patch)
treedb77df97da3ca0611b04c4954e1b68defd985c8a
parent91372e298d8effb5b3f8904449ebd5ca84afff2f (diff)
downloadlibssh-b309dd8fb72d1deaa16536f6d3391711594bbca5.tar.gz
libssh-b309dd8fb72d1deaa16536f6d3391711594bbca5.tar.xz
libssh-b309dd8fb72d1deaa16536f6d3391711594bbca5.zip
pki: Add support to generate ecdsa keys.
-rw-r--r--include/libssh/pki_priv.h1
-rw-r--r--src/pki.c17
-rw-r--r--src/pki_crypto.c34
3 files changed, 48 insertions, 4 deletions
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)