Commit 1e0aa105 by Carlos Martín Nieto

ssh: expose both hashes

The user may have the data hashed as MD5 or SHA-1, so we should provide
both types for consumption.
parent 286369a8
...@@ -24,11 +24,11 @@ GIT_BEGIN_DECL ...@@ -24,11 +24,11 @@ GIT_BEGIN_DECL
* Type of SSH host fingerprint * Type of SSH host fingerprint
*/ */
typedef enum { typedef enum {
/** MD5, 16 bytes */ /** MD5 is available */
GIT_CERT_SSH_MD5, GIT_CERT_SSH_MD5 = (1 << 0),
/** SHA-1, 20 bytes */ /** SHA-1 is available */
GIT_CERT_SSH_SHA1, GIT_CERT_SSH_SHA1 = (1 << 1),
} git_cert_ssh_type ; } git_cert_ssh_t;
/** /**
* Hostkey information taken from libssh2 * Hostkey information taken from libssh2
...@@ -43,12 +43,19 @@ typedef struct { ...@@ -43,12 +43,19 @@ typedef struct {
* A hostkey type from libssh2, either * A hostkey type from libssh2, either
* `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1` * `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1`
*/ */
git_cert_ssh_type type; git_cert_ssh_t type;
/**
* Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will
* have the MD5 hash of the hostkey.
*/
unsigned char hash_md5[16];
/** /**
* Hostkey hash. If the type is MD5, only the first 16 bytes * Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will
* will be set. * have the SHA-1 hash of the hostkey.
*/ */
unsigned char hash[20]; unsigned char hash_sha1[20];
} git_cert_hostkey; } git_cert_hostkey;
/** /**
......
...@@ -487,17 +487,17 @@ static int _git_ssh_setup_conn( ...@@ -487,17 +487,17 @@ static int _git_ssh_setup_conn(
key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
if (key != NULL) { if (key != NULL) {
cert.type = GIT_CERT_SSH_SHA1; cert.type |= GIT_CERT_SSH_SHA1;
memcpy(&cert.hash, key, 20); memcpy(&cert.hash_sha1, key, 20);
} else { }
key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
if (key != NULL) { if (key != NULL) {
cert.type = GIT_CERT_SSH_MD5; cert.type |= GIT_CERT_SSH_MD5;
memcpy(&cert.hash, key, 16); memcpy(&cert.hash_md5, key, 16);
}
} }
if (key == NULL) { if (cert.type == 0) {
giterr_set(GITERR_SSH, "unable to get the host key"); giterr_set(GITERR_SSH, "unable to get the host key");
return -1; return -1;
} }
......
...@@ -488,13 +488,22 @@ int ssh_certificate_check(git_cert *cert, int valid, void *payload) ...@@ -488,13 +488,22 @@ int ssh_certificate_check(git_cert *cert, int valid, void *payload)
cl_git_pass(git_oid_fromstrp(&expected, expected_str)); cl_git_pass(git_oid_fromstrp(&expected, expected_str));
cl_assert_equal_i(GIT_CERT_HOSTKEY_LIBSSH2, cert->cert_type); cl_assert_equal_i(GIT_CERT_HOSTKEY_LIBSSH2, cert->cert_type);
key = (git_cert_hostkey *) cert; key = (git_cert_hostkey *) cert;
git_oid_fromraw(&actual, key->hash);
cl_assert_equal_i(GIT_CERT_SSH_SHA1, key->type); /*
* We need to figure out how long our input was to check for
* the type. Here we abuse the fact that both hashes fit into
* our git_oid type.
*/
if (strlen(expected_str) == 32 && key->type & GIT_CERT_SSH_MD5) {
memcpy(&actual.id, key->hash_md5, 16);
} else if (strlen(expected_str) == 40 && key->type & GIT_CERT_SSH_SHA1) {
memcpy(&actual, key->hash_sha1, 20);
} else {
cl_fail("Cannot find a usable SSH hash");
}
cl_assert(git_oid_equal(&expected, &actual)); cl_assert(!memcmp(&expected, &actual, 20));
return GIT_EUSER; return GIT_EUSER;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment