golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.32k stars 17.58k forks source link

x/crypto: ssh/client.NewSession() fails when remote key has an exponent greater than 24b #50711

Open bpizzi opened 2 years ago

bpizzi commented 2 years ago

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

go version go1.17.5 linux/amd64

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
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.5"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/gedix/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build309787458=/tmp/go-build -gno-record-gcc-switches"

What did you do?

When trying to open a ssh session to a LSH server (lshd-1.4.3, secsh protocol version 2.0).

package main

import (
    "golang.org/x/crypto/ssh"
    "log"
)

func main() {
    user := "REDACTED"
    password := "REDACTED"
    host := "REDACTED"

    sshConfig := &ssh.ClientConfig{
        User:            user,
        Auth:            []ssh.AuthMethod{ssh.Password(password)},
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }

    client, dialErr := ssh.Dial("tcp", host, sshConfig)
    if dialErr != nil {
        log.Fatalf("dial: %s\n", dialErr)
    }

    if _, sessErr := client.NewSession(); sessErr != nil {
        log.Fatalf("session: %s\n", sessErr)
    }
    defer client.Close()
}

What did you expect to see?

No error on NewSession()

What did you see instead?

2022/01/20 12:02:05 dial: ssh: handshake failed: ssh: exponent too large

OTOH, openssh client connects successfully, giving that I specifies the expected values for KexAlgorithms and HostKeyAlgorithms (setting those in Go's ssh config doesn't help).

> ssh -v [HOST]
OpenSSH_8.8p1, OpenSSL 1.1.1m  14 Dec 2021
debug1: Connection established.
[...]
debug1: Local version string SSH-2.0-OpenSSH_8.8
debug1: Remote protocol version 2.0, remote software version lshd_1.4.3 lsh - a free ssh
debug1: compat_banner: no match: lshd_1.4.3 lsh - a free ssh
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: diffie-hellman-group1-sha1
debug1: kex: host key algorithm: ssh-rsa
debug1: kex: server->client cipher: aes256-ctr MAC: hmac-sha1 compression: none
debug1: kex: client->server cipher: aes256-ctr MAC: hmac-sha1 compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Server host key: ssh-rsa SHA256:lWlSUxbsOy5xtg3vvLTJaI1IrmwMjgoANXnFL+8sSzI
[...]
debug1: Authentications that can continue: password,publickey
[...]
debug1: Next authentication method: password
[success]

As a workaround, I managed to successfully establish the session by changing the max bit len to 31 (instead of actually 24) in x/crypto/ssh/keys.go:353 in ParseRSA().

heschi commented 2 years ago

cc @FiloSottile @agl @katiehockman @rolandshoemaker

rolandshoemaker commented 2 years ago

Why are you using a key with such a large exponent? Is this the default in lshd, or a key you've generated yourself?

We explicitly don't support such large exponents, since they provide little to no benefit. See https://github.com/golang/go/issues/3161 and https://codereview.appspot.com/5650067 for previous discussion (also https://www.imperialviolet.org/2012/03/16/rsae.html).

bpizzi commented 2 years ago

Hey, thanks for having a look at it.

Why are you using a key with such a large exponent? Is this the default in lshd, or a key you've generated yourself?

Actually I don't have a say on this, I'm trying to connect to a server where the key is as-is and can't be changed (its an appliance provided by a BigCorp). I not sure how the key have been generated.

We explicitly don't support such large exponents, since they provide little to no benefit. See #3161 and https://codereview.appspot.com/5650067 for previous discussion (also https://www.imperialviolet.org/2012/03/16/rsae.html).

Thanks for this, as its nice to have some background intel on how this came to be.

Do you think the decision for not handling big exponent is susceptible to being re evaluated in the regard of the present issue? Otherwise I'll move on, and at least we'll have a searchable issue here referencing for exponent too large ;)

rolandshoemaker commented 2 years ago

Thanks for the context.

This issue has popped up sparingly in the last decade since this was first discussed. Given how rare it is, and without some serious issue with RSA that requires everyone to switch to giant exponents, I don't think we'll be reconsidering this decision.