1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Remove 'keystr' parameter in get_rsa_ssh1_pub.

This parameter returned a substring of the input, which was used for
two purposes. Firstly, it was used to hash the host and server keys
during the initial SSH-1 key setup phase; secondly, it was used to
check the keys in Pageant against the public key blob of a key
specified on the command line.

Unfortunately, those two purposes didn't agree! The first one needs
just the bare key modulus bytes (without even the SSH-1 mpint length
header); the second needs the entire key blob. So, actually, it seems
to have never worked in SSH-1 to say 'putty -i keyfile' and have PuTTY
find that key in Pageant and not have to ask for the passphrase to
decrypt the version on disk.

Fixed by removing that parameter completely, which simplifies all the
_other_ call sites, and replacing it by custom code in those two
places that each does the actually right thing.
This commit is contained in:
Simon Tatham 2018-06-03 08:23:07 +01:00
parent ff11e10d62
commit 7f56e1e365
8 changed files with 27 additions and 31 deletions

View File

@ -813,7 +813,7 @@ int main(int argc, char **argv)
ret = rsa_ssh1_loadpub(infilename, BinarySink_UPCAST(blob),
&origcomment, &error);
BinarySource_BARE_INIT(src, blob->u, blob->len);
get_rsa_ssh1_pub(src, ssh1key, NULL, RSA_SSH1_EXPONENT_FIRST);
get_rsa_ssh1_pub(src, ssh1key, RSA_SSH1_EXPONENT_FIRST);
strbuf_free(blob);
ssh1key->comment = dupstr(origcomment);

View File

