1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-12 08:43:53 -05:00

Refactor ecdh_kex into an organised vtable.

This is already slightly nice because it lets me separate the
Weierstrass and Montgomery code more completely, without having to
have a vtable tucked into dh->extra. But more to the point, it will
allow completely different kex methods to fit into the same framework
later.

To that end, I've moved more of the descriptive message generation
into the vtable, and also provided the constructor with a flag that
will let it do different things in client and server.

Also, following on from a previous commit, I've arranged that the new
API returns arbitrary binary data for the exchange hash, rather than
an mp_int. An upcoming implementation of this interface will want to
return an encoded string instead of an encoded mp_int.
This commit is contained in:
Simon Tatham
2022-04-14 07:04:33 +01:00
parent 422a89e208
commit e59ee96554
9 changed files with 207 additions and 168 deletions

41
ssh.h
View File

@ -615,15 +615,6 @@ strbuf *ssh_rsakex_encrypt(
mp_int *ssh_rsakex_decrypt(
RSAKey *key, const ssh_hashalg *h, ptrlen ciphertext);
/*
* SSH2 ECDH key exchange functions
*/
const char *ssh_ecdhkex_curve_textname(const ssh_kex *kex);
ecdh_key *ssh_ecdhkex_newkey(const ssh_kex *kex);
void ssh_ecdhkex_freekey(ecdh_key *key);
void ssh_ecdhkex_getpublic(ecdh_key *key, BinarySink *bs);
mp_int *ssh_ecdhkex_getkey(ecdh_key *key, ptrlen remoteKey);
/*
* Helper function for k generation in DSA, reused in ECDSA
*/
@ -806,6 +797,9 @@ struct ssh_kex {
const char *name, *groupname;
enum { KEXTYPE_DH, KEXTYPE_RSA, KEXTYPE_ECDH, KEXTYPE_GSS } main_type;
const ssh_hashalg *hash;
union { /* publicly visible data for each type */
const ecdh_keyalg *ecdh_vt; /* for KEXTYPE_ECDH */
};
const void *extra; /* private to the kex methods */
};
@ -884,6 +878,35 @@ static inline const char *ssh_key_ssh_id(ssh_key *key)
static inline const char *ssh_key_cache_id(ssh_key *key)
{ return key->vt->cache_id; }
/*
* SSH2 ECDH key exchange vtable
*/
struct ecdh_key {
const ecdh_keyalg *vt;
};
struct ecdh_keyalg {
/* Unusually, the 'new' method here doesn't directly take a vt
* pointer, because it will also need the containing ssh_kex
* structure for top-level parameters, and since that contains a
* vt pointer anyway, we might as well _only_ pass that. */
ecdh_key *(*new)(const ssh_kex *kex, bool is_server);
void (*free)(ecdh_key *key);
void (*getpublic)(ecdh_key *key, BinarySink *bs);
bool (*getkey)(ecdh_key *key, ptrlen remoteKey, BinarySink *bs);
char *(*description)(const ssh_kex *kex);
};
static inline ecdh_key *ecdh_key_new(const ssh_kex *kex, bool is_server)
{ return kex->ecdh_vt->new(kex, is_server); }
static inline void ecdh_key_free(ecdh_key *key)
{ key->vt->free(key); }
static inline void ecdh_key_getpublic(ecdh_key *key, BinarySink *bs)
{ key->vt->getpublic(key, bs); }
static inline bool ecdh_key_getkey(ecdh_key *key, ptrlen remoteKey,
BinarySink *bs)
{ return key->vt->getkey(key, remoteKey, bs); }
static inline char *ecdh_keyalg_description(const ssh_kex *kex)
{ return kex->ecdh_vt->description(kex); }
/*
* Enumeration of signature flags from draft-miller-ssh-agent-02
*/