diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 84d05937..3833adcd 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); diff --git a/src/dh.c b/src/dh.c index f96a94a3..c22c849f 100644 --- a/src/dh.c +++ b/src/dh.c @@ -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: */