1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-02 03:52:49 -05:00

Centralise SSH-2 key fingerprinting into sshpubk.c.

There were ad-hoc functions for fingerprinting a bare key blob in both
cmdgen.c and pageant.c, not quite doing the same thing. Also, every
SSH-2 public key algorithm in the code base included a dedicated
fingerprint() method, which is completely pointless since SSH-2 key
fingerprints are computed in an algorithm-independent way (just hash
the standard-format public key blob), so each of those methods was
just duplicating the work of the public_blob() method with a less
general output mechanism.

Now sshpubk.c centrally provides an ssh2_fingerprint_blob() function
that does all the real work, plus an ssh2_fingerprint() function that
wraps it and deals with calling public_blob() to get something to
fingerprint. And the fingerprint() method has been completely removed
from ssh_signkey and all its implementations, and good riddance.
This commit is contained in:
Simon Tatham
2015-05-12 14:35:44 +01:00
parent eef0235a0f
commit 8682246d33
10 changed files with 71 additions and 213 deletions

View File

@ -1568,6 +1568,62 @@ void ssh2_write_pubkey(FILE *fp, const char *comment,
}
}
/* ----------------------------------------------------------------------
* Utility functions to compute SSH-2 fingerprints in a uniform way.
*/
char *ssh2_fingerprint_blob(const void *blob, int bloblen)
{
unsigned char digest[16];
char fingerprint_str[16*3];
const char *algstr;
int alglen;
const struct ssh_signkey *alg;
int i;
/*
* The fingerprint hash itself is always just the MD5 of the blob.
*/
MD5Simple(blob, bloblen, digest);
for (i = 0; i < 16; i++)
sprintf(fingerprint_str + i*3, "%02x%s", digest[i], i==15 ? "" : ":");
/*
* Identify the key algorithm, if possible.
*/
alglen = toint(GET_32BIT((const unsigned char *)blob));
if (alglen > 0 && alglen < bloblen-4) {
algstr = (const char *)blob + 4;
/*
* If we can actually identify the algorithm as one we know
* about, get hold of the key's bit count too.
*/
alg = find_pubkey_alg_len(alglen, algstr);
if (alg) {
int bits = alg->pubkey_bits(blob, bloblen);
return dupprintf("%.*s %d %s", alglen, algstr,
bits, fingerprint_str);
} else {
return dupprintf("%.*s %s", alglen, algstr, fingerprint_str);
}
} else {
/*
* No algorithm available (which means a seriously confused
* key blob, but there we go). Return only the hash.
*/
return dupstr(fingerprint_str);
}
}
char *ssh2_fingerprint(const struct ssh_signkey *alg, void *data)
{
int len;
unsigned char *blob = alg->public_blob(data, &len);
char *ret = ssh2_fingerprint_blob(blob, len);
sfree(blob);
return ret;
}
/* ----------------------------------------------------------------------
* Determine the type of a private key file.
*/