diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2013-11-06 16:39:00 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2013-11-06 17:10:35 +0100 |
commit | 06cd9bc4dc2530ee62e24e14a47a5a05b3dbfb5f (patch) | |
tree | 1b97020388775cd34740742c00c2a38fab0eb78a | |
parent | 0c8984ba9f01cb9686935bee27fd90acf86e4f6d (diff) | |
download | libssh-06cd9bc4dc2530ee62e24e14a47a5a05b3dbfb5f.tar.gz libssh-06cd9bc4dc2530ee62e24e14a47a5a05b3dbfb5f.tar.xz libssh-06cd9bc4dc2530ee62e24e14a47a5a05b3dbfb5f.zip |
dh: Add new ssh_get_publickey_hash() function.
-rw-r--r-- | include/libssh/libssh.h | 14 | ||||
-rw-r--r-- | src/dh.c | 121 |
2 files changed, 115 insertions, 20 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 84d0593..3833adc 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -412,8 +412,20 @@ LIBSSH_API socket_t ssh_get_fd(ssh_session session); LIBSSH_API char *ssh_get_hexa(const unsigned char *what, size_t len); LIBSSH_API char *ssh_get_issue_banner(ssh_session session); LIBSSH_API int ssh_get_openssh_version(ssh_session session); + LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key); -LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash); + +enum ssh_publickey_hash_type { + SSH_PUBLICKEY_HASH_SHA1, + SSH_PUBLICKEY_HASH_MD5 +}; +LIBSSH_API int ssh_get_publickey_hash(const ssh_key key, + enum ssh_publickey_hash_type type, + unsigned char **hash, + size_t *hlen); + +SSH_DEPRECATED LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash); + LIBSSH_API int ssh_get_random(void *where,int len,int strong); LIBSSH_API int ssh_get_version(ssh_session session); LIBSSH_API int ssh_get_status(ssh_session session); @@ -1047,25 +1047,7 @@ error: */ /** - * @brief Allocates a buffer with the MD5 hash of the server public key. - * - * This function allows you to get a MD5 hash of the public key. You can then - * print this hash in a human-readable form to the user so that he is able to - * verify it. Use ssh_get_hexa() or ssh_print_hexa() to display it. - * - * @param[in] session The SSH session to use. - * - * @param[in] hash The buffer to allocate. - * - * @return The bytes allocated or < 0 on error. - * - * @warning It is very important that you verify at some moment that the hash - * matches a known server. If you don't do it, cryptography wont help - * you at making things secure - * - * @see ssh_is_server_known() - * @see ssh_get_hexa() - * @see ssh_print_hexa() + * @deprecated Use ssh_get_publickey_hash() */ int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) { ssh_string pubkey; @@ -1142,6 +1124,107 @@ int ssh_get_publickey(ssh_session session, ssh_key *key) key); } +/** + * @brief Allocates a buffer with the hash of the public key. + * + * This function allows you to get a hash of the public key. You can then + * print this hash in a human-readable form to the user so that he is able to + * verify it. Use ssh_get_hexa() or ssh_print_hexa() to display it. + * + * @param[in] key The public key to create the hash for. + * + * @param[in] type The type of the hash you want. + * + * @param[in] hash A pointer to store the allocated buffer. It can be + * freed using ssh_clean_pubkey_hash(). + * + * @param[in] hlen The length of the hash. + * + * @return 0 on success, -1 if an error occured. + * + * @warning It is very important that you verify at some moment that the hash + * matches a known server. If you don't do it, cryptography wont help + * you at making things secure. + * OpenSSH uses SHA1 to print public key digests. + * + * @see ssh_is_server_known() + * @see ssh_get_hexa() + * @see ssh_print_hexa() + * @see ssh_clean_pubkey_hash() + */ +int ssh_get_publickey_hash(const ssh_key key, + enum ssh_publickey_hash_type type, + unsigned char **hash, + size_t *hlen) +{ + ssh_string blob; + unsigned char *h; + int rc; + + rc = ssh_pki_export_pubkey_blob(key, &blob); + if (rc < 0) { + return rc; + } + + switch (type) { + case SSH_PUBLICKEY_HASH_SHA1: + { + SHACTX ctx; + + h = malloc(SHA_DIGEST_LEN); + if (h == NULL) { + rc = -1; + goto out; + } + + ctx = sha1_init(); + if (ctx == NULL) { + free(h); + rc = -1; + goto out; + } + + sha1_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); + sha1_final(h, ctx); + + *hlen = SHA_DIGEST_LEN; + } + break; + case SSH_PUBLICKEY_HASH_MD5: + { + MD5CTX ctx; + + h = malloc(MD5_DIGEST_LEN); + if (h == NULL) { + rc = -1; + goto out; + } + + ctx = md5_init(); + if (ctx == NULL) { + free(h); + rc = -1; + goto out; + } + + md5_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); + md5_final(h, ctx); + + *hlen = MD5_DIGEST_LEN; + } + break; + default: + rc = -1; + goto out; + } + + *hash = h; + rc = 0; +out: + ssh_string_free(blob); + return rc; +} + /** @} */ /* vim: set ts=4 sw=4 et cindent: */ |