The previous implementation used bytes.TrimSpace, which strips all
Unicode whitespace categories (e.g., non-breaking spaces). However,
OpenSSH's known_hosts parser (hostfile.c) strictly treats only ASCII
space (0x20) and horizontal tab (0x09) as separators.
This discrepancy meant the Go parser might interpret fields differently
than OpenSSH, potentially treating parts of a key or hostname as
separators if they contained Unicode whitespace.
This change replaces bytes.TrimSpace with a local trimSpace helper that
only trims " \t", ensuring parsing behavior consistent with the
reference implementation.
This issue was found during a security audit by NCC Group Cryptography
Services, sponsored by Teleport, and was assessed and is being fixed as
a non-security bug.
Change-Id: Ia536889636de2c167d2507c01e3f1b7c033c9a8f
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/782426
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
I believe this fixes https://github.com/golang/go/issues/36126 .
The problem was that it was keeping only the first known key of each
type found.
If you have a server advertising multiple keys of the same type,
you might get a missmatch key error.
Per sshd(8) man page, it should allow reapeatable hosts with
different host keys, although it don't specify anything about
hosts being from different types:
"It is permissible (but not recommended) to have several lines or
different host keys for the same names. This will inevitably happen when
short forms of host names from different domains are put in the file. It
is possible that the files contain conflicting information;
authentication is accepted if valid information can be found from either
file."
So, this changes knownhosts behavior to accept any of the keys for a
given host, regardless of type.
Fixes#36126
Change-Id: I3450ff954259a403f2471082d013a5f79def0e16
GitHub-Last-Rev: 361bd2bcd20348956aaf114ef159a5350397eaf4
GitHub-Pull-Request: golang/crypto#254
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/478535
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
This fixes the following vulnerability scenario:
* Victim logs into SAFE-HOST on SAFE-IP-ADDRESS regularly.
* Victim is cajoled into connecting to attacker controlled
ATTACK-HOST, on ATTACK-IP-ADDRESS. ATTACK-HOST uses a different host
key type (e.g. Ed25519 vs RSA). The new key is added at the end of
known_hosts.
* Attacker makes DNS system return ATTACK-IP-ADDRESS for SAFE-HOST.
* Victim logs into SAFE-HOST, but is not warned because the host key
matches ATTACK-IP-ADDRESS.
For this attack to work, the key type has to be different, because
knownhosts gives precedence to the first key found for each type. Add
a test that asserts this behavior.
The new semantics simplify the code, but callers that modify
.ssh/known_host interactviely must now take an extra step to remain
OpenSSH compatible: on successful login, the IP address must be
checked without hostname, and if it is not known, added separately to
the known_hosts file, so future logins that use an IP address only
will be protected too.
Thanks to Daniel Parks <security@demonhorse.net> for finding this
vulnerability.
Change-Id: I62b1b60ceb02e2f583a4657213feac1a8885dd42
Reviewed-on: https://go-review.googlesource.com/104939
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
None are "wrong" per se, but there are a lot of good suggestions and
in one case a docstring that was not present in godoc due to the
presence of an extra newline.
Changed "Id" in struct properties to "ID" in some non-exported
structs. Removed a trailing period from some error messages; I believe
the exact contents of error strings are not covered by the Go
compatibility promise.
Change-Id: I7c620582dc247396f72c52d38c909ccc0ec87b83
Reviewed-on: https://go-review.googlesource.com/80145
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This is a breaking change.
This adds a new hostkey callback which takes the hostname field
restrictions into account when validating host certificates.
Prior to this, a known_hosts file with the following entry
@cert-authority *.example.com ssh-rsa <example.com public key>
would, when passed to knownhosts.New() generate an ssh.HostKeyCallback
that would accept all host certificates signed by the example.com public
key, no matter what host the client was connecting to.
After this change, that known_hosts entry can only be used to validate
host certificates presented when connecting to hosts under *.example.com
This also renames IsAuthority to IsUserAuthority to make its intended
purpose more clear.
Change-Id: I7188a53fdd40a8c0bc21983105317b3498f567bb
Reviewed-on: https://go-review.googlesource.com/41751
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Consider the following code:
var p *int
a := []int{0, 1, 2, 3}
for _, i := range a {
if i == 1 {
p = &i
}
}
fmt.Println(*p) // Prints 3
This prints 3 because the variable i is the exact same variable across
all iterations of the loop. When the address is taken for some specific
iteration, the user's intent is to capture the value of i at that
given loop, but instead the value of i in the last loop is what remains.
A bug this sort occurs in the check logic since the address of the
knownKey is taken, but is changed upon subsequent iterations of the
loop (which happens when there are multiple lines).
Change-Id: Ic626778cdcde3968dcff4fa5e7206274957dcb04
Reviewed-on: https://go-review.googlesource.com/40937
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>