Skip to content

x/crypto/ssh: allow unpadded signatures #68286

Closed
@imirkin

Description

@imirkin

Go version

go version go1.20.13 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=""
GOARCH="amd64"
GOVERSION="go1.20.13"
GCCGO="gccgo"
GOAMD64="v1"

What did you do?

Connect a lot of times to the SSH server with an RSA public key using PuTTY.

What did you see happen?

Occasional login failures with crypto/rsa: verification error

What did you expect to see?

All successes.

The issue is due to a short signature, rejected by rsa.VerifyPKCS1v15.

https://datatracker.ietf.org/doc/html/rfc4253#section-6.6

The resulting signature is encoded as follows:

  string    "ssh-rsa"
  string    rsa_signature_blob

The value for 'rsa_signature_blob' is encoded as a string containing
s (which is an integer, without lengths or padding, unsigned, and in
network byte order).

Which requires the signature to be unpadded.

I spoke with the PuTTY maintainer about this, Simon Tatham. His view is that the SSH RFC supercedes the PKCS RFC (8017), so the short signature is OK (in fact required).

However this approach is reversed in

https://datatracker.ietf.org/doc/html/rfc8332#section-3

The resulting signature is encoded as follows:

string "rsa-sha2-256" / "rsa-sha2-512"
string rsa_signature_blob

The value for 'rsa_signature_blob' is encoded as a string that
contains an octet string S (which is the output of RSASSA-PKCS1-v1_5)
and that has the same length (in octets) as the RSA modulus. When S
contains leading zeros, there exist signers that will send a shorter
encoding of S that omits them. A verifier MAY accept shorter
encodings of S with one or more leading zeros omitted.

and I believe that PuTTY may be fixed for this when using the new signature types (or even always). But even if it is, lots of PuTTY installs out there that will not be updated for a long time. (And WinSCP embeds PuTTY, thus has a similar issue... FileZilla as well potentially.)

In practice, the OpenSSH verify logic always allows unpadded signatures, while the sign logic always pads them (at least based on a quick read of https://github.com/openssh/openssh-portable/blob/master/ssh-rsa.c ssh_rsa_sign and ssh_rsa_verify). The current Go implementation is out of spec for ssh-rsa signatures, but it would be the flexible thing to do to also always allow the short signatures, as this is allowed by the RFC and (arguably) the most popular SSH server.

I'm happy to write up a patch if there are any prospects of it being accepted (past experience suggests this is best left to the core team though).

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions