diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2011-08-15 18:47:18 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2011-08-15 18:48:08 +0200 |
commit | 6ffee224486500ef3f01f7812d5b9c84f5b1aac4 (patch) | |
tree | a9a001f18c0b232cf7a11c56e8b01809a40e4d98 /src | |
parent | fe375132c33cbfd3ec6cbfdde35efe5439dbbdbb (diff) | |
download | libssh-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.c | 16 | ||||
-rw-r--r-- | src/pki_crypto.c | 74 | ||||
-rw-r--r-- | src/pki_gcrypt.c | 178 |
3 files changed, 247 insertions, 21 deletions
@@ -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; |