diff --git a/include/libssh/pki.h b/include/libssh/pki.h index 8657f0f0..8046fca6 100644 --- a/include/libssh/pki.h +++ b/include/libssh/pki.h @@ -46,23 +46,10 @@ struct ssh_key_struct { void *cert; }; -ssh_key ssh_key_dup(const ssh_key key); -void ssh_key_clean (ssh_key key); +/* internal pki functions */ ssh_key pki_key_dup(const ssh_key key, int demote); -ssh_key ssh_pki_publickey_from_privatekey(const ssh_key privkey); -ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, - ssh_key privatekey); - -/* temporary functions, to be removed after migration to ssh_key */ -ssh_public_key ssh_pki_convert_key_to_publickey(ssh_key key); -ssh_private_key ssh_pki_convert_key_to_privatekey(ssh_key key); - enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey); - -ssh_key pki_private_key_from_base64(ssh_session session, - const char *b64_key, - const char *passphrase); int pki_pubkey_build_dss(ssh_key key, ssh_string p, ssh_string q, @@ -72,6 +59,23 @@ int pki_pubkey_build_rsa(ssh_key key, ssh_string e, ssh_string n); + +/* half public ssh pki functions */ +ssh_key ssh_key_dup(const ssh_key key); +void ssh_key_clean (ssh_key key); + +ssh_key ssh_pki_publickey_from_privatekey(const ssh_key privkey); +ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, + ssh_key privatekey); + +/* temporary functions, to be removed after migration to ssh_key */ +ssh_public_key ssh_pki_convert_key_to_publickey(ssh_key key); +ssh_private_key ssh_pki_convert_key_to_privatekey(ssh_key key); + + +ssh_key pki_private_key_from_base64(ssh_session session, + const char *b64_key, + const char *passphrase); int ssh_pki_import_pubkey_string(ssh_session session, const ssh_string pubkey, ssh_key *pkey); diff --git a/src/pki.c b/src/pki.c index 50c61877..004f2db0 100644 --- a/src/pki.c +++ b/src/pki.c @@ -609,6 +609,15 @@ 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) +{ + if (key == NULL || pstr == NULL) { + return SSH_ERROR; + } + + return pki_publickey_to_string(key, pstr); +} + /* * This function signs the session id (known as H) as a string then * the content of sigbuf */ diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 821d3ccb..763cb46a 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -347,6 +347,102 @@ 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 buffer; + ssh_string type_s; + ssh_string e = NULL; + ssh_string n = NULL; + ssh_string p = NULL; + ssh_string g = NULL; + ssh_string q = NULL; + 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: + p = make_bignum_string(key->p); + if (p == NULL) { + goto fail; + } + + q = make_bignum_string(key->q); + if (q == NULL) { + goto fail; + } + + g = make_bignum_string(key->g); + if (g == NULL) { + goto fail; + } + + n = make_bignum_string(key->pub_key); + if (n == NULL) { + goto fail; + } + + 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; + } + break; + case SSH_KEYTYPE_RSA: + case SSH_KEYTYPE_RSA1: + if (rsa_public_to_string(key->rsa_pub, buf) < 0) { + goto error; + } + break; + } + + 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); + + *pstr = str; + return SSH_OK; +fail: + ssh_buffer_free(buffer); + ssh_string_free(e); + ssh_string_free(p); + ssh_string_free(g); + ssh_string_free(q); + ssh_string_free(n); + + return SSH_ERROR; +} + struct signature_struct *pki_do_sign(ssh_key privatekey, const unsigned char *hash) { struct signature_struct *sign;