Check by assertion that we cross-certified the right key type.

The flag 'cross_certifying' in the SSH-2 transport layer state is now
a pointer to the host key algorithm we expect to be certifying,
instead of a plain bool. That lets me check by assertion that it's
what we expected it to be after all the complicated key exchange has
happened.

(I have no reason to think this _will_ go wrong. When we cross-
certify, the desired algorithm should be the only one we put into our
KEXINIT host key algorithm list, so it should also be the only one we
can come out of the far end of KEXINIT having selected. But if
anything ever does go wrong with my KEXINIT handling then I'd prefer
an assertion failure to silently certifying the wrong key, and also,
this makes it clearer to static analysers - and perhaps also humans
reading the code - what we expect the situation to be.)
This commit is contained in:
Simon Tatham 2018-12-01 14:39:23 +00:00
Родитель e9b49fdced
Коммит 1e1f06b2ec
3 изменённых файлов: 10 добавлений и 6 удалений

Просмотреть файл

@ -836,6 +836,9 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s)
s->hostkey_str = s->keystr;
s->keystr = NULL;
} else if (s->cross_certifying) {
assert(s->hkey);
assert(ssh_key_alg(s->hkey) == s->cross_certifying);
s->fingerprint = ssh2_fingerprint(s->hkey);
ppl_logevent(("Storing additional host key for this host:"));
ppl_logevent(("%s", s->fingerprint));
@ -843,7 +846,6 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s)
s->fingerprint = NULL;
store_host_key(s->savedhost, s->savedport,
ssh_key_cache_id(s->hkey), s->keystr);
s->cross_certifying = false;
/*
* Don't forget to store the new key as the one we'll be
* re-checking in future normal rekeys.
@ -857,6 +859,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s)
* enforce that the key we're seeing this time is identical to
* the one we saw before.
*/
assert(s->keystr); /* filled in by prior key exchange */
if (strcmp(s->hostkey_str, s->keystr)) {
#ifndef FUZZING
ssh_sw_abort(s->ppl.ssh,

Просмотреть файл

@ -1856,8 +1856,7 @@ static void ssh2_transport_special_cmd(PacketProtocolLayer *ppl,
}
} else if (code == SS_XCERT) {
if (!s->kex_in_progress) {
s->hostkey_alg = ssh2_hostkey_algs[arg].alg;
s->cross_certifying = true;
s->cross_certifying = s->hostkey_alg = ssh2_hostkey_algs[arg].alg;
s->rekey_reason = "cross-certifying new host key";
s->rekey_class = RK_NORMAL;
queue_idempotent_callback(&s->ppl.ic_process_queue);

Просмотреть файл

@ -204,10 +204,12 @@ struct ssh2_transport_state {
int n_uncert_hostkeys;
/*
* Flag indicating that the current rekey is intended to finish
* with a newly cross-certified host key.
* Indicate that the current rekey is intended to finish with a
* newly cross-certified host key. To double-check that we
* certified the right one, we set this to point to the host key
* algorithm we expect it to be.
*/
bool cross_certifying;
const ssh_keyalg *cross_certifying;
ssh_key *const *hostkeys;
int nhostkeys;