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

Reorganise ssh_keyalg and use it as a vtable.

After Pavel Kryukov pointed out that I have to put _something_ in the
'ssh_key' structure, I thought of an actually useful thing to put
there: why not make it store a pointer to the ssh_keyalg structure?
Then ssh_key becomes a classoid - or perhaps 'traitoid' is a closer
analogy - in the same style as Socket and Plug. And just like Socket
and Plug, I've also arranged a system of wrapper macros that avoid the
need to mention the 'object' whose method you're invoking twice at
each call site.

The new vtable pointer directly replaces an existing field of struct
ec_key (which was usable by several different ssh_keyalgs, so it
already had to store a pointer to the currently active one), and also
replaces the 'alg' field of the ssh2_userkey structure that wraps up a
cryptographic key with its comment field.

I've also taken the opportunity to clean things up a bit in general:
most of the methods now have new and clearer names (e.g. you'd never
know that 'newkey' made a public-only key while 'createkey' made a
public+private key pair unless you went and looked it up, but now
they're called 'new_pub' and 'new_priv' you might be in with a
chance), and I've completely removed the openssh_private_npieces field
after realising that it was duplicating information that is actually
_more_ conveniently obtained by calling the new_priv_openssh method
(formerly openssh_createkey) and throwing away the result.
This commit is contained in:
Simon Tatham 2018-06-03 12:58:05 +01:00
parent 15bacbf630
commit 06a14fe8b8
14 changed files with 327 additions and 333 deletions

View File

