This fixes a data race in the tests for x/crypto/ssh, which expects to
be able to examine a transport's read and write counters without
locking after closing it.
(Given the number of goroutines, channels, and mutexes used in this
package, I wouldn't be surprised if other concurrency bugs remain.
I would suggest simplifying the concurrency in this package, but I
don't intend to follow up on that myself at the moment.)
Fixesgolang/go#56957.
Change-Id: Ib1f1390b66707c66a3608e48f3f52483cff3c1f5
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/456758
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
In accordance to RFC8308, send ext-info-c only during the first key
exchange. Some server implementations such as OpenSSH 7 will send an
extInfoMsg message each time when ext-info-c is received. This results
in a closed connection, as our client does not expect this message while
handling the mux.
See https://bugzilla.mindrot.org/show_bug.cgi?id=2929 regarding the
behaviour of OpenSSH if it sees ext-info-c in later key exchanges.
Fixesgolang/go#51808
Change-Id: Id94f1ef73cec6147136246b0b6048b57db92660d
GitHub-Last-Rev: fcfe5ed37306136219854031abc809e0dc9b3124
GitHub-Pull-Request: golang/crypto#208
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/394134
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Trust: Roland Shoemaker <roland@golang.org>
CL 220037 had implemented support for host authentication using
rsa-sha2-256/512, but not client public key authentication. OpenSSH
disabled the SHA-1 based ssh-rsa by default in version 8.8 (after
pre-announcing it in versions 8.2, 8.3, 8.4, 8.5, 8.6, and 8.7) although
some distributions re-enable it. GitHub will start rejecting ssh-rsa for
keys uploaded before November 2, 2021 on March 15, 2022.
https://github.blog/2021-09-01-improving-git-protocol-security-github/
The server side already worked, as long as the client selected one of
the SHA-2 algorithms, because the signature flowed freely to Verify.
There was however nothing verifying that the signature algorithm matched
the advertised one. The comment suggested the check was being performed,
but it got lost back in CL 86190043. Not a security issue because the
signature had to pass the callback's Verify method regardless, and both
values were checked to be acceptable.
Tested with OpenSSH 8.8 configured with "PubkeyAcceptedKeyTypes -ssh-rsa"
and no application-side changes.
The Signers returned by ssh/agent (when backed by an agent client)
didn't actually implement AlgorithmSigner but ParameterizedSigner, an
interface defined in an earlier version of CL 123955.
Updates golang/go#49269Fixesgolang/go#39885
For golang/go#49952
Change-Id: I13b41db8041f1112a70f106c55f077b904b12cb8
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392394
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
The server side implementation was not actually populating the
SSH_MSG_USERAUTH_INFO_REQUEST field with the
KeyboardInteractiveChallenge argument, although the client side was
deserializing it and passing it to the KeyboardInteractiveChallenge
callback.
Anyway, the first field of SSH_MSG_USERAUTH_INFO_REQUEST is "name", not
"user". Maybe the confusion was due to the first field of
SSH_MSG_USERAUTH_REQUEST being the user.
RFC 4256, Section 3.3, says this about it
One possibility is to use the name field (possibly
prefixed with the application's name) as the title of a dialog window
in which the prompt(s) are presented.
and examples include "CRYPTOCard Authentication", "Password
Authentication", and "Password Expired".
Co-authored-by: Kevin Wallace <kevin@pentabarf.net>
Change-Id: Ic6ec0dfea2122704603c44f42898a980689a15c9
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/372234
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
The server implementation looks at the HostKeys to advertise and
negotiate host key signature algorithms. A fundamental issue of the
Signer and AlgorithmSigner interfaces is that they don't expose the
supported signature algorithms, so really the server has to guess.
Currently, it would guess exclusively based on the PublicKey.Type,
regardless of whether the host key implemented AlgorithmSigner. This
means that a legacy Signer that only supports ssh-rsa still led the
server to negotiate rsa-sha2 algorithms. The server would then fail to
find a suitable host key to make the signature and crash.
This won't happen if only Signers from this package are used, but if a
custom Signer that doesn't support SignWithAlgorithm() but returns
"ssh-rsa" from PublicKey().Type() is used as a HostKey, the server is
vulnerable to DoS.
The only workable rules to determine what to advertise seems to be:
1. a pure Signer will always Sign with the PublicKey.Type
2. an AlgorithmSigner supports all algorithms associated with the
PublicKey.Type
Rule number two means that we can't add new supported algorithms in the
future, which is not great, but it's too late to fix that.
rsaSigner was breaking rule number one, and although it would have been
fine where it's used, I didn't want to break our own interface contract.
It's unclear why we had separate test key entries for rsa-sha2
algorithms, since we can use the ssh-rsa key for those. The only test
that used them, TestCertTypes, seemed broken: the init was actually
failing at making the corresponding signers rsaSigners, and indeed the
test for the SHA-256 signer expected and checked a SHA-512 signature.
Pending CVE
For golang/go#49952
Change-Id: Ie658eefcadd87906e63fc7faae8249376aa96c79
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392355
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
RFC 8332, Section 2 sets up two overlapping namespaces: public key
formats and public key algorithms.
* The formats are what we currently have KeyAlgo constants for, and they
appear in PublicKey.Type.
* The algorithms are the set of both KeyAlgo and SigAlgo constants, and
they appear in Signature.Format (amongst other places).
This is incoherent, because that means Signature.Format can be both a
KeyAlgo (like KeyAlgoECDSA256) or a SigAlgo (like SigAlgoRSASHA2256).
One solution would be to duplicate all the KeyAlgo constants into the
SigAlgo namespace, but that would be confusing because applications are
currently using KeyAlgos where they'd be supposed to use the new
SigAlgos (while we can't deprecate the KeyAlgos because they are still
necessary for the PublicKey.Type namespace).
Instead, drop the separate namespaces, and use KeyAlgos throughout.
There are simply some KeyAlgos that can't be a PublicKey.Type.
Take the opportunity to fix the stuttering SHA22565/SHA2512 names. It's
totally ok to call those hashes SHA-256 and SHA-512 without the family
infix.
For golang/go#49952
Change-Id: Ia1fce3912a7e60aa70a88f75ed311be331fd19d5
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392354
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
The previous code
if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 {
deobfuscates to the classic mistake
if g <= 1 && g >= p - 1 {
which is never true.
What the code actually intended to do is
if gex.g.Cmp(one) != 1 || gex.g.Cmp(pMinusOne) != -1 {
or more readably and consistently with the diffieHellman method
if gex.g.Cmp(one) <= 0 || gex.g.Cmp(pMinusOne) >= 0 {
Now, is this a security issue? The incorrect checks apply to g and k,
but not what we call Y and the spec calls f. RFC 4419 says:
Either side MUST NOT send or accept e or f values that are not in the
range [1, p-1]. If this condition is violated, the key exchange
fails. To prevent confinement attacks, they MUST accept the shared
secret K only if 1 < K < p - 1.
Note that RFC 8268, Section 4 updates the equivalent RFC 4253 statement
(although not the RFC 4419 one) about e and f, but we are already doing
the correct full check there.
DH Public Key values MUST be checked and both conditions:
1 < e < p-1
1 < f < p-1
MUST be true. Values not within these bounds MUST NOT be sent or
accepted by either side. If either one of these conditions is
violated, then the key exchange fails.
This simple check ensures that:
o The remote peer behaves properly.
o The local system is not forced into the two-element subgroup.
The check on K seems like a proxy for checking a number of ways to fix
the DH output (for example by manipulating g) to one of 0, 1, or -1.
This should not be meaningful to security for two reasons:
- all parameters end up in the "transcript" hash that will get signed
by the server's host key, and if the attacker controls the host
key's signature, they have the ability to MitM without resorting to
confinement attacks
- the client secret is ephemeral, so leaking bits of it by forcing it
into small sub-groups does not gain the attacker anything, as the
secret does not get reused
Indeed, this is the same explanation of why it's ok not to check that p
is indeed a (safe) prime, which even OpenSSH omits. Building an
equivalent attack by manipulating p instead of g is left as an exercise
to the reader.
For the future, this is a case study in why we should not add complexity
even when it looks easy enough to do. CL 174257 added the
diffie-hellman-group-exchange kex. That introduced a data race (arguably
a security issue), which was fixed in CL 222078. Then it was too slow,
which led to CL 252337 that removed the primalty check, which required a
full analysis of whether it's safe to skip it, and checking against
other implementations. Now we find there's a bug and we have to do
another security analysis that not even the RFC bothered to do in order
to decide if it's a security issue. My decision in
https://github.com/golang/go/issues/17230#issuecomment-489163656
does not look like the right one in hindsight.
While at it, clean up the code some
- drop useless bit size bounds logic in the server stub that get
ignored by the rest of the function
- make p and g local variables instead of method fields, since they
are not persistent state (this was originally a data race which was
fixed in CL 222078 by making Client not a pointer receiver)
Updates golang/go#17230
Change-Id: I4b1c68537109f627ccd75ec381dcfab57ce1768c
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392015
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
RFC 9142 made diffie-hellman-group14-sha256 from RFC 8268 a MUST, and
it's strictly better than diffie-hellman-group14-sha1, which we already
have, and trivial to add.
> The method of key exchange used for the name "diffie-hellman-
> group14-sha256" is the same as that for "diffie-hellman-group14-sha1"
> except that the SHA256 hash algorithm is used.
Ignore the bigger groups which have a meaningful performance cost, and
don't share the same interoperability benefit.
Adapted from CL 387994.
Fixesgolang/go#31731
Co-authored-by: Nicola Murino <nicola.murino@gmail.com>
Change-Id: Id4ce345a2065840f193986739ea890f105a1e929
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392014
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
If we are going to send the disconnect message and close the connection,
because we have exhausted the number of authentication attempts, don't
send the final authentication failure message. This behavior matches
that of OpenSSH.
Fixesgolang/go#51149
Change-Id: I43b2de2e854f789161cd7fd6c05876661adfb2c1
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/385236
Trust: Roland Shoemaker <roland@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This change adds support for RSA SHA-2 based signatures for host keys and certificates. It also switches the default certificate signature algorithm for RSA to use SHA-512. This is implemented by treating ssh.Signer specially when the key type is `ssh-rsa` by also allowing SHA-256 and SHA-512 signatures.
Fixesgolang/go#37278
Change-Id: I2ee1ac4ae4c9c1de441a2d6cf1e806357ef18910
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/220037
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
The ability to trigger the 'gssapi-with-mic' authentication method is
not properly gated by the presence of the GSSAPIWithMICConfig field of
the ServerConfig type. If this field is not set and a client sends a
'gssapi-with-mic' request, regardless of if the server advertises it,
the server will panic.
This issue was discovered and reported by Joern Schneewesiz, GitLab
Security Research Team.
Fixes CVE-2020-29652
Change-Id: Ie25de2766e442c8ab46680aae3ac89b0823cdeed
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/278852
Trust: Roland Shoemaker <roland@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
The existing implementation validates that the prime returned by the server is, in fact, prime, which is extremely slow, especially for large key sizes.
As other implementations, including OpenSSH, do not verify the primality of the provided parameters, this change removes that check.
Fixesgolang/go#41151
Change-Id: I7539714c690f08b5792a0c540cbf46c3e81f13ba
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/252337
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Roland Shoemaker <roland@golang.org>
By using a slice instead of a map for tried authentication methods the order is always the same. Small slices are also faster than maps.
Before the change sometimes I get the error:
ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
and sometimes:
ssh: handshake failed: ssh: unable to authenticate, attempted methods [publickey none], no supported methods remain
Change-Id: I06507d57e9eef497ff05bce088d52607e69dde3e
GitHub-Last-Rev: 3a46aae4c6e3e5f52ca4b04384b3cc4efc039aa6
GitHub-Pull-Request: golang/crypto#142
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/239171
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
rfc4254 section 5.4 states that channel request messages sent to an
unrecognized channel should be replied with a `SSH_MSG_CHANNEL_FAILURE`,
rather than erring out and closing the mux. This can occur with servers
like openssh-portable, which can begin to close a channel and also use
that channel for keepalives before it has received a closed response
from the client.
Fixesgolang/go#38908
Change-Id: Id68b77e16b2889d3a21d505ed8018f9f457e067a
GitHub-Last-Rev: 8a92f87dc30697d9e3805af695efdf1b1dc8409b
GitHub-Pull-Request: golang/crypto#136
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/232659
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
The original referenced paper is no longer available. I contacted the author, and this is the reference he supplied.
Change-Id: Ib5ad88932f2bfc12ff62639f7fb7c3ee568610d6
GitHub-Last-Rev: 2cf7d15c63a114952c90a018ea5afe085965202e
GitHub-Pull-Request: golang/crypto#132
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/228638
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
The existing code for decrypting OpenSSH-format keys only allows aes256-ctr, the current ssh-keygen default.
However, the default encryption scheme was aes256-cbc until relatively recently, and some of these keys are still in use.
Support for aes256-cbc has been added.
Fixesgolang/go#37939
Change-Id: I3730347109c5dd18e4cbe61b48bbca9566ad61d2
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/224817
Reviewed-by: Filippo Valsorda <filippo@golang.org>
An attacker can craft an ssh-ed25519 or sk-ssh-ed25519@openssh.com
public key, such that the library will panic when trying to verify a
signature with it. Clients can deliver such a public key and signature
to any golang.org/x/crypto/ssh server with a PublicKeyCallback, and
servers can deliver them to any golang.org/x/crypto/ssh client.
This issue was discovered and reported by Alex Gaynor, Fish in a Barrel,
and is tracked as CVE-2020-9283.
Change-Id: Ie25b78a0b0181fbbc8cc7de4f4e27d908777529c
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/220357
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
CL 212377 changed end of input character on windows - from \n to \r.
But CL 212377 did not adjust ReadConsole accordingly. For example,
after CL 212377 \n was still used to end of password processing,
and \r was ignored.
This CL swaps these rules - \r is now used to end password processing,
and \n are ignored. The change only affects windows, all non windows
code should work as before.
This CL also adjusts TestReadPasswordLineEnd to fit new rules.
Fixesgolang/go#36609
Change-Id: I027bf80d10e7d4d4b17ff0264935d14b8bea9097
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/215417
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>