Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/crypto/ssh: support RSA SHA-2 host key signatures #37278

Open
hansnielsen opened this issue Feb 18, 2020 · 18 comments
Open

x/crypto/ssh: support RSA SHA-2 host key signatures #37278

hansnielsen opened this issue Feb 18, 2020 · 18 comments

Comments

@hansnielsen
Copy link

@hansnielsen hansnielsen commented Feb 18, 2020

What version of Go are you using (go version)?

$ go version
1.13.8

Version of x/crypto: 1d94cc7ab1c630336ab82ccb9c9cda72a875c382

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
n/a

What did you do?

I tried to connect to an OpenSSH 8.2 server with the ssh-rsa host key algorithm disabled on the server. I also tried to run an x/crypto/ssh server and connect from an OpenSSH client with ssh-rsa disabled. Lastly, I tried to sign a host certificate with ssh.Certificate.SignCert with a SHA-2 based signature.

What did you expect to see?

I expected the RSA host key and certificate to validate successfully with the new SHA-2 based signatures introduced in RFC 8332. I also expected to be able to sign host certificates and have them automatically received a SHA-2 based signature.

OpenSSH has already deprecated ssh-rsa (i.e. SHA-1 based) signatures in host certificates in version 8.2 because of safety reasons. They can still be used by the host key algorithm must be manually specified.

What did you see instead?

I was unable to connect either as a server or a client if ssh-rsa wasn't enabled while using RSA host keys or host certificates. I was able to sign a certificate with the AlgorithmSigner wrapper approach (i.e. by forcefully overriding Sign) proposed by @stoggi in #36261, but it's not a great experience for users.

@gopherbot gopherbot added this to the Unreleased milestone Feb 18, 2020
@hansnielsen
Copy link
Author

@hansnielsen hansnielsen commented Feb 18, 2020

I spent some time hacking away at a solution for this and believe I have something largely ready to make a CL from: hansnielsen/golang-x-crypto@master...hans-rsa-sha2-support

The main change is that when given an ssh-rsa-type key or an RSA crypto.Signer (and not a custom ssh.Signer), the code will automatically register the ssh-rsa, rsa-sha2-256, and rsa-sha2-512 host key algorithms for use. This means that for users who haven't specified explicit algorithm preferences, they'll get the new SHA-2 based signatures just by updating. There shouldn't be any external-facing changes beyond algorithm support and the certificate signing choice mentioned below.

The approach OpenSSH chose for these new signature types is somewhat interesting: they have the same key type (ssh-rsa) but different signature algorithms. This makes it slightly tricky to integrate while keeping the existing tests working. There's a little more explicit special-casing of the RSA SHA-2 signature family than I'd like.

The one main choice I made in here (beyond just adding support for the new signature types) is that certificates now default to rsa-sha2-512 instead of ssh-rsa. I think given the already-deprecated nature of ssh-rsa plus the reasonable threat model for host certificates, this is the correct choice. The "wrapped AlgorithmSigner" approach can still be used to force an RSA SHA-1 signature and there's no need to encourage this.

Feedback welcome! If the approach in the code above looks good, I'll work on submitting a CL.

@josharian
Copy link
Contributor

@josharian josharian commented Feb 18, 2020

@FiloSottile
Copy link
Member

@FiloSottile FiloSottile commented Feb 18, 2020

Sounds good on both adding the algorithms and changing the certificate default.

OpenSSH 8.2 already stopped supporting ssh-rsa signed certificates, right?

@alex
Copy link
Contributor

@alex alex commented Feb 18, 2020

Only for host certificates I think, client certs still can use it.

@hansnielsen
Copy link
Author

@hansnielsen hansnielsen commented Feb 18, 2020

I considered removing the SHA-1 RSA signature for host certs but wanted to keep this issue to algorithm addition. There are some choices in the client host key algorithm list that are probably worth revisiting as well and it’d probably be best to handle that as one issue.

@FiloSottile
Copy link
Member

@FiloSottile FiloSottile commented Feb 18, 2020

How long has OpenSSH supported rsa-sha2-512 certificates?

@hansnielsen
Copy link
Author

@hansnielsen hansnielsen commented Feb 18, 2020

OpenSSH 7.3 was the first version with rsa-sha2-512 certificate support, released on 2016-08-01. Ubuntu xenial stands out as being the largest distro that's still on 7.2 with backported security fixes.

@alex
Copy link
Contributor

@alex alex commented Feb 18, 2020

I always regret asking things like this, but surely support non-SHA1 signature algorithms is as deserving of a security backport as an actual CVE?

@gopherbot
Copy link

@gopherbot gopherbot commented Feb 19, 2020

Change https://golang.org/cl/220037 mentions this issue: ssh: support RSA SHA-2 (RFC8332) signatures

@rsc
Copy link
Contributor

@rsc rsc commented Feb 26, 2020

Based on the discussion above, this seems like a likely accept.

@rsc rsc added this to Active in Proposals Feb 26, 2020
@rsc rsc moved this from Active to Likely Accept in Proposals Feb 26, 2020
@rsc
Copy link
Contributor