@ -243,8 +243,8 @@ struct BinarySource {
BinarySource_get_mp_ssh1(BinarySource_UPCAST(src))
#define get_mp_ssh2(src) \
BinarySource_get_mp_ssh2(BinarySource_UPCAST(src))
#define get_rsa_ssh1_pub(src, rsa, keystr, order) \
BinarySource_get_rsa_ssh1_pub(BinarySource_UPCAST(src), rsa, keystr, order)
#define get_rsa_ssh1_pub(src, rsa, order) \
BinarySource_get_rsa_ssh1_pub(BinarySource_UPCAST(src), rsa, order)
#define get_rsa_ssh1_priv(src, rsa) \
BinarySource_get_rsa_ssh1_priv(BinarySource_UPCAST(src), rsa)

View File

@ -264,7 +264,7 @@ void pageant_handle_msg(BinarySink *bs,
response = NULL;
memset(&reqkey, 0, sizeof(reqkey));
get_rsa_ssh1_pub(msg, &reqkey, NULL, RSA_SSH1_EXPONENT_FIRST);
get_rsa_ssh1_pub(msg, &reqkey, RSA_SSH1_EXPONENT_FIRST);
challenge = get_mp_ssh1(msg);
session_id = get_data(msg, 16);
response_type = get_uint32(msg);
@ -363,7 +363,7 @@ void pageant_handle_msg(BinarySink *bs,
key = snew(struct RSAKey);
memset(key, 0, sizeof(struct RSAKey));
get_rsa_ssh1_pub(msg, key, NULL, RSA_SSH1_MODULUS_FIRST);
get_rsa_ssh1_pub(msg, key, RSA_SSH1_MODULUS_FIRST);
get_rsa_ssh1_priv(msg, key);
/* SSH-1 names p and q the other way round, i.e. we have
@ -486,7 +486,7 @@ void pageant_handle_msg(BinarySink *bs,
plog(logctx, logfn, "request: SSH1_AGENTC_REMOVE_RSA_IDENTITY");
get_rsa_ssh1_pub(msg, &reqkey, NULL, RSA_SSH1_EXPONENT_FIRST);
get_rsa_ssh1_pub(msg, &reqkey, RSA_SSH1_EXPONENT_FIRST);
if (get_err(msg)) {
pageant_failure_msg(bs, "unable to decode request",
@ -1321,7 +1321,7 @@ int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx,
/* public blob and fingerprint */
memset(&rkey, 0, sizeof(rkey));
get_rsa_ssh1_pub(src, &rkey, NULL, RSA_SSH1_EXPONENT_FIRST);
get_rsa_ssh1_pub(src, &rkey, RSA_SSH1_EXPONENT_FIRST);
comment = get_string(src);
if (get_err(src)) {

23
ssh.c
View File

@ -4082,7 +4082,6 @@ static void do_ssh1_login(void *vctx)
int crLine;
int len;
unsigned char *rsabuf;
ptrlen keystr1, keystr2;
unsigned long supported_ciphers_mask, supported_auths_mask;
int tried_publickey, tried_agent;
int tis_auth_refused, ccard_auth_refused;
@ -4123,8 +4122,8 @@ static void do_ssh1_login(void *vctx)
pl = get_data(pktin, 8);
memcpy(s->cookie, pl.ptr, pl.len);
get_rsa_ssh1_pub(pktin, &s->servkey, &s->keystr1, RSA_SSH1_EXPONENT_FIRST);
get_rsa_ssh1_pub(pktin, &s->hostkey, &s->keystr2, RSA_SSH1_EXPONENT_FIRST);
get_rsa_ssh1_pub(pktin, &s->servkey, RSA_SSH1_EXPONENT_FIRST);
get_rsa_ssh1_pub(pktin, &s->hostkey, RSA_SSH1_EXPONENT_FIRST);
/*
* Log the host key fingerprint.
@ -4153,8 +4152,13 @@ static void do_ssh1_login(void *vctx)
ssh->v1_local_protoflags |= SSH1_PROTOFLAG_SCREEN_NUMBER;
MD5Init(&md5c);
put_data(&md5c, s->keystr2.ptr, s->keystr2.len);
put_data(&md5c, s->keystr1.ptr, s->keystr1.len);
{
int i;
for (i = (bignum_bitcount(s->hostkey.modulus) + 7) / 8; i-- ;)
put_byte(&md5c, bignum_byte(s->hostkey.modulus, i));
for (i = (bignum_bitcount(s->servkey.modulus) + 7) / 8; i-- ;)
put_byte(&md5c, bignum_byte(s->servkey.modulus, i));
}
put_data(&md5c, s->cookie, 8);
MD5Final(s->session_id, &md5c);
@ -4496,15 +4500,20 @@ static void do_ssh1_login(void *vctx)
}
logeventf(ssh, "Pageant has %d SSH-1 keys", s->nkeys);
for (s->keyi = 0; s->keyi < s->nkeys; s->keyi++) {
ptrlen keystr;
get_rsa_ssh1_pub(s->asrc, &s->key, &keystr,
size_t start, end;
start = s->asrc->pos;
get_rsa_ssh1_pub(s->asrc, &s->key,
RSA_SSH1_EXPONENT_FIRST);
end = s->asrc->pos;
s->comment = get_string(s->asrc);
if (get_err(s->asrc)) {
logevent("Pageant key list packet was truncated");
break;
}
if (s->publickey_blob) {
ptrlen keystr = make_ptrlen(
(const char *)s->asrc->data + start, end - start);
if (keystr.len == s->publickey_blob->len &&
!memcmp(keystr.ptr, s->publickey_blob->s,
s->publickey_blob->len)) {

3
ssh.h
View File

@ -183,8 +183,7 @@ struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve
typedef enum { RSA_SSH1_EXPONENT_FIRST, RSA_SSH1_MODULUS_FIRST } RsaSsh1Order;
void BinarySource_get_rsa_ssh1_pub(
BinarySource *src, struct RSAKey *result,
ptrlen *keystr, RsaSsh1Order order);
BinarySource *src, struct RSAKey *result, RsaSsh1Order order);
void BinarySource_get_rsa_ssh1_priv(
BinarySource *src, struct RSAKey *rsa);
int rsa_ssh1_encrypt(unsigned char *data, int length, struct RSAKey *key);

View File

@ -65,7 +65,7 @@ static int rsa_ssh1_load_main(FILE * fp, struct RSAKey *key, int pub_only,
goto end; /* reserved field nonzero, panic! */
/* Now the serious stuff. An ordinary SSH-1 public key. */
get_rsa_ssh1_pub(src, key, NULL, RSA_SSH1_MODULUS_FIRST);
get_rsa_ssh1_pub(src, key, RSA_SSH1_MODULUS_FIRST);
/* Next, the comment field. */
comment = get_string(src);

View File

@ -11,31 +11,20 @@
#include "misc.h"
void BinarySource_get_rsa_ssh1_pub(
BinarySource *src, struct RSAKey *rsa, ptrlen *keystr, RsaSsh1Order order)
BinarySource *src, struct RSAKey *rsa, RsaSsh1Order order)
{
const unsigned char *start, *end;
unsigned bits;
Bignum e, m;
bits = get_uint32(src);
if (order == RSA_SSH1_EXPONENT_FIRST) {
e = get_mp_ssh1(src);
start = get_ptr(src);
m = get_mp_ssh1(src);
end = get_ptr(src);
} else {
start = get_ptr(src);
m = get_mp_ssh1(src);
end = get_ptr(src);
e = get_mp_ssh1(src);
}
if (keystr) {
start += (end-start >= 2 ? 2 : end-start);
keystr->ptr = start;
keystr->len = end - start;
}
if (rsa) {
rsa->bits = bits;
rsa->exponent = e;

View File

@ -707,8 +707,7 @@ void run_client(void)
BinarySource_BARE_INIT(src, key->blob->u, key->blob->len);
memset(&rkey, 0, sizeof(rkey));
rkey.comment = dupstr(key->comment);
get_rsa_ssh1_pub(src, &rkey, NULL,
RSA_SSH1_EXPONENT_FIRST);
get_rsa_ssh1_pub(src, &rkey, RSA_SSH1_EXPONENT_FIRST);
ssh1_write_pubkey(fp, &rkey);
freersakey(&rkey);
} else {