From e38f2f933b3f091fa4d9beed917e31f82bcf6a1c Mon Sep 17 00:00:00 2001 From: Aris Adamantiadis Date: Sat, 24 Sep 2011 01:36:58 +0200 Subject: pki: ssh_pki_generate for both gcrypt and openssl --- include/libssh/libssh.h | 2 ++ include/libssh/pki_priv.h | 2 ++ src/pki.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/pki_crypto.c | 23 +++++++++++++++++++++++ src/pki_gcrypt.c | 27 +++++++++++++++++++++++++++ 5 files changed, 97 insertions(+) diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 2b9aa505..9c60eb3b 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -456,6 +456,8 @@ LIBSSH_API enum ssh_keytypes_e ssh_key_type_from_name(const char *name); LIBSSH_API int ssh_key_is_public(const ssh_key k); LIBSSH_API int ssh_key_is_private(const ssh_key k); +LIBSSH_API int ssh_pki_generate(enum ssh_keytypes_e type, int parameter, + ssh_key *pkey); LIBSSH_API int ssh_pki_import_privkey_base64(const char *b64_key, const char *passphrase, ssh_auth_callback auth_fn, diff --git a/include/libssh/pki_priv.h b/include/libssh/pki_priv.h index 8e9347f6..6be297ed 100644 --- a/include/libssh/pki_priv.h +++ b/include/libssh/pki_priv.h @@ -34,6 +34,8 @@ void _ssh_pki_log(const char *function, /* SSH Key Functions */ 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); /* SSH Private Key Functions */ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey); diff --git a/src/pki.c b/src/pki.c index d0e52c44..c6f0e5f8 100644 --- a/src/pki.c +++ b/src/pki.c @@ -789,6 +789,49 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) return rc; } +/** + * @brief Generates a keypair. + * @param[in] type Type of key to create + * @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 + * @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. + * @warning Generating a key pair may take some time. + */ + +int ssh_pki_generate(enum ssh_keytypes_e type, int parameter, + ssh_key *pkey){ + int rc; + ssh_key key = ssh_key_new(); + switch(type){ + case SSH_KEYTYPE_RSA: + case SSH_KEYTYPE_RSA1: + rc = pki_key_generate_rsa(key, parameter); + if(rc == SSH_ERROR) + goto error; + break; + case SSH_KEYTYPE_DSS: + rc = pki_key_generate_dss(key, parameter); + if(rc == SSH_ERROR) + goto error; + break; + case SSH_KEYTYPE_ECDSA: + 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: + ssh_key_free(key); + return SSH_ERROR; +} + /** * @brief Create a public key from a private key. * diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 130b5e5b..850ea668 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -244,6 +244,29 @@ fail: return NULL; } +int pki_key_generate_rsa(ssh_key key, int parameter){ + key->rsa = RSA_generate_key(parameter, 65537, NULL, NULL); + if(key->rsa == NULL) + return SSH_ERROR; + return SSH_OK; +} + +int pki_key_generate_dss(ssh_key key, int parameter){ + int rc; + key->dsa = DSA_generate_parameters(parameter, NULL, 0, NULL, NULL, + NULL, NULL); + if(key->dsa == NULL){ + return SSH_ERROR; + } + rc = DSA_generate_key(key->dsa); + if (rc != 1){ + DSA_free(key->dsa); + key->dsa=NULL; + return SSH_ERROR; + } + return SSH_OK; +} + ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase, ssh_auth_callback auth_fn, diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c index 6f3cd957..2bb99d24 100644 --- a/src/pki_gcrypt.c +++ b/src/pki_gcrypt.c @@ -966,6 +966,33 @@ fail: return NULL; } +static int pki_key_generate(ssh_key key, int parameter, const char *type_s, int type){ + gcry_sexp_t parms; + int rc; + rc = gcry_sexp_build(&parms, + NULL, + "(genkey(%s(nbits %d)(transient-key)))", + type_s, + parameter); + if (rc != 0) + return SSH_ERROR; + if(type == SSH_KEYTYPE_RSA) + rc = gcry_pk_genkey(&key->rsa, parms); + else + rc = gcry_pk_genkey(&key->dsa, parms); + gcry_sexp_release(parms); + if (rc != 0) + return SSH_ERROR; + return SSH_OK; +} + +int pki_key_generate_rsa(ssh_key key, int parameter){ + return pki_key_generate(key, parameter, "rsa", SSH_KEYTYPE_RSA); +} +int pki_key_generate_dss(ssh_key key, int parameter){ + return pki_key_generate(key, parameter, "dsa", SSH_KEYTYPE_DSS); +} + ssh_string pki_publickey_to_blob(const ssh_key key) { ssh_buffer buffer; -- cgit v1.2.3