summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2013-11-06 16:39:00 +0100
committerAndreas Schneider <asn@cryptomilk.org>2013-11-06 17:10:35 +0100
commit06cd9bc4dc2530ee62e24e14a47a5a05b3dbfb5f (patch)
tree1b97020388775cd34740742c00c2a38fab0eb78a
parent0c8984ba9f01cb9686935bee27fd90acf86e4f6d (diff)
downloadlibssh-06cd9bc4dc2530ee62e24e14a47a5a05b3dbfb5f.tar.gz
libssh-06cd9bc4dc2530ee62e24e14a47a5a05b3dbfb5f.tar.xz
libssh-06cd9bc4dc2530ee62e24e14a47a5a05b3dbfb5f.zip
dh: Add new ssh_get_publickey_hash() function.
-rw-r--r--include/libssh/libssh.h14
-rw-r--r--src/dh.c121
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);
diff --git a/src/dh.c b/src/dh.c
index f96a94a..c22c849 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: */