mirror of
https://git.proxmox.com/git/libgit2
synced 2025-07-10 13:25:14 +00:00
ssh: expose both hashes
The user may have the data hashed as MD5 or SHA-1, so we should provide both types for consumption.
This commit is contained in:
parent
286369a81f
commit
1e0aa105fa
@ -24,11 +24,11 @@ GIT_BEGIN_DECL
|
||||
* Type of SSH host fingerprint
|
||||
*/
|
||||
typedef enum {
|
||||
/** MD5, 16 bytes */
|
||||
GIT_CERT_SSH_MD5,
|
||||
/** SHA-1, 20 bytes */
|
||||
GIT_CERT_SSH_SHA1,
|
||||
} git_cert_ssh_type ;
|
||||
/** MD5 is available */
|
||||
GIT_CERT_SSH_MD5 = (1 << 0),
|
||||
/** SHA-1 is available */
|
||||
GIT_CERT_SSH_SHA1 = (1 << 1),
|
||||
} git_cert_ssh_t;
|
||||
|
||||
/**
|
||||
* Hostkey information taken from libssh2
|
||||
@ -43,12 +43,19 @@ typedef struct {
|
||||
* A hostkey type from libssh2, either
|
||||
* `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1`
|
||||
*/
|
||||
git_cert_ssh_type type;
|
||||
git_cert_ssh_t type;
|
||||
|
||||
/**
|
||||
* Hostkey hash. If the type is MD5, only the first 16 bytes
|
||||
* will be set.
|
||||
* Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will
|
||||
* have the MD5 hash of the hostkey.
|
||||
*/
|
||||
unsigned char hash[20];
|
||||
unsigned char hash_md5[16];
|
||||
|
||||
/**
|
||||
* Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will
|
||||
* have the SHA-1 hash of the hostkey.
|
||||
*/
|
||||
unsigned char hash_sha1[20];
|
||||
} git_cert_hostkey;
|
||||
|
||||
/**
|
||||
|
@ -487,17 +487,17 @@ static int _git_ssh_setup_conn(
|
||||
|
||||
key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
if (key != NULL) {
|
||||
cert.type = GIT_CERT_SSH_SHA1;
|
||||
memcpy(&cert.hash, key, 20);
|
||||
} else {
|
||||
key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||
if (key != NULL) {
|
||||
cert.type = GIT_CERT_SSH_MD5;
|
||||
memcpy(&cert.hash, key, 16);
|
||||
}
|
||||
cert.type |= GIT_CERT_SSH_SHA1;
|
||||
memcpy(&cert.hash_sha1, key, 20);
|
||||
}
|
||||
|
||||
if (key == NULL) {
|
||||
key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||
if (key != NULL) {
|
||||
cert.type |= GIT_CERT_SSH_MD5;
|
||||
memcpy(&cert.hash_md5, key, 16);
|
||||
}
|
||||
|
||||
if (cert.type == 0) {
|
||||
giterr_set(GITERR_SSH, "unable to get the host key");
|
||||
return -1;
|
||||
}
|
||||
|
@ -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_assert_equal_i(GIT_CERT_HOSTKEY_LIBSSH2, cert->cert_type);
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user