mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
Add API for getting all of a key's fingerprints.
ssh2_all_fingerprints() and friends will return a small 'char **' array, containing all the fingerprints of a key that we know how to generate, indexed by the FingerprintType enum. The result requires complex freeing, so there's an ssh2_free_all_fingerprints as well. For SSH-1 RSA keys, we refuse to generate any fingerprint except the old SSH-1 MD5 version, because there's no other fingerprint type I know of that anyone else uses. So I've got a function that returns the same 'char **' for an SSH-1 key, but it only fills in the MD5 slot, and leaves the rest NULL. As a result, I also need a dynamic function that takes a fingerprint list and returns the id of the most preferred fingerprint type in it _that actually exists_. NFC: this API is introduced, but not yet used.
This commit is contained in:
parent
911ead25e7
commit
995e2f7164
8
ssh.h
8
ssh.h
@ -567,6 +567,7 @@ mp_int *rsa_ssh1_decrypt(mp_int *input, RSAKey *key);
|
|||||||
bool rsa_ssh1_decrypt_pkcs1(mp_int *input, RSAKey *key, strbuf *outbuf);
|
bool rsa_ssh1_decrypt_pkcs1(mp_int *input, RSAKey *key, strbuf *outbuf);
|
||||||
char *rsastr_fmt(RSAKey *key);
|
char *rsastr_fmt(RSAKey *key);
|
||||||
char *rsa_ssh1_fingerprint(RSAKey *key);
|
char *rsa_ssh1_fingerprint(RSAKey *key);
|
||||||
|
char **rsa_ssh1_fake_all_fingerprints(RSAKey *key);
|
||||||
bool rsa_verify(RSAKey *key);
|
bool rsa_verify(RSAKey *key);
|
||||||
void rsa_ssh1_public_blob(BinarySink *bs, RSAKey *key, RsaSsh1Order order);
|
void rsa_ssh1_public_blob(BinarySink *bs, RSAKey *key, RsaSsh1Order order);
|
||||||
int rsa_ssh1_public_blob_len(ptrlen data);
|
int rsa_ssh1_public_blob_len(ptrlen data);
|
||||||
@ -1337,6 +1338,10 @@ typedef enum {
|
|||||||
#define SSH_FPTYPE_DEFAULT SSH_FPTYPE_MD5
|
#define SSH_FPTYPE_DEFAULT SSH_FPTYPE_MD5
|
||||||
#define SSH_N_FPTYPES (SSH_FPTYPE_SHA256 + 1)
|
#define SSH_N_FPTYPES (SSH_FPTYPE_SHA256 + 1)
|
||||||
|
|
||||||
|
FingerprintType ssh2_pick_fingerprint(char **fingerprints,
|
||||||
|
FingerprintType preferred_type);
|
||||||
|
FingerprintType ssh2_pick_default_fingerprint(char **fingerprints);
|
||||||
|
|
||||||
char *ssh1_pubkey_str(RSAKey *ssh1key);
|
char *ssh1_pubkey_str(RSAKey *ssh1key);
|
||||||
void ssh1_write_pubkey(FILE *fp, RSAKey *ssh1key);
|
void ssh1_write_pubkey(FILE *fp, RSAKey *ssh1key);
|
||||||
char *ssh2_pubkey_openssh_str(ssh2_userkey *key);
|
char *ssh2_pubkey_openssh_str(ssh2_userkey *key);
|
||||||
@ -1345,6 +1350,9 @@ void ssh2_write_pubkey(FILE *fp, const char *comment,
|
|||||||
int keytype);
|
int keytype);
|
||||||
char *ssh2_fingerprint_blob(ptrlen, FingerprintType);
|
char *ssh2_fingerprint_blob(ptrlen, FingerprintType);
|
||||||
char *ssh2_fingerprint(ssh_key *key, FingerprintType);
|
char *ssh2_fingerprint(ssh_key *key, FingerprintType);
|
||||||
|
char **ssh2_all_fingerprints_for_blob(ptrlen);
|
||||||
|
char **ssh2_all_fingerprints(ssh_key *key);
|
||||||
|
void ssh2_free_all_fingerprints(char **);
|
||||||
int key_type(const Filename *filename);
|
int key_type(const Filename *filename);
|
||||||
int key_type_s(BinarySource *src);
|
int key_type_s(BinarySource *src);
|
||||||
const char *key_type_to_str(int type);
|
const char *key_type_to_str(int type);
|
||||||
|
24
sshpubk.c
24
sshpubk.c
@ -1794,6 +1794,14 @@ char *ssh2_fingerprint_blob(ptrlen blob, FingerprintType fptype)
|
|||||||
return strbuf_to_str(sb);
|
return strbuf_to_str(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char **ssh2_all_fingerprints_for_blob(ptrlen blob)
|
||||||
|
{
|
||||||
|
char **fps = snewn(SSH_N_FPTYPES, char *);
|
||||||
|
for (unsigned i = 0; i < SSH_N_FPTYPES; i++)
|
||||||
|
fps[i] = ssh2_fingerprint_blob(blob, i);
|
||||||
|
return fps;
|
||||||
|
}
|
||||||
|
|
||||||
char *ssh2_fingerprint(ssh_key *data, FingerprintType fptype)
|
char *ssh2_fingerprint(ssh_key *data, FingerprintType fptype)
|
||||||
{
|
{
|
||||||
strbuf *blob = strbuf_new();
|
strbuf *blob = strbuf_new();
|
||||||
@ -1803,6 +1811,22 @@ char *ssh2_fingerprint(ssh_key *data, FingerprintType fptype)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char **ssh2_all_fingerprints(ssh_key *data)
|
||||||
|
{
|
||||||
|
strbuf *blob = strbuf_new();
|
||||||
|
ssh_key_public_blob(data, BinarySink_UPCAST(blob));
|
||||||
|
char **ret = ssh2_all_fingerprints_for_blob(ptrlen_from_strbuf(blob));
|
||||||
|
strbuf_free(blob);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssh2_free_all_fingerprints(char **fps)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < SSH_N_FPTYPES; i++)
|
||||||
|
sfree(fps[i]);
|
||||||
|
sfree(fps);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* Determine the type of a private key file.
|
* Determine the type of a private key file.
|
||||||
*/
|
*/
|
||||||
|
13
sshrsa.c
13
sshrsa.c
@ -319,6 +319,19 @@ char *rsa_ssh1_fingerprint(RSAKey *key)
|
|||||||
return strbuf_to_str(out);
|
return strbuf_to_str(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrap the output of rsa_ssh1_fingerprint up into the same kind of
|
||||||
|
* structure that comes from ssh2_all_fingerprints.
|
||||||
|
*/
|
||||||
|
char **rsa_ssh1_fake_all_fingerprints(RSAKey *key)
|
||||||
|
{
|
||||||
|
char **ret = snewn(SSH_N_FPTYPES, char *);
|
||||||
|
for (unsigned i = 0; i < SSH_N_FPTYPES; i++)
|
||||||
|
ret[i] = NULL;
|
||||||
|
ret[SSH_FPTYPE_MD5] = rsa_ssh1_fingerprint(key);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify that the public data in an RSA key matches the private
|
* Verify that the public data in an RSA key matches the private
|
||||||
* data. We also check the private data itself: we ensure that p >
|
* data. We also check the private data itself: we ensure that p >
|
||||||
|
21
utils.c
21
utils.c
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "ssh.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a string block size specification. This is approximately a
|
* Parse a string block size specification. This is approximately a
|
||||||
@ -1099,3 +1100,23 @@ void memxor(uint8_t *out, const uint8_t *in1, const uint8_t *in2, size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FingerprintType ssh2_pick_fingerprint(
|
||||||
|
char **fingerprints, FingerprintType preferred_type)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Keys are either SSH-2, in which case we have all fingerprint
|
||||||
|
* types, or SSH-1, in which case we have only MD5. So we return
|
||||||
|
* the default type if we can, or MD5 if that's all we have; no
|
||||||
|
* need for a fully general preference-list system.
|
||||||
|
*/
|
||||||
|
FingerprintType fptype = fingerprints[preferred_type] ?
|
||||||
|
preferred_type : SSH_FPTYPE_MD5;
|
||||||
|
assert(fingerprints[fptype]);
|
||||||
|
return fptype;
|
||||||
|
}
|
||||||
|
|
||||||
|
FingerprintType ssh2_pick_default_fingerprint(char **fingerprints)
|
||||||
|
{
|
||||||
|
return ssh2_pick_fingerprint(fingerprints, SSH_FPTYPE_DEFAULT);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user