summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2011-08-15 18:47:18 +0200
committerAndreas Schneider <asn@cryptomilk.org>2011-08-15 18:48:08 +0200
commit6ffee224486500ef3f01f7812d5b9c84f5b1aac4 (patch)
treea9a001f18c0b232cf7a11c56e8b01809a40e4d98 /src
parentfe375132c33cbfd3ec6cbfdde35efe5439dbbdbb (diff)
downloadlibssh-6ffee224486500ef3f01f7812d5b9c84f5b1aac4.tar.gz
libssh-6ffee224486500ef3f01f7812d5b9c84f5b1aac4.tar.xz
libssh-6ffee224486500ef3f01f7812d5b9c84f5b1aac4.zip
pki: Add ssh_pki_publickey_to_string().
Diffstat (limited to 'src')
-rw-r--r--src/pki.c16
-rw-r--r--src/pki_crypto.c74
-rw-r--r--src/pki_gcrypt.c178
3 files changed, 247 insertions, 21 deletions
diff --git a/src/pki.c b/src/pki.c
index 004f2db..6883a21 100644
--- a/src/pki.c
+++ b/src/pki.c
@@ -609,13 +609,21 @@ ssh_key ssh_pki_publickey_from_privatekey(const ssh_key privkey) {
return pki_key_dup(privkey, 1);
}
-int ssh_pki_publickey_to_string(const ssh_key key, ssh_string *pstr)
+/**
+ * @brief Create a ssh string from a public key.
+ *
+ * @param[in] key A public or private key to create the public ssh_string
+ * from.
+ *
+ * @return The string or NULL on error.
+ */
+ssh_string ssh_pki_publickey_to_string(const ssh_key key)
{
- if (key == NULL || pstr == NULL) {
- return SSH_ERROR;
+ if (key == NULL) {
+ return NULL;
}
- return pki_publickey_to_string(key, pstr);
+ return pki_publickey_to_string(key);
}
/*
diff --git a/src/pki_crypto.c b/src/pki_crypto.c
index 68d46b3..32e6c6a 100644
--- a/src/pki_crypto.c
+++ b/src/pki_crypto.c
@@ -32,6 +32,7 @@
#include "libssh/priv.h"
#include "libssh/libssh.h"
+#include "libssh/buffer.h"
#include "libssh/session.h"
#include "libssh/callbacks.h"
#include "libssh/pki.h"
@@ -347,10 +348,11 @@ int pki_pubkey_build_rsa(ssh_key key,
return SSH_OK;
}
-int pki_publickey_to_string(const ssh_key key, ssh_string *pstr)
+ssh_string pki_publickey_to_string(const ssh_key key)
{
- ssh_string buffer;
+ ssh_buffer buffer;
ssh_string type_s;
+ ssh_string str = NULL;
ssh_string e = NULL;
ssh_string n = NULL;
ssh_string p = NULL;
@@ -378,22 +380,22 @@ int pki_publickey_to_string(const ssh_key key, ssh_string *pstr)
switch (key->type) {
case SSH_KEYTYPE_DSS:
- p = make_bignum_string(key->p);
+ p = make_bignum_string(key->dsa->p);
if (p == NULL) {
goto fail;
}
- q = make_bignum_string(key->q);
+ q = make_bignum_string(key->dsa->q);
if (q == NULL) {
goto fail;
}
- g = make_bignum_string(key->g);
+ g = make_bignum_string(key->dsa->g);
if (g == NULL) {
goto fail;
}
- n = make_bignum_string(key->pub_key);
+ n = make_bignum_string(key->dsa->pub_key);
if (n == NULL) {
goto fail;
}
@@ -410,14 +412,46 @@ int pki_publickey_to_string(const ssh_key key, ssh_string *pstr)
if (buffer_add_ssh_string(buffer, n) < 0) {
goto fail;
}
- break;
- case SSH_KEYTYPE_RSA:
- case SSH_KEYTYPE_RSA1:
- if (rsa_public_to_string(key->rsa_pub, buf) < 0) {
- goto error;
- }
- break;
- }
+
+ ssh_string_burn(p);
+ ssh_string_free(p);
+ ssh_string_burn(g);
+ ssh_string_free(g);
+ ssh_string_burn(q);
+ ssh_string_free(q);
+ ssh_string_burn(n);
+ ssh_string_free(n);
+
+ break;
+ case SSH_KEYTYPE_RSA:
+ case SSH_KEYTYPE_RSA1:
+ e = make_bignum_string(key->rsa->e);
+ if (p == NULL) {
+ goto fail;
+ }
+
+ n = make_bignum_string(key->rsa->n);
+ if (q == NULL) {
+ goto fail;
+ }
+
+ if (buffer_add_ssh_string(buffer, e) < 0) {
+ goto fail;
+ }
+ if (buffer_add_ssh_string(buffer, n) < 0) {
+ goto fail;
+ }
+
+ ssh_string_burn(e);
+ ssh_string_free(e);
+ ssh_string_burn(n);
+ ssh_string_free(n);
+
+ break;
+ case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_UNKNOWN:
+ goto fail;
+ }
str = ssh_string_new(buffer_get_rest_len(buffer));
if (str == NULL) {
@@ -430,17 +464,23 @@ int pki_publickey_to_string(const ssh_key key, ssh_string *pstr)
}
ssh_buffer_free(buffer);
- *pstr = str;
- return SSH_OK;
+ return str;
fail:
ssh_buffer_free(buffer);
+ ssh_string_burn(str);
+ ssh_string_free(str);
+ ssh_string_burn(e);
ssh_string_free(e);
+ ssh_string_burn(p);
ssh_string_free(p);
+ ssh_string_burn(g);
ssh_string_free(g);
+ ssh_string_burn(q);
ssh_string_free(q);
+ ssh_string_burn(n);
ssh_string_free(n);
- return SSH_ERROR;
+ return NULL;
}
struct signature_struct *pki_do_sign(ssh_key privatekey,
diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c
index 28b4bad..8fd96bc 100644
--- a/src/pki_gcrypt.c
+++ b/src/pki_gcrypt.c
@@ -991,6 +991,184 @@ fail:
return NULL;
}
+ssh_string pki_publickey_to_string(const ssh_key key)
+{
+ ssh_buffer buffer;
+ ssh_string type_s;
+ ssh_string str = NULL;
+ ssh_string e = NULL;
+ ssh_string n = NULL;
+ ssh_string p = NULL;
+ ssh_string g = NULL;
+ ssh_string q = NULL;
+ const char *tmp = NULL;
+ size_t size;
+ gcry_sexp_t sexp;
+ int rc;
+
+ buffer = ssh_buffer_new();
+ if (buffer == NULL) {
+ return NULL;
+ }
+
+ type_s = ssh_string_from_char(key->type_c);
+ if (type_s == NULL) {
+ ssh_buffer_free(buffer);
+ return NULL;
+ }
+
+ rc = buffer_add_ssh_string(buffer, type_s);
+ string_free(type_s);
+ if (rc < 0) {
+ ssh_buffer_free(buffer);
+ return NULL;
+ }
+
+ switch (key->type) {
+ case SSH_KEYTYPE_DSS:
+ sexp = gcry_sexp_find_token(key, "p", 0);
+ if (sexp == NULL) {
+ goto fail;
+ }
+ tmp = gcry_sexp_nth_data(sexp, 1, &size);
+ p = ssh_string_new(size);
+ if (p == NULL) {
+ goto fail;
+ }
+ ssh_string_fill(p, (char *) tmp, size);
+ gcry_sexp_release(sexp);
+
+ sexp = gcry_sexp_find_token(key, "q", 0);
+ if (sexp == NULL) {
+ goto fail;
+ }
+ tmp = gcry_sexp_nth_data(sexp, 1, &size);
+ q = ssh_string_new(size);
+ if (q == NULL) {
+ goto fail;
+ }
+ ssh_string_fill(q, (char *) tmp, size);
+ gcry_sexp_release(sexp);
+
+ sexp = gcry_sexp_find_token(key, "g", 0);
+ if (sexp == NULL) {
+ goto fail;
+ }
+ tmp = gcry_sexp_nth_data(sexp, 1, &size);
+ g = ssh_string_new(size);
+ if (g == NULL) {
+ goto fail;
+ }
+ ssh_string_fill(g, (char *) tmp, size);
+ gcry_sexp_release(sexp);
+
+ sexp = gcry_sexp_find_token(key, "y", 0);
+ if (sexp == NULL) {
+ goto fail;
+ }
+ tmp = gcry_sexp_nth_data(sexp, 1, &size);
+ n = ssh_string_new(size);
+ if (n == NULL) {
+ goto fail;
+ }
+ ssh_string_fill(n, (char *) tmp, size);
+
+ if (buffer_add_ssh_string(buffer, p) < 0) {
+ goto fail;
+ }
+ if (buffer_add_ssh_string(buffer, q) < 0) {
+ goto fail;
+ }
+ if (buffer_add_ssh_string(buffer, g) < 0) {
+ goto fail;
+ }
+ if (buffer_add_ssh_string(buffer, n) < 0) {
+ goto fail;
+ }
+
+ ssh_string_burn(p);
+ ssh_string_free(p);
+ ssh_string_burn(g);
+ ssh_string_free(g);
+ ssh_string_burn(q);
+ ssh_string_free(q);
+ ssh_string_burn(n);
+ ssh_string_free(n);
+
+ break;
+ case SSH_KEYTYPE_RSA:
+ case SSH_KEYTYPE_RSA1:
+ sexp = gcry_sexp_find_token(key, "e", 0);
+ if (sexp == NULL) {
+ goto error;
+ }
+ tmp = gcry_sexp_nth_data(sexp, 1, &size);
+ e = ssh_string_new(size);
+ if (e == NULL) {
+ goto error;
+ }
+ ssh_string_fill(e, (char *) tmp, size);
+
+ sexp = gcry_sexp_find_token(key, "n", 0);
+ if (sexp == NULL) {
+ goto error;
+ }
+ tmp = gcry_sexp_nth_data(sexp, 1, &size);
+ n = ssh_string_new(size);
+ if (n == NULL) {
+ goto error;
+ }
+ ssh_string_fill(n, (char *) tmp, size);
+ gcry_sexp_release(sexp);
+
+ if (buffer_add_ssh_string(buffer, e) < 0) {
+ goto fail;
+ }
+ if (buffer_add_ssh_string(buffer, n) < 0) {
+ goto fail;
+ }
+
+ ssh_string_burn(e);
+ ssh_string_free(e);
+ ssh_string_burn(n);
+ ssh_string_free(n);
+
+ break;
+ case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_UNKNOWN:
+ goto fail;
+ }
+
+ str = ssh_string_new(buffer_get_rest_len(buffer));
+ if (str == NULL) {
+ goto fail;
+ }
+
+ rc = ssh_string_fill(str, buffer_get_rest(buffer), buffer_get_rest_len(buffer));
+ if (rc < 0) {
+ goto fail;
+ }
+ ssh_buffer_free(buffer);
+
+ return str;
+fail:
+ ssh_buffer_free(buffer);
+ ssh_string_burn(str);
+ ssh_string_free(str);
+ ssh_string_burn(e);
+ ssh_string_free(e);
+ ssh_string_burn(p);
+ ssh_string_free(p);
+ ssh_string_burn(g);
+ ssh_string_free(g);
+ ssh_string_burn(q);
+ ssh_string_free(q);
+ ssh_string_burn(n);
+ ssh_string_free(n);
+
+ return NULL;
+}
+
struct signature_struct *pki_do_sign(ssh_key privatekey,
const unsigned char *hash) {
struct signature_struct *sign;