diff options
author | djm@openbsd.org <djm@openbsd.org> | 2021-12-19 22:12:30 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2021-12-20 09:28:07 +1100 |
commit | 288fd0218dbfdcb05d9fbd1885904bed9b6d42e6 (patch) | |
tree | 7e31fb89f6384e5312308562c1b7609eb3011832 /monitor.c | |
parent | dbb339f015c33d63484261d140c84ad875a9e548 (diff) | |
download | openssh-git-288fd0218dbfdcb05d9fbd1885904bed9b6d42e6.tar.gz |
upstream: sshd side of hostbound public key auth
This is identical to the standard "publickey" method, but it also includes
the initial server hostkey in the message signed by the client.
feedback / ok markus@
OpenBSD-Commit-ID: 7ea01bb7238a560c1bfb426fda0c10a8aac07862
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 26 |
1 files changed, 21 insertions, 5 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.228 2021/08/11 05:20:17 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.229 2021/12/19 22:12:30 djm Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Markus Friedl <markus@openbsd.org> @@ -1246,11 +1246,12 @@ static int monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) { struct sshbuf *b; + struct sshkey *hostkey = NULL; const u_char *p; char *userstyle, *cp; size_t len; u_char type; - int r, fail = 0; + int hostbound = 0, r, fail = 0; if ((b = sshbuf_from(data, datalen)) == NULL) fatal_f("sshbuf_from"); @@ -1291,19 +1292,34 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) if ((r = sshbuf_skip_string(b)) != 0 || /* service */ (r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse method"); - if (strcmp("publickey", cp) != 0) - fail++; + if (strcmp("publickey", cp) != 0) { + if (strcmp("publickey-hostbound-v00@openssh.com", cp) == 0) + hostbound = 1; + else + fail++; + } free(cp); if ((r = sshbuf_get_u8(b, &type)) != 0) fatal_fr(r, "parse pktype"); if (type == 0) fail++; if ((r = sshbuf_skip_string(b)) != 0 || /* pkalg */ - (r = sshbuf_skip_string(b)) != 0) /* pkblob */ + (r = sshbuf_skip_string(b)) != 0 || /* pkblob */ + (hostbound && (r = sshkey_froms(b, &hostkey)) != 0)) fatal_fr(r, "parse pk"); if (sshbuf_len(b) != 0) fail++; sshbuf_free(b); + if (hostkey != NULL) { + /* + * Ensure this is actually one of our hostkeys; unfortunately + * can't check ssh->kex->initial_hostkey directly at this point + * as packet state has not yet been exported to monitor. + */ + if (get_hostkey_index(hostkey, 1, ssh) == -1) + fatal_f("hostbound hostkey does not match"); + sshkey_free(hostkey); + } return (fail == 0); } |