@ -248,7 +248,6 @@ int main(int argc, char **argv)
struct RSAKey *ssh1key = NULL;
strbuf *ssh2blob = NULL;
char *ssh2alg = NULL;
const ssh_keyalg *ssh2algf = NULL;
char *old_passphrase = NULL, *new_passphrase = NULL;
int load_encrypted;
progfn_t progressfn = is_interactive() ? progress_update : no_progress;
@ -722,22 +721,19 @@ int main(int argc, char **argv)
struct dss_key *dsskey = snew(struct dss_key);
dsa_generate(dsskey, bits, progressfn, &prog);
ssh2key = snew(struct ssh2_userkey);
ssh2key->data = &dsskey->sshk;
ssh2key->alg = &ssh_dss;
ssh2key->key = &dsskey->sshk;
ssh1key = NULL;
} else if (keytype == ECDSA) {
struct ec_key *ec = snew(struct ec_key);
ec_generate(ec, bits, progressfn, &prog);
ssh2key = snew(struct ssh2_userkey);
ssh2key->data = &ec->sshk;
ssh2key->alg = ec->signalg;
ssh2key->key = &ec->sshk;
ssh1key = NULL;
} else if (keytype == ED25519) {
struct ec_key *ec = snew(struct ec_key);
ec_edgenerate(ec, bits, progressfn, &prog);
ssh2key = snew(struct ssh2_userkey);
ssh2key->data = &ec->sshk;
ssh2key->alg = &ssh_ecdsa_ed25519;
ssh2key->key = &ec->sshk;
ssh1key = NULL;
} else {
struct RSAKey *rsakey = snew(struct RSAKey);
@ -747,8 +743,7 @@ int main(int argc, char **argv)
ssh1key = rsakey;
} else {
ssh2key = snew(struct ssh2_userkey);
ssh2key->data = &rsakey->sshk;
ssh2key->alg = &ssh_rsa;
ssh2key->key = &rsakey->sshk;
}
}
progressfn(&prog, PROGFN_PROGRESS, INT_MAX, -1);
@ -838,10 +833,10 @@ int main(int argc, char **argv)
ssh2blob = strbuf_new();
if (ssh2_userkey_loadpub(infilename, &ssh2alg, BinarySink_UPCAST(ssh2blob),
&origcomment, &error)) {
ssh2algf = find_pubkey_alg(ssh2alg);
if (ssh2algf)
bits = ssh2algf->pubkey_bits(
ssh2algf, make_ptrlen(ssh2blob->s, ssh2blob->len));
const ssh_keyalg *alg = find_pubkey_alg(ssh2alg);
if (alg)
bits = ssh_key_public_bits(
alg, make_ptrlen(ssh2blob->s, ssh2blob->len));
else
bits = -1;
} else {
@ -995,7 +990,7 @@ int main(int argc, char **argv)
if (!ssh2blob) {
assert(ssh2key);
ssh2blob = strbuf_new();
ssh2key->alg->public_blob(ssh2key->data, BinarySink_UPCAST(ssh2blob));
ssh_key_public_blob(ssh2key->key, BinarySink_UPCAST(ssh2blob));
}
ssh2_write_pubkey(fp, ssh2key ? ssh2key->comment : origcomment,
@ -1020,8 +1015,7 @@ int main(int argc, char **argv)
fingerprint = rsa_ssh1_fingerprint(ssh1key);
} else {
if (ssh2key) {
fingerprint = ssh2_fingerprint(ssh2key->alg,
ssh2key->data);
fingerprint = ssh2_fingerprint(ssh2key->key);
} else {
assert(ssh2blob);
fingerprint = ssh2_fingerprint_blob(
@ -1085,7 +1079,7 @@ int main(int argc, char **argv)
if (ssh1key)
freersakey(ssh1key);
if (ssh2key) {
ssh2key->alg->freekey(ssh2key->data);
ssh_key_free(ssh2key->key);
sfree(ssh2key);
}

131
import.c
View File

@ -502,6 +502,7 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
{
struct openssh_pem_key *key = load_openssh_pem_key(filename, errmsg_p);
struct ssh2_userkey *retkey;
const ssh_keyalg *alg;
BinarySource src[1];
int i, num_integers;
struct ssh2_userkey *retval = NULL;
@ -661,19 +662,18 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
/* Construct the key */
retkey = snew(struct ssh2_userkey);
retkey->alg = alg;
put_stringz(blob, alg->name);
put_stringz(blob, alg->ssh_id);
put_stringz(blob, curve->name);
put_stringpl(blob, pubkey.data);
publen = blob->len;
put_mp_ssh2_from_string(blob, privkey.data.ptr, privkey.data.len);
retkey->data = retkey->alg->createkey(
retkey->alg, make_ptrlen(blob->u, publen),
retkey->key = ssh_key_new_priv(
alg, make_ptrlen(blob->u, publen),
make_ptrlen(blob->u + publen, blob->len - publen));
if (!retkey->data) {
if (!retkey->key) {
sfree(retkey);
errmsg = "unable to create key data structure";
goto error;
@ -740,12 +740,12 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
*/
assert(privptr > 0); /* should have bombed by now if not */
retkey = snew(struct ssh2_userkey);
retkey->alg = (key->keytype == OP_RSA ? &ssh_rsa : &ssh_dss);
retkey->data = retkey->alg->createkey(
retkey->alg, make_ptrlen(blob->u, privptr),
alg = (key->keytype == OP_RSA ? &ssh_rsa : &ssh_dss);
retkey->key = ssh_key_new_priv(
alg, make_ptrlen(blob->u, privptr),
make_ptrlen(blob->u+privptr, blob->len-privptr));
if (!retkey->data) {
if (!retkey->key) {
sfree(retkey);
errmsg = "unable to create key data structure";
goto error;
@ -794,9 +794,9 @@ int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
* Fetch the key blobs.
*/
pubblob = strbuf_new();
key->alg->public_blob(key->data, BinarySink_UPCAST(pubblob));
ssh_key_public_blob(key->key, BinarySink_UPCAST(pubblob));
privblob = strbuf_new();
key->alg->private_blob(key->data, BinarySink_UPCAST(privblob));
ssh_key_private_blob(key->key, BinarySink_UPCAST(privblob));
spareblob = NULL;
outblob = strbuf_new();
@ -805,7 +805,8 @@ int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
* Encode the OpenSSH key blob, and also decide on the header
* line.
*/
if (key->alg == &ssh_rsa || key->alg == &ssh_dss) {
if (ssh_key_alg(key->key) == &ssh_rsa ||
ssh_key_alg(key->key) == &ssh_dss) {
strbuf *seq;
/*
@ -815,7 +816,7 @@ int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
* bignums per key type and then construct the actual blob in
* common code after that.
*/
if (key->alg == &ssh_rsa) {
if (ssh_key_alg(key->key) == &ssh_rsa) {
ptrlen n, e, d, p, q, iqmp, dmp1, dmq1;
Bignum bd, bp, bq, bdmp1, bdmq1;
@ -911,11 +912,11 @@ int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
put_ber_id_len(outblob, 16, seq->len, ASN1_CONSTRUCTED);
put_data(outblob, seq->s, seq->len);
strbuf_free(seq);
} else if (key->alg == &ssh_ecdsa_nistp256 ||
key->alg == &ssh_ecdsa_nistp384 ||
key->alg == &ssh_ecdsa_nistp521) {
} else if (ssh_key_alg(key->key) == &ssh_ecdsa_nistp256 ||
ssh_key_alg(key->key) == &ssh_ecdsa_nistp384 ||
ssh_key_alg(key->key) == &ssh_ecdsa_nistp521) {
const unsigned char *oid;
struct ec_key *ec = FROMFIELD(key->data, struct ec_key, sshk);
struct ec_key *ec = FROMFIELD(key->key, struct ec_key, sshk);
int oidlen;
int pointlen;
strbuf *seq, *sub;
@ -930,7 +931,7 @@ int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
* [1]
* BIT STRING (0x00 public key point)
*/
oid = ec_alg_oid(key->alg, &oidlen);
oid = ec_alg_oid(ssh_key_alg(key->key), &oidlen);
pointlen = (ec->publicKey.curve->fieldBits + 7) / 8 * 2;
seq = strbuf_new();
@ -1340,7 +1341,6 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
{
struct openssh_new_key *key = load_openssh_new_key(filename, errmsg_p);
struct ssh2_userkey *retkey = NULL;
int i;
struct ssh2_userkey *retval = NULL;
const char *errmsg;
unsigned checkint;
@ -1428,56 +1428,42 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
goto error;
}
retkey = NULL;
retkey = snew(struct ssh2_userkey);
retkey->key = NULL;
retkey->comment = NULL;
for (key_index = 0; key_index < key->nkeys; key_index++) {
ptrlen keytype, thiskey, comment;
ptrlen comment;
/*
* Read the key type, which will tell us how to scan over
* the key to get to the next one.
* Identify the key type.
*/
keytype = get_string(src);
/*
* Preliminary key type identification, and decide how
* many pieces of key we expect to see. Currently
* (conveniently) all key types can be seen as some number
* of strings, so we just need to know how many of them to
* skip over. (The numbers below exclude the key comment.)
*/
alg = find_pubkey_alg_len(keytype);
alg = find_pubkey_alg_len(get_string(src));
if (!alg) {
errmsg = "private key type not recognised\n";
goto error;
}
thiskey.ptr = get_ptr(src);
/*
* Skip over the pieces of key.
* Read the key. We have to do this even if it's not the one
* we want, because it's the only way to find out how much
* data to skip past to get to the next key in the file.
*/
for (i = 0; i < alg->openssh_private_npieces; i++)
get_string(src);
retkey->key = ssh_key_new_priv_openssh(alg, src);
if (get_err(src)) {
errmsg = "unable to read entire private key";
goto error;
}
thiskey.len = (const char *)get_ptr(src) - (const char *)thiskey.ptr;
if (key_index == key->key_wanted) {
BinarySource src[1];
BinarySource_BARE_INIT(src, thiskey.ptr, thiskey.len);
retkey = snew(struct ssh2_userkey);
retkey->comment = NULL;
retkey->alg = alg;
retkey->data = alg->openssh_createkey(alg, src);
if (!retkey->data) {
errmsg = "unable to create key data structure";
goto error;
}
if (!retkey->key) {
errmsg = "unable to create key data structure";
goto error;
}
if (key_index != key->key_wanted) {
/*
* If this isn't the key we're looking for, throw it away.
*/
ssh_key_free(retkey->key);
retkey->key = NULL;
}
/*
@ -1518,10 +1504,8 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
error:
if (retkey) {
sfree(retkey->comment);
if (retkey->data) {
assert(alg);
alg->freekey(retkey->data);
}
if (retkey->key)
ssh_key_free(retkey->key);
sfree(retkey);
}
smemclr(key->keyblob, key->keyblob_size);
@ -1547,9 +1531,9 @@ int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
* Fetch the key blobs and find out the lengths of things.
*/
pubblob = strbuf_new();
key->alg->public_blob(key->data, BinarySink_UPCAST(pubblob));
ssh_key_public_blob(key->key, BinarySink_UPCAST(pubblob));
privblob = strbuf_new();
key->alg->openssh_fmtkey(key->data, BinarySink_UPCAST(privblob));
ssh_key_openssh_blob(key->key, BinarySink_UPCAST(privblob));
/*
* Construct the cleartext version of the blob.
@ -1597,7 +1581,7 @@ int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
/* Private key. The main private blob goes inline, with no string
* wrapper. */
put_stringz(cpblob, key->alg->name);
put_stringz(cpblob, ssh_key_ssh_id(key->key));
put_data(cpblob, privblob->s, privblob->len);
/* Comment. */
@ -1669,11 +1653,11 @@ int openssh_auto_write(const Filename *filename, struct ssh2_userkey *key,
* assume that anything not in that fixed list is newer, and hence
* will use the new format.
*/
if (key->alg == &ssh_dss ||
key->alg == &ssh_rsa ||
key->alg == &ssh_ecdsa_nistp256 ||
key->alg == &ssh_ecdsa_nistp384 ||
key->alg == &ssh_ecdsa_nistp521)
if (ssh_key_alg(key->key) == &ssh_dss ||
ssh_key_alg(key->key) == &ssh_rsa ||
ssh_key_alg(key->key) == &ssh_ecdsa_nistp256 ||
ssh_key_alg(key->key) == &ssh_ecdsa_nistp384 ||
ssh_key_alg(key->key) == &ssh_ecdsa_nistp521)
return openssh_pem_write(filename, key, passphrase);
else
return openssh_new_write(filename, key, passphrase);
@ -2117,7 +2101,7 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
/*
* Now we break down into RSA versus DSA. In either case we'll
* construct public and private blobs in our own format, and
* end up feeding them to alg->createkey().
* end up feeding them to ssh_key_new_priv().
*/
blob = strbuf_new();
if (type == RSA) {
@ -2173,11 +2157,10 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
}
retkey = snew(struct ssh2_userkey);
retkey->alg = alg;
retkey->data = alg->createkey(
retkey->key = ssh_key_new_priv(
alg, make_ptrlen(blob->u, publen),
make_ptrlen(blob->u + publen, blob->len - publen));
if (!retkey->data) {
if (!retkey->key) {
sfree(retkey);
errmsg = "unable to create key data structure";
goto error;
@ -2216,16 +2199,16 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
* Fetch the key blobs.
*/
pubblob = strbuf_new();
key->alg->public_blob(key->data, BinarySink_UPCAST(pubblob));
ssh_key_public_blob(key->key, BinarySink_UPCAST(pubblob));
privblob = strbuf_new();
key->alg->private_blob(key->data, BinarySink_UPCAST(privblob));
ssh_key_private_blob(key->key, BinarySink_UPCAST(privblob));
outblob = NULL;
/*
* Find the sequence of integers to be encoded into the OpenSSH
* key blob, and also decide on the header line.
*/
if (key->alg == &ssh_rsa) {
if (ssh_key_alg(key->key) == &ssh_rsa) {
ptrlen n, e, d, p, q, iqmp;
/*
@ -2254,7 +2237,7 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
nnumbers = 6;
initial_zero = 0;
type = "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}";
} else if (key->alg == &ssh_dss) {
} else if (ssh_key_alg(key->key) == &ssh_dss) {
ptrlen p, q, g, y, x;
/*

View File

@ -89,7 +89,7 @@ static int cmpkeys_ssh2_asymm(void *av, void *bv)
* Compare purely by public blob.
*/
bblob = strbuf_new();
b->alg->public_blob(b->data, BinarySink_UPCAST(bblob));
ssh_key_public_blob(b->key, BinarySink_UPCAST(bblob));
c = 0;
for (i = 0; i < ablob->len && i < bblob->len; i++) {
@ -123,7 +123,7 @@ static int cmpkeys_ssh2(void *av, void *bv)
int toret;
ablob = strbuf_new();
a->alg->public_blob(a->data, BinarySink_UPCAST(ablob));
ssh_key_public_blob(a->key, BinarySink_UPCAST(ablob));
apl.ptr = ablob->u;
apl.len = ablob->len;
toret = cmpkeys_ssh2_asymm(&apl, bv);
@ -151,7 +151,7 @@ void pageant_make_keylist2(BinarySink *bs)
put_uint32(bs, count234(ssh2keys));
for (i = 0; NULL != (key = index234(ssh2keys, i)); i++) {
strbuf *blob = strbuf_new();
key->alg->public_blob(key->data, BinarySink_UPCAST(blob));
ssh_key_public_blob(key->key, BinarySink_UPCAST(blob));
put_stringsb(bs, blob);
put_stringz(bs, key->comment);
}
@ -235,8 +235,7 @@ void pageant_handle_msg(BinarySink *bs,
int i;
struct ssh2_userkey *skey;
for (i = 0; NULL != (skey = pageant_nth_ssh2_key(i)); i++) {
char *fingerprint = ssh2_fingerprint(skey->alg,
skey->data);
char *fingerprint = ssh2_fingerprint(skey->key);
plog(logctx, logfn, "returned key: %s %s",
fingerprint, skey->comment);
sfree(fingerprint);
@ -343,8 +342,8 @@ void pageant_handle_msg(BinarySink *bs,
put_byte(bs, SSH2_AGENT_SIGN_RESPONSE);
signature = strbuf_new();
key->alg->sign(key->data, sigdata.ptr, sigdata.len,
BinarySink_UPCAST(signature));
ssh_key_sign(key->key, sigdata.ptr, sigdata.len,
BinarySink_UPCAST(signature));
put_stringsb(bs, signature);
plog(logctx, logfn, "reply: SSH2_AGENT_SIGN_RESPONSE");
@ -416,24 +415,25 @@ void pageant_handle_msg(BinarySink *bs,
*/
{
struct ssh2_userkey *key = NULL;
ptrlen alg;
ptrlen algpl;
const ssh_keyalg *alg;
plog(logctx, logfn, "request: SSH2_AGENTC_ADD_IDENTITY");
alg = get_string(msg);
algpl = get_string(msg);
key = snew(struct ssh2_userkey);
key->data = NULL;
key->key = NULL;
key->comment = NULL;
key->alg = find_pubkey_alg_len(alg);
if (!key->alg) {
alg = find_pubkey_alg_len(algpl);
if (!alg) {
pageant_failure_msg(bs, "algorithm unknown", logctx, logfn);
goto add2_cleanup;
}
key->data = key->alg->openssh_createkey(key->alg, msg);
key->key = ssh_key_new_priv_openssh(alg, msg);
if (!key->data) {
if (!key->key) {
pageant_failure_msg(bs, "key setup failed", logctx, logfn);
goto add2_cleanup;
}
@ -447,7 +447,7 @@ void pageant_handle_msg(BinarySink *bs,
}
if (logfn) {
char *fingerprint = ssh2_fingerprint(key->alg, key->data);
char *fingerprint = ssh2_fingerprint(key->key);
plog(logctx, logfn, "submitted key: %s %s",
fingerprint, key->comment);
sfree(fingerprint);
@ -467,8 +467,8 @@ void pageant_handle_msg(BinarySink *bs,
add2_cleanup:
if (key) {
if (key->data)
key->alg->freekey(key->data);
if (key->key)
ssh_key_free(key->key);
if (key->comment)
sfree(key->comment);
sfree(key);
@ -558,7 +558,7 @@ void pageant_handle_msg(BinarySink *bs,
del234(ssh2keys, key);
keylist_update();
key->alg->freekey(key->data);
ssh_key_free(key->key);
sfree(key->comment);
sfree(key);
put_byte(bs, SSH_AGENT_SUCCESS);
@ -599,7 +599,7 @@ void pageant_handle_msg(BinarySink *bs,
while ((skey = index234(ssh2keys, 0)) != NULL) {
del234(ssh2keys, skey);
skey->alg->freekey(skey->data);
ssh_key_free(skey->key);
sfree(skey->comment);
sfree(skey);
}
@ -1274,8 +1274,8 @@ int pageant_add_keyfile(Filename *filename, const char *passphrase,
request = strbuf_new_for_agent_query();
put_byte(request, SSH2_AGENTC_ADD_IDENTITY);
put_stringz(request, skey->alg->name);
skey->alg->openssh_fmtkey(skey->data, BinarySink_UPCAST(request));
put_stringz(request, ssh_key_ssh_id(skey->key));
ssh_key_openssh_blob(skey->key, BinarySink_UPCAST(request));
put_stringz(request, skey->comment);
agent_query_synchronous(request, &vresponse, &resplen);
strbuf_free(request);
@ -1291,7 +1291,7 @@ int pageant_add_keyfile(Filename *filename, const char *passphrase,
sfree(response);
} else {
if (!pageant_add_ssh2_key(skey)) {
skey->alg->freekey(skey->data);
ssh_key_free(skey->key);
sfree(skey); /* already present, don't waste RAM */
}
}

129
ssh.c
View File

@ -903,7 +903,7 @@ struct ssh_tag {
const struct ssh_compress *cscomp, *sccomp;
void *cs_comp_ctx, *sc_comp_ctx;
const struct ssh_kex *kex;
const ssh_keyalg *hostkey;
const ssh_keyalg *hostkey_alg;
char *hostkey_str; /* string representation, for easy checking in rekeys */
unsigned char v2_session_id[SSH2_KEX_MAX_HASH_LEN];
int v2_session_id_len;
@ -4008,9 +4008,7 @@ static void ssh_disconnect(Ssh ssh, const char *client_reason,
sfree(error);
}
int verify_ssh_manual_host_key(Ssh ssh, const char *fingerprint,
const ssh_keyalg *ssh2keytype,
void *ssh2keydata)
int verify_ssh_manual_host_key(Ssh ssh, const char *fingerprint, ssh_key *key)
{
if (!conf_get_str_nthstrkey(ssh->conf, CONF_ssh_manual_hostkeys, 0)) {
return -1; /* no manual keys configured */
@ -4035,7 +4033,7 @@ int verify_ssh_manual_host_key(Ssh ssh, const char *fingerprint,
return 1; /* success */
}
if (ssh2keydata) {
if (key) {
/*
* Construct the base64-encoded public key blob and see if
* that's listed.
@ -4044,7 +4042,7 @@ int verify_ssh_manual_host_key(Ssh ssh, const char *fingerprint,
char *base64blob;
int atoms, i;
binblob = strbuf_new();
ssh2keytype->public_blob(ssh2keydata, BinarySink_UPCAST(binblob));
ssh_key_public_blob(key, BinarySink_UPCAST(binblob));
atoms = (binblob->len + 2) / 3;
base64blob = snewn(atoms * 4 + 1, char);
for (i = 0; i < atoms; i++)
@ -4193,7 +4191,7 @@ static void do_ssh1_login(void *vctx)
fingerprint = rsa_ssh1_fingerprint(&s->hostkey);
/* First check against manually configured host keys. */
s->dlgret = verify_ssh_manual_host_key(ssh, fingerprint, NULL, NULL);
s->dlgret = verify_ssh_manual_host_key(ssh, fingerprint, NULL);
sfree(fingerprint);
if (s->dlgret == 0) { /* did not match */
bombout(("Host key did not appear in manually configured list"));
@ -6349,7 +6347,7 @@ static int ssh_transient_hostkey_cache_cmp(void *av, void *bv)
const struct ssh_transient_hostkey_cache_entry
*a = (const struct ssh_transient_hostkey_cache_entry *)av,
*b = (const struct ssh_transient_hostkey_cache_entry *)bv;
return strcmp(a->alg->name, b->alg->name);
return strcmp(a->alg->ssh_id, b->alg->ssh_id);
}
static int ssh_transient_hostkey_cache_find(void *av, void *bv)
@ -6357,7 +6355,7 @@ static int ssh_transient_hostkey_cache_find(void *av, void *bv)
const ssh_keyalg *aalg = (const ssh_keyalg *)av;
const struct ssh_transient_hostkey_cache_entry
*b = (const struct ssh_transient_hostkey_cache_entry *)bv;
return strcmp(aalg->name, b->alg->name);
return strcmp(aalg->ssh_id, b->alg->ssh_id);
}
static void ssh_init_transient_hostkey_store(Ssh ssh)
@ -6376,35 +6374,33 @@ static void ssh_cleanup_transient_hostkey_store(Ssh ssh)
freetree234(ssh->transient_hostkey_cache);
}
static void ssh_store_transient_hostkey(
Ssh ssh, const ssh_keyalg *alg, ssh_key *key)
static void ssh_store_transient_hostkey(Ssh ssh, ssh_key *key)
{
struct ssh_transient_hostkey_cache_entry *ent, *retd;
if ((ent = find234(ssh->transient_hostkey_cache, (void *)alg,
if ((ent = find234(ssh->transient_hostkey_cache, (void *)ssh_key_alg(key),
ssh_transient_hostkey_cache_find)) != NULL) {
strbuf_free(ent->pub_blob);
sfree(ent);
}
ent = snew(struct ssh_transient_hostkey_cache_entry);
ent->alg = alg;
ent->alg = ssh_key_alg(key);
ent->pub_blob = strbuf_new();
alg->public_blob(key, BinarySink_UPCAST(ent->pub_blob));
ssh_key_public_blob(key, BinarySink_UPCAST(ent->pub_blob));
retd = add234(ssh->transient_hostkey_cache, ent);
assert(retd == ent);
}
static int ssh_verify_transient_hostkey(
Ssh ssh, const ssh_keyalg *alg, ssh_key *key)
static int ssh_verify_transient_hostkey(Ssh ssh, ssh_key *key)
{
struct ssh_transient_hostkey_cache_entry *ent;
int toret = FALSE;
if ((ent = find234(ssh->transient_hostkey_cache, (void *)alg,
if ((ent = find234(ssh->transient_hostkey_cache, (void *)ssh_key_alg(key),
ssh_transient_hostkey_cache_find)) != NULL) {
strbuf *this_blob = strbuf_new();
alg->public_blob(key, BinarySink_UPCAST(this_blob));
ssh_key_public_blob(key, BinarySink_UPCAST(this_blob));
if (this_blob->len == ent->pub_blob->len &&
!memcmp(this_blob->s, ent->pub_blob->s,
@ -6726,9 +6722,9 @@ static void do_ssh2_transport(void *vctx)
if (hostkey_algs[j].id != s->preferred_hk[i])
continue;
if (have_ssh_host_key(ssh->savedhost, ssh->savedport,
hostkey_algs[j].alg->keytype)) {
hostkey_algs[j].alg->cache_id)) {
alg = ssh2_kexinit_addalg(s->kexlists[KEXLIST_HOSTKEY],
hostkey_algs[j].alg->name);
hostkey_algs[j].alg->ssh_id);
alg->u.hk.hostkey = hostkey_algs[j].alg;
alg->u.hk.warn = warn;
}
@ -6742,7 +6738,7 @@ static void do_ssh2_transport(void *vctx)
if (hostkey_algs[j].id != s->preferred_hk[i])
continue;
alg = ssh2_kexinit_addalg(s->kexlists[KEXLIST_HOSTKEY],
hostkey_algs[j].alg->name);
hostkey_algs[j].alg->ssh_id);
alg->u.hk.hostkey = hostkey_algs[j].alg;
alg->u.hk.warn = warn;
}
@ -6770,7 +6766,7 @@ static void do_ssh2_transport(void *vctx)
continue;
if (ssh_have_transient_hostkey(ssh, hostkey_algs[j].alg)) {
alg = ssh2_kexinit_addalg(s->kexlists[KEXLIST_HOSTKEY],
hostkey_algs[j].alg->name);
hostkey_algs[j].alg->ssh_id);
alg->u.hk.hostkey = hostkey_algs[j].alg;
alg->u.hk.warn = warn;
}
@ -6787,8 +6783,8 @@ static void do_ssh2_transport(void *vctx)
*/
assert(ssh->kex);
alg = ssh2_kexinit_addalg(s->kexlists[KEXLIST_HOSTKEY],
ssh->hostkey->name);
alg->u.hk.hostkey = ssh->hostkey;
ssh->hostkey_alg->ssh_id);
alg->u.hk.hostkey = ssh->hostkey_alg;
alg->u.hk.warn = FALSE;
}
if (s->can_gssapi_keyex) {
@ -6907,7 +6903,7 @@ static void do_ssh2_transport(void *vctx)
crStopV;
}
ssh->kex = NULL;
ssh->hostkey = NULL;
ssh->hostkey_alg = NULL;
s->cscipher_tobe = NULL;
s->sccipher_tobe = NULL;
s->csmac_tobe = NULL;
@ -6969,7 +6965,7 @@ static void do_ssh2_transport(void *vctx)
if (alg->u.hk.hostkey == NULL &&
ssh->kex->main_type != KEXTYPE_GSS)
continue;
ssh->hostkey = alg->u.hk.hostkey;
ssh->hostkey_alg = alg->u.hk.hostkey;
s->warn_hk = alg->u.hk.warn;
} else if (i == KEXLIST_CSCIPHER) {
s->cscipher_tobe = alg->u.cipher.cipher;
@ -7019,11 +7015,11 @@ static void do_ssh2_transport(void *vctx)
ssh->n_uncert_hostkeys = 0;
for (j = 0; j < lenof(hostkey_algs); j++) {
if (hostkey_algs[j].alg != ssh->hostkey &&
in_commasep_string(hostkey_algs[j].alg->name,
if (hostkey_algs[j].alg != ssh->hostkey_alg &&
in_commasep_string(hostkey_algs[j].alg->ssh_id,
str.ptr, str.len) &&
!have_ssh_host_key(ssh->savedhost, ssh->savedport,
hostkey_algs[j].alg->keytype)) {
hostkey_algs[j].alg->cache_id)) {
ssh->uncert_hostkeys[ssh->n_uncert_hostkeys++] = j;
}
}
@ -7096,21 +7092,21 @@ static void do_ssh2_transport(void *vctx)
if (betteralgs) {
char *old_ba = betteralgs;
betteralgs = dupcat(betteralgs, ",",
hktype->alg->name,
hktype->alg->ssh_id,
(const char *)NULL);
sfree(old_ba);
} else {
betteralgs = dupstr(hktype->alg->name);
betteralgs = dupstr(hktype->alg->ssh_id);
}
}
}
if (betteralgs) {
s->dlgret = askhk(ssh->frontend, ssh->hostkey->name,
s->dlgret = askhk(ssh->frontend, ssh->hostkey_alg->ssh_id,
betteralgs, ssh_dialog_callback, ssh);
sfree(betteralgs);
} else {
s->dlgret = askalg(ssh->frontend, "host key type",
ssh->hostkey->name,
ssh->hostkey_alg->ssh_id,
ssh_dialog_callback, ssh);
}
if (s->dlgret < 0) {
@ -7257,7 +7253,7 @@ static void do_ssh2_transport(void *vctx)
}
set_busy_status(ssh->frontend, BUSY_CPU); /* cogitate */
s->hostkeydata = get_string(pktin);
s->hkey = ssh->hostkey->newkey(ssh->hostkey, s->hostkeydata);
s->hkey = ssh_key_new_pub(ssh->hostkey_alg, s->hostkeydata);
s->f = get_mp_ssh2(pktin);
s->sigdata = get_string(pktin);
if (get_err(pktin)) {
@ -7328,7 +7324,7 @@ static void do_ssh2_transport(void *vctx)
s->hostkeydata = get_string(pktin);
put_stringpl(ssh->exhash_bs, s->hostkeydata);
s->hkey = ssh->hostkey->newkey(ssh->hostkey, s->hostkeydata);
s->hkey = ssh_key_new_pub(ssh->hostkey_alg, s->hostkeydata);
{
strbuf *pubpoint = strbuf_new();
@ -7530,9 +7526,9 @@ static void do_ssh2_transport(void *vctx)
break;
case SSH2_MSG_KEXGSS_HOSTKEY:
s->hostkeydata = get_string(pktin);
if (ssh->hostkey) {
s->hkey = ssh->hostkey->newkey(ssh->hostkey,
s->hostkeydata);
if (ssh->hostkey_alg) {
s->hkey = ssh_key_new_pub(ssh->hostkey_alg,
s->hostkeydata);
put_string(ssh->exhash_bs,
s->hostkeydata.ptr, s->hostkeydata.len);
}
@ -7626,7 +7622,7 @@ static void do_ssh2_transport(void *vctx)
s->hostkeydata = get_string(pktin);
put_stringpl(ssh->exhash_bs, s->hostkeydata);
s->hkey = ssh->hostkey->newkey(ssh->hostkey, s->hostkeydata);
s->hkey = ssh_key_new_pub(ssh->hostkey_alg, s->hostkeydata);
rsakeydata = get_string(pktin);
@ -7765,7 +7761,7 @@ static void do_ssh2_transport(void *vctx)
crStopV;
}
if (!ssh->hostkey->verifysig(
if (!ssh_key_verify(
s->hkey, s->sigdata,
make_ptrlen(s->exchange_hash, ssh->kex->hash->hlen))) {
#ifndef FUZZING
@ -7776,8 +7772,7 @@ static void do_ssh2_transport(void *vctx)
}
}
s->keystr = (ssh->hostkey && s->hkey ?
ssh->hostkey->fmtkey(s->hkey) : NULL);
s->keystr = (s->hkey ? ssh_key_cache_str(s->hkey) : NULL);
#ifndef NO_GSSAPI
if (ssh->gss_kex_used) {
/*
@ -7792,12 +7787,12 @@ static void do_ssh2_transport(void *vctx)
* host key, store it.
*/
if (s->hkey) {
s->fingerprint = ssh2_fingerprint(ssh->hostkey, s->hkey);
s->fingerprint = ssh2_fingerprint(s->hkey);
logevent("GSS kex provided fallback host key:");
logevent(s->fingerprint);
sfree(s->fingerprint);
s->fingerprint = NULL;
ssh_store_transient_hostkey(ssh, ssh->hostkey, s->hkey);
ssh_store_transient_hostkey(ssh, s->hkey);
} else if (!ssh_have_any_transient_hostkey(ssh)) {
/*
* But if it didn't, then we currently have no
@ -7812,7 +7807,7 @@ static void do_ssh2_transport(void *vctx)
* startup, and only add the key to the transient
* cache.
*/
if (ssh->hostkey) {
if (ssh->hostkey_alg) {
s->need_gss_transient_hostkey = TRUE;
} else {
/*
@ -7850,15 +7845,14 @@ static void do_ssh2_transport(void *vctx)
* triggered on purpose to populate the transient cache.
*/
assert(s->hkey); /* only KEXTYPE_GSS lets this be null */
s->fingerprint = ssh2_fingerprint(ssh->hostkey, s->hkey);
s->fingerprint = ssh2_fingerprint(s->hkey);
if (s->need_gss_transient_hostkey) {
logevent("Post-GSS rekey provided fallback host key:");
logevent(s->fingerprint);
ssh_store_transient_hostkey(ssh, ssh->hostkey, s->hkey);
ssh_store_transient_hostkey(ssh, s->hkey);
s->need_gss_transient_hostkey = FALSE;
} else if (!ssh_verify_transient_hostkey(
ssh, ssh->hostkey, s->hkey)) {
} else if (!ssh_verify_transient_hostkey(ssh, s->hkey)) {
logevent("Non-GSS rekey after initial GSS kex "
"used host key:");
logevent(s->fingerprint);
@ -7878,7 +7872,7 @@ static void do_ssh2_transport(void *vctx)
int i, j, nkeys = 0;
char *list = NULL;
for (i = 0; i < lenof(hostkey_algs); i++) {
if (hostkey_algs[i].alg == ssh->hostkey)
if (hostkey_algs[i].alg == ssh->hostkey_alg)
continue;
for (j = 0; j < ssh->n_uncert_hostkeys; j++)
@ -7889,9 +7883,9 @@ static void do_ssh2_transport(void *vctx)
char *newlist;
if (list)
newlist = dupprintf("%s/%s", list,
hostkey_algs[i].alg->name);
hostkey_algs[i].alg->ssh_id);
else
newlist = dupprintf("%s", hostkey_algs[i].alg->name);
newlist = dupprintf("%s", hostkey_algs[i].alg->ssh_id);
sfree(list);
list = newlist;
nkeys++;
@ -7911,12 +7905,11 @@ static void do_ssh2_transport(void *vctx)
* Authenticate remote host: verify host key. (We've already
* checked the signature of the exchange hash.)
*/
s->fingerprint = ssh2_fingerprint(ssh->hostkey, s->hkey);
s->fingerprint = ssh2_fingerprint(s->hkey);
logevent("Host key fingerprint is:");
logevent(s->fingerprint);
/* First check against manually configured host keys. */
s->dlgret = verify_ssh_manual_host_key(ssh, s->fingerprint,
ssh->hostkey, s->hkey);
s->dlgret = verify_ssh_manual_host_key(ssh, s->fingerprint, s->hkey);
if (s->dlgret == 0) { /* did not match */
bombout(("Host key did not appear in manually configured list"));
crStopV;
@ -7924,8 +7917,8 @@ static void do_ssh2_transport(void *vctx)
ssh_set_frozen(ssh, 1);
s->dlgret = verify_ssh_host_key(ssh->frontend,
ssh->savedhost, ssh->savedport,
ssh->hostkey->keytype, s->keystr,
s->fingerprint,
ssh_key_cache_id(s->hkey),
s->keystr, s->fingerprint,
ssh_dialog_callback, ssh);
#ifdef FUZZING
s->dlgret = 1;
@ -7950,12 +7943,12 @@ static void do_ssh2_transport(void *vctx)
ssh->hostkey_str = s->keystr;
s->keystr = NULL;
} else if (ssh->cross_certifying) {
s->fingerprint = ssh2_fingerprint(ssh->hostkey, s->hkey);
s->fingerprint = ssh2_fingerprint(s->hkey);
logevent("Storing additional host key for this host:");
logevent(s->fingerprint);
sfree(s->fingerprint);
store_host_key(ssh->savedhost, ssh->savedport,
ssh->hostkey->keytype, s->keystr);
ssh_key_cache_id(s->hkey), s->keystr);
ssh->cross_certifying = FALSE;
/*
* Don't forget to store the new key as the one we'll be
@ -7979,7 +7972,7 @@ static void do_ssh2_transport(void *vctx)
}
sfree(s->keystr);
if (s->hkey) {
ssh->hostkey->freekey(s->hkey);
ssh_key_free(s->hkey);
s->hkey = NULL;
}
@ -10505,9 +10498,9 @@ static void do_ssh2_userauth(void *vctx)
/* service requested */
put_stringz(s->pktout, "publickey"); /* method */
put_bool(s->pktout, TRUE); /* signature follows */
put_stringz(s->pktout, key->alg->name);
put_stringz(s->pktout, ssh_key_ssh_id(key->key));
pkblob = strbuf_new();
key->alg->public_blob(key->data, BinarySink_UPCAST(pkblob));
ssh_key_public_blob(key->key, BinarySink_UPCAST(pkblob));
put_string(s->pktout, pkblob->s, pkblob->len);
/*
@ -10529,8 +10522,8 @@ static void do_ssh2_userauth(void *vctx)
put_data(sigdata, s->pktout->data + 5,
s->pktout->length - 5);
sigblob = strbuf_new();
key->alg->sign(key->data, sigdata->s, sigdata->len,
BinarySink_UPCAST(sigblob));
ssh_key_sign(key->key, sigdata->s, sigdata->len,
BinarySink_UPCAST(sigblob));
strbuf_free(sigdata);
ssh2_add_sigblob(ssh, s->pktout, pkblob->s, pkblob->len,
sigblob->s, sigblob->len);
@ -10540,7 +10533,7 @@ static void do_ssh2_userauth(void *vctx)
ssh2_pkt_send(ssh, s->pktout);
logevent("Sent public key signature");
s->type = AUTH_TYPE_PUBLICKEY;
key->alg->freekey(key->data);
ssh_key_free(key->key);
sfree(key->comment);
sfree(key);
}
@ -12021,7 +12014,7 @@ static const char *ssh_init(void *frontend_handle, void **backend_handle,
ssh->sc_comp_ctx = NULL;
ssh->kex = NULL;
ssh->kex_ctx = NULL;
ssh->hostkey = NULL;
ssh->hostkey_alg = NULL;
ssh->hostkey_str = NULL;
ssh->exitcode = -1;
ssh->close_expected = FALSE;
@ -12538,7 +12531,7 @@ static const struct telnet_special *ssh_get_specials(void *handle)
struct telnet_special uncert[1];
const ssh_keyalg *alg =
hostkey_algs[ssh->uncert_hostkeys[i]].alg;
uncert[0].name = alg->name;
uncert[0].name = alg->ssh_id;
uncert[0].code = TS_LOCALSTART + ssh->uncert_hostkeys[i];
ADD_SPECIALS(uncert);
}
@ -12607,7 +12600,7 @@ static void ssh_special(void *handle, Telnet_Special code)
queue_idempotent_callback(&ssh->ssh2_transport_icb);
}
} else if (code >= TS_LOCALSTART) {
ssh->hostkey = hostkey_algs[code - TS_LOCALSTART].alg;
ssh->hostkey_alg = hostkey_algs[code - TS_LOCALSTART].alg;
ssh->cross_certifying = TRUE;
if (!ssh->kex_in_progress && !ssh->bare_connection &&
ssh->version == 2) {

67
ssh.h
View File

@ -77,11 +77,8 @@ void share_setup_x11_channel(void *csv, void *chanv,
typedef void *Bignum;
#endif
typedef struct ssh_key {
int dummy;
} ssh_key;
typedef struct ssh_keyalg ssh_keyalg;
typedef const struct ssh_keyalg *ssh_key;
struct RSAKey {
int bits;
@ -164,10 +161,9 @@ int ec_ed_alg_and_curve_by_bits(int bits,
const ssh_keyalg **alg);
struct ec_key {
const ssh_keyalg *signalg;
struct ec_point publicKey;
Bignum privateKey;
struct ssh_key sshk;
ssh_key sshk;
};
struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve);
@ -391,31 +387,47 @@ struct ssh_kexes {
};
struct ssh_keyalg {
ssh_key *(*newkey) (const ssh_keyalg *self, ptrlen data);
/* Constructors that create an ssh_key */
ssh_key *(*new_pub) (const ssh_keyalg *self, ptrlen pub);
ssh_key *(*new_priv) (const ssh_keyalg *self, ptrlen pub, ptrlen priv);
ssh_key *(*new_priv_openssh) (const ssh_keyalg *self, BinarySource *);
/* Methods that operate on an existing ssh_key */
void (*freekey) (ssh_key *key);
char *(*fmtkey) (ssh_key *key);
void (*sign) (ssh_key *key, const void *data, int datalen, BinarySink *);
int (*verify) (ssh_key *key, ptrlen sig, ptrlen data);
void (*public_blob)(ssh_key *key, BinarySink *);
void (*private_blob)(ssh_key *key, BinarySink *);
ssh_key *(*createkey) (const ssh_keyalg *self, ptrlen pub, ptrlen priv);
ssh_key *(*openssh_createkey) (const ssh_keyalg *self, BinarySource *);
void (*openssh_fmtkey) (ssh_key *key, BinarySink *);
/* OpenSSH private key blobs, as created by openssh_fmtkey and
* consumed by openssh_createkey, always (at least so far...) take
* the form of a number of SSH-2 strings / mpints concatenated
* end-to-end. Because the new-style OpenSSH private key format
* stores those blobs without a containing string wrapper, we need
* to know how many strings each one consists of, so that we can
* skip over the right number to find the next key in the file.
* openssh_private_npieces gives that information. */
int openssh_private_npieces;
void (*openssh_blob) (ssh_key *key, BinarySink *);
char *(*cache_str) (ssh_key *key);
/* 'Class methods' that don't deal with an ssh_key at all */
int (*pubkey_bits) (const ssh_keyalg *self, ptrlen blob);
int (*verifysig) (ssh_key *key, ptrlen sig, ptrlen data);
void (*sign) (ssh_key *key, const void *data, int datalen, BinarySink *);
const char *name;
const char *keytype; /* for host key cache */
const void *extra; /* private to the public key methods */
/* Constant data fields giving information about the key type */
const char *ssh_id; /* string identifier in the SSH protocol */
const char *cache_id; /* identifier used in PuTTY's host key cache */
const void *extra; /* private to the public key methods */
};
#define ssh_key_new_pub(alg, data) ((alg)->new_pub(alg, data))
#define ssh_key_new_priv(alg, pub, priv) ((alg)->new_priv(alg, pub, priv))
#define ssh_key_new_priv_openssh(alg, bs) ((alg)->new_priv_openssh(alg, bs))
#define ssh_key_free(key) ((*(key))->freekey(key))
#define ssh_key_sign(key, data, len, bs) ((*(key))->sign(key, data, len, bs))
#define ssh_key_verify(key, sig, data) ((*(key))->verify(key, sig, data))
#define ssh_key_public_blob(key, bs) ((*(key))->public_blob(key, bs))
#define ssh_key_private_blob(key, bs) ((*(key))->private_blob(key, bs))
#define ssh_key_openssh_blob(key, bs) ((*(key))->openssh_blob(key, bs))
#define ssh_key_cache_str(key) ((*(key))->cache_str(key))
#define ssh_key_public_bits(alg, blob) ((alg)->pubkey_bits(alg, blob))
#define ssh_key_alg(key) (*(key))
#define ssh_key_ssh_id(key) ((*(key))->ssh_id)
#define ssh_key_cache_id(key) ((*(key))->cache_id)
struct ssh_compress {
const char *name;
/* For zlib@openssh.com: if non-NULL, this name will be considered once
@ -434,8 +446,7 @@ struct ssh_compress {
};
struct ssh2_userkey {
const ssh_keyalg *alg; /* the key algorithm */
ssh_key *data; /* the key data */
ssh_key *key; /* the key itself */
char *comment; /* the key comment */
};
@ -782,7 +793,7 @@ void ssh2_write_pubkey(FILE *fp, const char *comment,
const void *v_pub_blob, int pub_len,
int keytype);
char *ssh2_fingerprint_blob(const void *blob, int bloblen);
char *ssh2_fingerprint(const ssh_keyalg *alg, ssh_key *key);
char *ssh2_fingerprint(ssh_key *key);
int key_type(const Filename *filename);
const char *key_type_to_str(int type);

View File

@ -11,7 +11,7 @@
static void dss_freekey(ssh_key *key); /* forward reference */
static ssh_key *dss_newkey(const ssh_keyalg *self, ptrlen data)
static ssh_key *dss_new_pub(const ssh_keyalg *self, ptrlen data)
{
BinarySource src[1];
struct dss_key *dss;
@ -21,6 +21,7 @@ static ssh_key *dss_newkey(const ssh_keyalg *self, ptrlen data)
return NULL;
dss = snew(struct dss_key);
dss->sshk = &ssh_dss;
dss->p = get_mp_ssh2(src);
dss->q = get_mp_ssh2(src);
dss->g = get_mp_ssh2(src);
@ -53,7 +54,7 @@ static void dss_freekey(ssh_key *key)
sfree(dss);
}
static char *dss_fmtkey(ssh_key *key)
static char *dss_cache_str(ssh_key *key)
{
struct dss_key *dss = FROMFIELD(key, struct dss_key, sshk);
char *p;
@ -103,7 +104,7 @@ static char *dss_fmtkey(ssh_key *key)
return p;
}
static int dss_verifysig(ssh_key *key, ptrlen sig, ptrlen data)
static int dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
{
struct dss_key *dss = FROMFIELD(key, struct dss_key, sshk);
BinarySource src[1];
@ -221,7 +222,7 @@ static void dss_private_blob(ssh_key *key, BinarySink *bs)
put_mp_ssh2(bs, dss->x);
}
static ssh_key *dss_createkey(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
static ssh_key *dss_new_priv(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
{
BinarySource src[1];
ssh_key *sshk;
@ -231,7 +232,7 @@ static ssh_key *dss_createkey(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
unsigned char digest[20];
Bignum ytest;
sshk = dss_newkey(self, pub);
sshk = dss_new_pub(self, pub);
if (!sshk)
return NULL;
@ -273,12 +274,13 @@ static ssh_key *dss_createkey(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
return &dss->sshk;
}
static ssh_key *dss_openssh_createkey(const ssh_keyalg *self,
BinarySource *src)
static ssh_key *dss_new_priv_openssh(const ssh_keyalg *self,
BinarySource *src)
{
struct dss_key *dss;
dss = snew(struct dss_key);
dss->sshk = &ssh_dss;
dss->p = get_mp_ssh2(src);
dss->q = get_mp_ssh2(src);
@ -296,7 +298,7 @@ static ssh_key *dss_openssh_createkey(const ssh_keyalg *self,
return &dss->sshk;
}
static void dss_openssh_fmtkey(ssh_key *key, BinarySink *bs)
static void dss_openssh_blob(ssh_key *key, BinarySink *bs)
{
struct dss_key *dss = FROMFIELD(key, struct dss_key, sshk);
@ -313,7 +315,7 @@ static int dss_pubkey_bits(const ssh_keyalg *self, ptrlen pub)
struct dss_key *dss;
int ret;
sshk = dss_newkey(self, pub);
sshk = dss_new_pub(self, pub);
if (!sshk)
return -1;
@ -485,18 +487,20 @@ static void dss_sign(ssh_key *key, const void *data, int datalen,
}
const ssh_keyalg ssh_dss = {
dss_newkey,
dss_new_pub,
dss_new_priv,
dss_new_priv_openssh,
dss_freekey,
dss_fmtkey,
dss_sign,
dss_verify,
dss_public_blob,
dss_private_blob,
dss_createkey,
dss_openssh_createkey,
dss_openssh_fmtkey,
5 /* p,q,g,y,x */,
dss_openssh_blob,
dss_cache_str,
dss_pubkey_bits,
dss_verifysig,
dss_sign,
"ssh-dss",
"dss",
NULL,

View File

@ -12,6 +12,8 @@ int dsa_generate(struct dss_key *key, int bits, progfn_t pfn,
unsigned pfirst, qfirst;
int progress;
key->sshk = &ssh_dss;
/*
* Set up the phase limits for the progress report. We do this
* by passing minus the phase number.

119
sshecc.c
View File

@ -1713,7 +1713,7 @@ static void ecdsa_freekey(ssh_key *key)
sfree(ec);
}
static ssh_key *ecdsa_newkey(const ssh_keyalg *self, ptrlen data)
static ssh_key *ecdsa_new_pub(const ssh_keyalg *self, ptrlen data)
{
const struct ecsign_extra *extra =
(const struct ecsign_extra *)self->extra;
@ -1734,8 +1734,8 @@ static ssh_key *ecdsa_newkey(const ssh_keyalg *self, ptrlen data)
}
ec = snew(struct ec_key);
ec->sshk = self;
ec->signalg = self;
ec->publicKey.curve = curve;
ec->publicKey.infinity = 0;
ec->publicKey.x = NULL;
@ -1758,7 +1758,7 @@ static ssh_key *ecdsa_newkey(const ssh_keyalg *self, ptrlen data)
return &ec->sshk;
}
static char *ecdsa_fmtkey(ssh_key *key)
static char *ecdsa_cache_str(ssh_key *key)
{
struct ec_key *ec = FROMFIELD(key, struct ec_key, sshk);
char *p;
@ -1810,7 +1810,7 @@ static void ecdsa_public_blob(ssh_key *key, BinarySink *bs)
assert(pointlen >= 2);
put_stringz(bs, ec->signalg->name);
put_stringz(bs, ec->sshk->ssh_id);
put_uint32(bs, pointlen);
/* Unset last bit of y and set first bit of x in its place */
@ -1824,7 +1824,7 @@ static void ecdsa_public_blob(ssh_key *key, BinarySink *bs)
pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
put_stringz(bs, ec->signalg->name);
put_stringz(bs, ec->sshk->ssh_id);
put_stringz(bs, ec->publicKey.curve->name);
put_uint32(bs, (2 * pointlen) + 1);
put_byte(bs, 0x04);
@ -1864,15 +1864,14 @@ static void ecdsa_private_blob(ssh_key *key, BinarySink *bs)
}
}
static ssh_key *ecdsa_createkey(const ssh_keyalg *self,
ptrlen pub, ptrlen priv)
static ssh_key *ecdsa_new_priv(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
{
BinarySource src[1];
ssh_key *sshk;
struct ec_key *ec;
struct ec_point *publicKey;
sshk = ecdsa_newkey(self, pub);
sshk = ecdsa_new_pub(self, pub);
if (!sshk)
return NULL;
@ -1910,8 +1909,8 @@ static ssh_key *ecdsa_createkey(const ssh_keyalg *self,
return &ec->sshk;
}
static ssh_key *ed25519_openssh_createkey(const ssh_keyalg *self,
BinarySource *src)
static ssh_key *ed25519_new_priv_openssh(const ssh_keyalg *self,
BinarySource *src)
{
struct ec_key *ec;
struct ec_point *publicKey;
@ -1923,8 +1922,8 @@ static ssh_key *ed25519_openssh_createkey(const ssh_keyalg *self,
return NULL;
ec = snew(struct ec_key);
ec->sshk = self;
ec->signalg = self;
ec->publicKey.curve = ec_ed25519();
ec->publicKey.infinity = 0;
ec->privateKey = NULL;
@ -1966,7 +1965,7 @@ static ssh_key *ed25519_openssh_createkey(const ssh_keyalg *self,
return &ec->sshk;
}
static void ed25519_openssh_fmtkey(ssh_key *key, BinarySink *bs)
static void ed25519_openssh_blob(ssh_key *key, BinarySink *bs)
{
struct ec_key *ec = FROMFIELD(key, struct ec_key, sshk);
strbuf *pub;
@ -2002,8 +2001,8 @@ static void ed25519_openssh_fmtkey(ssh_key *key, BinarySink *bs)
strbuf_free(pub);
}
static ssh_key *ecdsa_openssh_createkey(const ssh_keyalg *self,
BinarySource *src)
static ssh_key *ecdsa_new_priv_openssh(const ssh_keyalg *self,
BinarySource *src)
{
const struct ecsign_extra *extra =
(const struct ecsign_extra *)self->extra;
@ -2017,8 +2016,8 @@ static ssh_key *ecdsa_openssh_createkey(const ssh_keyalg *self,
assert(curve->type == EC_WEIERSTRASS);
ec = snew(struct ec_key);
ec->sshk = self;
ec->signalg = self;
ec->publicKey.curve = curve;
ec->publicKey.infinity = 0;
ec->publicKey.x = NULL;
@ -2067,7 +2066,7 @@ static ssh_key *ecdsa_openssh_createkey(const ssh_keyalg *self,
return &ec->sshk;
}
static void ecdsa_openssh_fmtkey(ssh_key *key, BinarySink *bs)
static void ecdsa_openssh_blob(ssh_key *key, BinarySink *bs)
{
struct ec_key *ec = FROMFIELD(key, struct ec_key, sshk);
@ -2096,7 +2095,7 @@ static int ecdsa_pubkey_bits(const ssh_keyalg *self, ptrlen blob)
struct ec_key *ec;
int ret;
sshk = ecdsa_newkey(self, blob);
sshk = ecdsa_new_pub(self, blob);
if (!sshk)
return -1;
@ -2107,11 +2106,11 @@ static int ecdsa_pubkey_bits(const ssh_keyalg *self, ptrlen blob)
return ret;
}
static int ecdsa_verifysig(ssh_key *key, ptrlen sig, ptrlen data)
static int ecdsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
{
struct ec_key *ec = FROMFIELD(key, struct ec_key, sshk);
const struct ecsign_extra *extra =
(const struct ecsign_extra *)ec->signalg->extra;
(const struct ecsign_extra *)ec->sshk->extra;
BinarySource src[1];
ptrlen sigstr;
int ret;
@ -2122,7 +2121,7 @@ static int ecdsa_verifysig(ssh_key *key, ptrlen sig, ptrlen data)
BinarySource_BARE_INIT(src, sig.ptr, sig.len);
/* Check the signature starts with the algorithm name */
if (!ptrlen_eq_string(get_string(src), ec->signalg->name))
if (!ptrlen_eq_string(get_string(src), ec->sshk->ssh_id))
return 0;
sigstr = get_string(src);
@ -2261,7 +2260,7 @@ static void ecdsa_sign(ssh_key *key, const void *data, int datalen,
{
struct ec_key *ec = FROMFIELD(key, struct ec_key, sshk);
const struct ecsign_extra *extra =
(const struct ecsign_extra *)ec->signalg->extra;
(const struct ecsign_extra *)ec->sshk->extra;
unsigned char digest[512 / 8];
int digestLen;
Bignum r = NULL, s = NULL;
@ -2347,7 +2346,7 @@ static void ecdsa_sign(ssh_key *key, const void *data, int datalen,
}
/* Format the output */
put_stringz(bs, ec->signalg->name);
put_stringz(bs, ec->sshk->ssh_id);
pointlen = ec->publicKey.curve->fieldBits / 8;
put_uint32(bs, pointlen * 2);
@ -2379,7 +2378,7 @@ static void ecdsa_sign(ssh_key *key, const void *data, int datalen,
assert(s);
/* Format the output */
put_stringz(bs, ec->signalg->name);
put_stringz(bs, ec->sshk->ssh_id);
substr = strbuf_new();
put_mp_ssh2(substr, r);
@ -2396,18 +2395,20 @@ const struct ecsign_extra sign_extra_ed25519 = {
NULL, 0,
};
const ssh_keyalg ssh_ecdsa_ed25519 = {
ecdsa_newkey,
ecdsa_new_pub,
ecdsa_new_priv,
ed25519_new_priv_openssh,
ecdsa_freekey,
ecdsa_fmtkey,
ecdsa_sign,
ecdsa_verify,
ecdsa_public_blob,
ecdsa_private_blob,
ecdsa_createkey,
ed25519_openssh_createkey,
ed25519_openssh_fmtkey,
2 /* point, private exponent */,
ed25519_openssh_blob,
ecdsa_cache_str,
ecdsa_pubkey_bits,
ecdsa_verifysig,
ecdsa_sign,
"ssh-ed25519",
"ssh-ed25519",
&sign_extra_ed25519,
@ -2422,18 +2423,20 @@ const struct ecsign_extra sign_extra_nistp256 = {
nistp256_oid, lenof(nistp256_oid),
};
const ssh_keyalg ssh_ecdsa_nistp256 = {
ecdsa_newkey,
ecdsa_new_pub,
ecdsa_new_priv,
ecdsa_new_priv_openssh,
ecdsa_freekey,
ecdsa_fmtkey,
ecdsa_sign,
ecdsa_verify,
ecdsa_public_blob,
ecdsa_private_blob,
ecdsa_createkey,
ecdsa_openssh_createkey,
ecdsa_openssh_fmtkey,
3 /* curve name, point, private exponent */,
ecdsa_openssh_blob,
ecdsa_cache_str,
ecdsa_pubkey_bits,
ecdsa_verifysig,
ecdsa_sign,
"ecdsa-sha2-nistp256",
"ecdsa-sha2-nistp256",
&sign_extra_nistp256,
@ -2448,18 +2451,20 @@ const struct ecsign_extra sign_extra_nistp384 = {
nistp384_oid, lenof(nistp384_oid),
};
const ssh_keyalg ssh_ecdsa_nistp384 = {
ecdsa_newkey,
ecdsa_new_pub,
ecdsa_new_priv,
ecdsa_new_priv_openssh,
ecdsa_freekey,
ecdsa_fmtkey,
ecdsa_sign,
ecdsa_verify,
ecdsa_public_blob,
ecdsa_private_blob,
ecdsa_createkey,
ecdsa_openssh_createkey,
ecdsa_openssh_fmtkey,
3 /* curve name, point, private exponent */,
ecdsa_openssh_blob,
ecdsa_cache_str,
ecdsa_pubkey_bits,
ecdsa_verifysig,
ecdsa_sign,
"ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp384",
&sign_extra_nistp384,
@ -2474,18 +2479,20 @@ const struct ecsign_extra sign_extra_nistp521 = {
nistp521_oid, lenof(nistp521_oid),
};
const ssh_keyalg ssh_ecdsa_nistp521 = {
ecdsa_newkey,
ecdsa_new_pub,
ecdsa_new_priv,
ecdsa_new_priv_openssh,
ecdsa_freekey,
ecdsa_fmtkey,
ecdsa_sign,
ecdsa_verify,
ecdsa_public_blob,
ecdsa_private_blob,
ecdsa_createkey,
ecdsa_openssh_createkey,
ecdsa_openssh_fmtkey,
3 /* curve name, point, private exponent */,
ecdsa_openssh_blob,
ecdsa_cache_str,
ecdsa_pubkey_bits,
ecdsa_verifysig,
ecdsa_sign,
"ecdsa-sha2-nistp521",
"ecdsa-sha2-nistp521",
&sign_extra_nistp521,
@ -2559,7 +2566,7 @@ struct ec_key *ssh_ecdhkex_newkey(const struct ssh_kex *kex)
key = snew(struct ec_key);
key->signalg = NULL;
key->sshk = NULL;
key->publicKey.curve = curve;
if (curve->type == EC_MONTGOMERY) {

View File

@ -13,7 +13,7 @@ int ec_generate(struct ec_key *key, int bits, progfn_t pfn,
struct ec_point *publicKey;
if (!ec_nist_alg_and_curve_by_bits(bits, &key->publicKey.curve,
&key->signalg))
&key->sshk))
return 0;
key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n);
@ -40,7 +40,7 @@ int ec_edgenerate(struct ec_key *key, int bits, progfn_t pfn,
struct ec_point *publicKey;
if (!ec_ed_alg_and_curve_by_bits(bits, &key->publicKey.curve,
&key->signalg))
&key->sshk))
return 0;
{

View File

@ -563,9 +563,7 @@ static int read_blob(FILE *fp, int nlines, BinarySink *bs)
/*
* Magic error return value for when the passphrase is wrong.
*/
struct ssh2_userkey ssh2_wrong_passphrase = {
NULL, NULL, NULL
};
struct ssh2_userkey ssh2_wrong_passphrase = { NULL, NULL };
const ssh_keyalg *find_pubkey_alg_len(ptrlen name)
{
@ -741,7 +739,7 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
free_macdata = FALSE;
} else {
macdata = strbuf_new();
put_stringz(macdata, alg->name);
put_stringz(macdata, alg->ssh_id);
put_stringz(macdata, encryption);
put_stringz(macdata, comment);
put_string(macdata, public_blob->s,
@ -797,12 +795,11 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
* Create and return the key.
*/
ret = snew(struct ssh2_userkey);
ret->alg = alg;
ret->comment = comment;
ret->data = alg->createkey(
ret->key = ssh_key_new_priv(
alg, make_ptrlen(public_blob->u, public_blob->len),
make_ptrlen(private_blob->u, private_blob->len));
if (!ret->data) {
if (!ret->key) {
sfree(ret);
ret = NULL;
error = "createkey failed";
@ -1129,7 +1126,7 @@ int ssh2_userkey_loadpub(const Filename *filename, char **algorithm,
fclose(fp);
if (algorithm)
*algorithm = dupstr(alg->name);
*algorithm = dupstr(alg->ssh_id);
return TRUE;
/*
@ -1252,9 +1249,9 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
* Fetch the key component blobs.
*/
pub_blob = strbuf_new();
key->alg->public_blob(key->data, BinarySink_UPCAST(pub_blob));
ssh_key_public_blob(key->key, BinarySink_UPCAST(pub_blob));
priv_blob = strbuf_new();
key->alg->private_blob(key->data, BinarySink_UPCAST(priv_blob));
ssh_key_private_blob(key->key, BinarySink_UPCAST(priv_blob));
/*
* Determine encryption details, and encrypt the private blob.
@ -1286,7 +1283,7 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
char header[] = "putty-private-key-file-mac-key";
macdata = strbuf_new();
put_stringz(macdata, key->alg->name);
put_stringz(macdata, ssh_key_ssh_id(key->key));
put_stringz(macdata, cipherstr);
put_stringz(macdata, key->comment);
put_string(macdata, pub_blob->s, pub_blob->len);
@ -1333,7 +1330,7 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
sfree(priv_blob_encrypted);
return 0;
}
fprintf(fp, "PuTTY-User-Key-File-2: %s\n", key->alg->name);
fprintf(fp, "PuTTY-User-Key-File-2: %s\n", ssh_key_ssh_id(key->key));
fprintf(fp, "Encryption: %s\n", cipherstr);
fprintf(fp, "Comment: %s\n", key->comment);
fprintf(fp, "Public-Lines: %d\n", base64_lines(pub_blob->len));
@ -1425,7 +1422,7 @@ char *ssh2_pubkey_openssh_str(struct ssh2_userkey *key)
char *ret;
blob = strbuf_new();
key->alg->public_blob(key->data, BinarySink_UPCAST(blob));
ssh_key_public_blob(key->key, BinarySink_UPCAST(blob));
ret = ssh2_pubkey_openssh_str_internal(
key->comment, blob->s, blob->len);
strbuf_free(blob);
@ -1510,7 +1507,7 @@ char *ssh2_fingerprint_blob(const void *blob, int bloblen)
if (!get_err(src)) {
alg = find_pubkey_alg_len(algname);
if (alg) {
int bits = alg->pubkey_bits(alg, make_ptrlen(blob, bloblen));
int bits = ssh_key_public_bits(alg, make_ptrlen(blob, bloblen));
return dupprintf("%.*s %d %s", PTRLEN_PRINTF(algname),
bits, fingerprint_str);
} else {
@ -1526,10 +1523,10 @@ char *ssh2_fingerprint_blob(const void *blob, int bloblen)
}
}
char *ssh2_fingerprint(const ssh_keyalg *alg, ssh_key *data)
char *ssh2_fingerprint(ssh_key *data)
{
strbuf *blob = strbuf_new();
alg->public_blob(data, BinarySink_UPCAST(blob));
ssh_key_public_blob(data, BinarySink_UPCAST(blob));
char *ret = ssh2_fingerprint_blob(blob->s, blob->len);
strbuf_free(blob);
return ret;

View File

@ -474,7 +474,7 @@ void freersakey(struct RSAKey *key)
static void rsa2_freekey(ssh_key *key); /* forward reference */
static ssh_key *rsa2_newkey(const ssh_keyalg *self, ptrlen data)
static ssh_key *rsa2_new_pub(const ssh_keyalg *self, ptrlen data)
{
BinarySource src[1];
struct RSAKey *rsa;
@ -484,6 +484,7 @@ static ssh_key *rsa2_newkey(const ssh_keyalg *self, ptrlen data)
return NULL;
rsa = snew(struct RSAKey);
rsa->sshk = &ssh_rsa;
rsa->exponent = get_mp_ssh2(src);
rsa->modulus = get_mp_ssh2(src);
rsa->private_exponent = NULL;
@ -505,7 +506,7 @@ static void rsa2_freekey(ssh_key *key)
sfree(rsa);
}
static char *rsa2_fmtkey(ssh_key *key)
static char *rsa2_cache_str(ssh_key *key)
{
struct RSAKey *rsa = FROMFIELD(key, struct RSAKey, sshk);
char *p;
@ -536,14 +537,14 @@ static void rsa2_private_blob(ssh_key *key, BinarySink *bs)
put_mp_ssh2(bs, rsa->iqmp);
}
static ssh_key *rsa2_createkey(const ssh_keyalg *self,
static ssh_key *rsa2_new_priv(const ssh_keyalg *self,
ptrlen pub, ptrlen priv)
{
BinarySource src[1];
ssh_key *sshk;
struct RSAKey *rsa;
sshk = rsa2_newkey(self, pub);
sshk = rsa2_new_pub(self, pub);
if (!sshk)
return NULL;
@ -562,12 +563,13 @@ static ssh_key *rsa2_createkey(const ssh_keyalg *self,
return &rsa->sshk;
}
static ssh_key *rsa2_openssh_createkey(const ssh_keyalg *self,
BinarySource *src)
static ssh_key *rsa2_new_priv_openssh(const ssh_keyalg *self,
BinarySource *src)
{
struct RSAKey *rsa;
rsa = snew(struct RSAKey);
rsa->sshk = &ssh_rsa;
rsa->comment = NULL;
rsa->modulus = get_mp_ssh2(src);
@ -585,7 +587,7 @@ static ssh_key *rsa2_openssh_createkey(const ssh_keyalg *self,
return &rsa->sshk;
}
static void rsa2_openssh_fmtkey(ssh_key *key, BinarySink *bs)
static void rsa2_openssh_blob(ssh_key *key, BinarySink *bs)
{
struct RSAKey *rsa = FROMFIELD(key, struct RSAKey, sshk);
@ -603,7 +605,7 @@ static int rsa2_pubkey_bits(const ssh_keyalg *self, ptrlen pub)
struct RSAKey *rsa;
int ret;
sshk = rsa2_newkey(self, pub);
sshk = rsa2_new_pub(self, pub);
if (!sshk)
return -1;
@ -645,7 +647,7 @@ static const unsigned char asn1_weird_stuff[] = {
#define ASN1_LEN ( (int) sizeof(asn1_weird_stuff) )
static int rsa2_verifysig(ssh_key *key, ptrlen sig, ptrlen data)
static int rsa2_verify(ssh_key *key, ptrlen sig, ptrlen data)
{
struct RSAKey *rsa = FROMFIELD(key, struct RSAKey, sshk);
BinarySource src[1];
@ -744,18 +746,20 @@ static void rsa2_sign(ssh_key *key, const void *data, int datalen,
}
const ssh_keyalg ssh_rsa = {
rsa2_newkey,
rsa2_new_pub,
rsa2_new_priv,
rsa2_new_priv_openssh,
rsa2_freekey,
rsa2_fmtkey,
rsa2_sign,
rsa2_verify,
rsa2_public_blob,
rsa2_private_blob,
rsa2_createkey,
rsa2_openssh_createkey,
rsa2_openssh_fmtkey,
6 /* n,e,d,iqmp,q,p */,
rsa2_openssh_blob,
rsa2_cache_str,
rsa2_pubkey_bits,
rsa2_verifysig,
rsa2_sign,
"ssh-rsa",
"rsa2",
NULL,
@ -763,7 +767,7 @@ const ssh_keyalg ssh_rsa = {
struct RSAKey *ssh_rsakex_newkey(const void *data, int len)
{
ssh_key *sshk = rsa2_newkey(&ssh_rsa, make_ptrlen(data, len));
ssh_key *sshk = rsa2_new_pub(&ssh_rsa, make_ptrlen(data, len));
if (!sshk)
return NULL;
return FROMFIELD(sshk, struct RSAKey, sshk);

View File

@ -14,6 +14,8 @@ int rsa_generate(struct RSAKey *key, int bits, progfn_t pfn,
Bignum pm1, qm1, phi_n;
unsigned pfirst, qfirst;
key->sshk = &ssh_rsa;
/*
* Set up the phase limits for the progress report. We do this
* by passing minus the phase number.

View File

@ -769,7 +769,7 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
savecomment = state->ssh2key.comment;
state->ssh2key.comment = NULL;
fp = ssh2_fingerprint(state->ssh2key.alg, state->ssh2key.data);
fp = ssh2_fingerprint(state->ssh2key.key);
state->ssh2key.comment = savecomment;
SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);
@ -1321,8 +1321,8 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
} else {
if (state->ssh2) {
strbuf *blob = strbuf_new();
state->ssh2key.alg->public_blob(
state->ssh2key.data, BinarySink_UPCAST(blob));
ssh_key_public_blob(
state->ssh2key.key, BinarySink_UPCAST(blob));
ssh2_write_pubkey(fp, state->ssh2key.comment,
blob->u, blob->len,
SSH_KEYTYPE_SSH2_PUBLIC_RFC4716);
@ -1365,17 +1365,13 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, PROGRESSRANGE, 0);
if (state->ssh2) {
if (state->keytype == DSA) {
state->ssh2key.data = &state->dsskey.sshk;
state->ssh2key.alg = &ssh_dss;
state->ssh2key.key = &state->dsskey.sshk;
} else if (state->keytype == ECDSA) {
state->ssh2key.data = &state->eckey.sshk;
state->ssh2key.alg = state->eckey.signalg;
state->ssh2key.key = &state->eckey.sshk;
} else if (state->keytype == ED25519) {
state->ssh2key.data = &state->eckey.sshk;
state->ssh2key.alg = &ssh_ecdsa_ed25519;
state->ssh2key.key = &state->eckey.sshk;
} else {
state->ssh2key.data = &state->key.sshk;
state->ssh2key.alg = &ssh_rsa;
state->ssh2key.key = &state->key.sshk;
}
state->commentptr = &state->ssh2key.comment;
} else {
@ -1423,7 +1419,7 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
savecomment = *state->commentptr;
*state->commentptr = NULL;
if (state->ssh2)
fp = ssh2_fingerprint(state->ssh2key.alg, state->ssh2key.data);
fp = ssh2_fingerprint(state->ssh2key.key);
else
fp = rsa_ssh1_fingerprint(&state->key);
SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);

View File

@ -339,7 +339,7 @@ void keylist_update(void)
* stop and leave out a tab character. Urgh.
*/
p = ssh2_fingerprint(skey->alg, skey->data);
p = ssh2_fingerprint(skey->key);
listentry = dupprintf("%s\t%s", p, skey->comment);
sfree(p);
@ -350,7 +350,8 @@ void keylist_update(void)
break;
listentry[pos++] = '\t';
}
if (skey->alg != &ssh_dss && skey->alg != &ssh_rsa) {
if (ssh_key_alg(skey->key) != &ssh_dss &&
ssh_key_alg(skey->key) != &ssh_rsa) {
/*
* Remove the bit-count field, which is between the
* first and second \t.
@ -647,7 +648,7 @@ static INT_PTR CALLBACK KeyListProc(HWND hwnd, UINT msg,
if (selectedArray[itemNum] == rCount + i) {
pageant_delete_ssh2_key(skey);
skey->alg->freekey(skey->data);
ssh_key_free(skey->key);
sfree(skey);
itemNum--;
}