@rsc rsc commented Mar 4, 2020

No change in consensus, so accepted.

@awly
Copy link
Contributor

@awly awly commented May 12, 2020

Looks like https://go-review.googlesource.com/c/crypto/+/220037 has had no progress since Feb 20th.
Since everyone seems to agree on the change, @hansnielsen @FiloSottile do you have the time to finish that CL review?

This is causing teleport some interop problems with newer openssh versions.

peterverraedt added a commit to kuleuven/crypto that referenced this issue Jun 15, 2020
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.

Fixes golang/go#37278

Change-Id: I2ee1ac4ae4c9c1de441a2d6cf1e806357ef18910
@SwampDragons
Copy link

@SwampDragons SwampDragons commented Jun 26, 2020

This issue is hitting us over in Packer at hashicorp/packer#8609. We use the ssh client, generating the Auth method first by calling ParsePrivateKey and then feeding that signer into the PublicKeys method to retrieve the publickeycallback. code: https://github.com/hashicorp/packer/blob/master/helper/communicator/config.go#L320-L324

I can create my own algorithm signer to set the algorithm and call the wrappedSigner's SignWithAlgorithm, but it doesn't work with the proposed change at https://go-review.googlesource.com/c/crypto/+/220037 unless the publickeycallback is also modified, because it's still sending the key type as the algorithm, in this case "ssh-rsa".

By hardcoding lines https://github.com/golang/crypto/blob/75b288015ac94e66e3d6715fb68a9b41bf046ec2/ssh/client_auth.go#L218 and https://github.com/golang/crypto/blob/75b288015ac94e66e3d6715fb68a9b41bf046ec2/ssh/client_auth.go#L232 to SigAlgoRSASHA2256, I can force this to work to connect to an ssh server that doesn't allow the "ssh-rsa" algorithm, but obviously this isn't a viable patch for the module.

This is my first time doing a real dive into this library so I'm wondering if anyone else on this thread has an instinct about how to extend the ssh.PublicKeys() method to make it work for AlgorithmSigners that are actually using custom algorithms.

@awly
Copy link
Contributor

@awly awly commented Jun 26, 2020

I tried working around this by implementing a custom ssh.AlgorithmSigner around an ssh.Signer (which is derived from an SSH certificate).
You can sign new certificates using a CA this way and it seems to work fine with OpenSSH.

However, you can't use such signers for actual SSH handshakes against a Go SSH server, because of https://github.com/golang/crypto/blob/75b288015ac94e66e3d6715fb68a9b41bf046ec2/ssh/server.go#L556-L564. That's a hardcoded check for algorithms supported in handshake signatures.
So, without https://go-review.googlesource.com/c/crypto/+/220037, you can only get cert signing to work.

For reference, here's our workaround for certs: https://github.com/gravitational/teleport/pull/3777/files#diff-193b31b40b2b216b00568f93daa82603

@SwampDragons
Copy link

@SwampDragons SwampDragons commented Jun 26, 2020

Turns out my particular client key handling needs aren't actually directly relevant to this patch, though the underlying "this module is having some problems with handling rsa sha-2 algorithms" is the same -- I think it needs its own GH issue. I'll work on setting up my own case and my own patch suggestion 😬

@dustymabe
Copy link

@dustymabe dustymabe commented Oct 6, 2020

In order to workaround this issue I tried to use an ecdsa key instead, which worked fine until we hit a brick wall because AWS only supports RSA keys.

Any chance we can increase the priority of the code review in https://go-review.googlesource.com/c/crypto/+/220037/ ?

@FiloSottile
Copy link
Member

@FiloSottile FiloSottile commented Oct 6, 2020

dustymabe added a commit to dustymabe/fedora-coreos-config that referenced this issue Oct 6, 2020
… f33

For F33 let's re-enable RSA-SHA1 keys for now so our kola tests will
work. The plan is to only re-enable this briefly while we wait for
an upstream feature [1] to be implemented. We had moved to an ecdsa
key [2] but AWS doesn't support non RSA keys [3] so we reverted it
for now in [4].

[1] golang/go#37278 (comment)
[2] coreos/coreos-assembler#1749
[3] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#how-to-generate-your-own-key-and-import-it-to-aws
[4] coreos/coreos-assembler#1767
dustymabe added a commit to coreos/fedora-coreos-config that referenced this issue Oct 6, 2020
… f33

For F33 let's re-enable RSA-SHA1 keys for now so our kola tests will
work. The plan is to only re-enable this briefly while we wait for
an upstream feature [1] to be implemented. We had moved to an ecdsa
key [2] but AWS doesn't support non RSA keys [3] so we reverted it
for now in [4].

[1] golang/go#37278 (comment)
[2] coreos/coreos-assembler#1749
[3] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#how-to-generate-your-own-key-and-import-it-to-aws
[4] coreos/coreos-assembler#1767
@SwampDragons
Copy link

@SwampDragons SwampDragons commented Oct 14, 2020

When you look at this one, if you have time to take a look at a related patch over here: #39885 that'd be super rad

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Proposals
Accepted
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants
You can’t perform that action at this time.