golang/go

crypto/ecdsa: signature verification succeeds when it should fail

guidovranken opened this issue · 4 comments

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

go version devel +b53df56 Fri Oct 30 19:00:33 2020 +0000 linux/amd64

Does this issue reproduce with the latest release?

I think so.

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

GO111MODULE="off"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/jhg/.cache/go-build"
GOENV="/home/jhg/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/mnt/2tb/golang/go/packages/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/mnt/2tb/golang/go/packages"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/mnt/2tb/golang/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/mnt/2tb/golang/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build057338421=/tmp/go-build -gno-record-gcc-switches"

What did you do?

https://play.golang.org/p/cpkYx0J-eh5

What did you expect to see?

Console output:

false

What did you see instead?

Console output:

true

Notes

Found with fuzzing, hence the odd values.

It looks like the public key point is not on the curve, so I don't think there is any defined behavior we're supposed to follow here. As an issue it seems harmless because 1) any public key decoding function like elliptic.Unmarshal or x509.ParsePKIXPublicKey will check that the point is on the curve and 2) an attacker generally doesn't control the ECDSA public key, or they would just pick one for which they know the private key.

https://play.golang.org/p/DfYlrn_lObX

Is there anything particular about this input? Why should it fail verification?

To add to @FiloSottile s response:

If for some reason you parse the PublicKey yourself, you can easily check if it's a valid public key by calling elliptic.CurveParams.IsOnCurve(x, y):

https://play.golang.org/p/YxY4nJ8k8Nm

But consider using parsing functions provided by the standard library. They check for you if the provided public key is valid.

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)