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

signer panic in go1.24 unless crypto.PrivateKey.PublicKey() called #807

Open
sul3n3t opened this issue Feb 20, 2025 · 0 comments
Open

signer panic in go1.24 unless crypto.PrivateKey.PublicKey() called #807

sul3n3t opened this issue Feb 20, 2025 · 0 comments

Comments

@sul3n3t
Copy link

sul3n3t commented Feb 20, 2025

Instructions

I created a minimal reproduction here using flow-go-sdk v1.3.3: https://github.com/sul3n3t/flow-panic

Problem

While updating to go 1.24, some existing code triggered a panic during signing. The panic is caused because stdlib crypto code expects fields of the public component of a private key to be present.

Steps to Reproduce

package flowpanic_test

import (
	"testing"

	"github.com/onflow/flow-go-sdk/crypto"
)

func TestSign(t *testing.T) {
	privateKey, err := crypto.GeneratePrivateKey(crypto.ECDSA_P256, make([]byte, 32))
	if err != nil {
		t.Fatal(err)
	}
	// privateKey.PublicKey() // necessary on go 1.24 to avoid panic

	signer, err := crypto.NewInMemorySigner(privateKey, crypto.SHA3_256)
	if err != nil {
		t.Fatal(err)
	}
	_, err = signer.Sign([]byte("some message"))
	if err != nil {
		t.Fatal(err)
	}
}

Results in

--- FAIL: TestSign (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x10 pc=0x1045aab08]

goroutine 36 [running]:
testing.tRunner.func1.2({0x1047afac0, 0x104958b50})
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/testing/testing.go:1734 +0x1ac
testing.tRunner.func1()
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/testing/testing.go:1737 +0x334
panic({0x1047afac0?, 0x104958b50?})
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/runtime/panic.go:787 +0x124
math/big.(*Int).Sign(...)
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/math/big/int.go:48
crypto/ecdsa.pointFromAffine({0x1047f9910?, 0x104959080?}, 0x0, 0x0)
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/crypto/ecdsa/ecdsa.go:416 +0x38
crypto/ecdsa.privateKeyToFIPS[...](0x140001a6e00, 0x1400019d440)
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/crypto/ecdsa/ecdsa.go:405 +0x3c
crypto/ecdsa.signFIPS[...](0x140001a6e00, 0x14000064cf8, {0x1047f7960?, 0x14000198160}, {0x140001b4480, 0x20, 0x20})
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/crypto/ecdsa/ecdsa.go:244 +0x70
crypto/ecdsa.SignASN1({0x1047f7960, 0x14000198160}, 0x1400019d440, {0x140001b4480, 0x20, 0x20})
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/crypto/ecdsa/ecdsa.go:227 +0x234
crypto/ecdsa.Sign({0x1047f7960?, 0x14000198160?}, 0x1?, {0x140001b4480?, 0x14000064e28?, 0x1045bafa8?})
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/crypto/ecdsa/ecdsa_legacy.go:65 +0x2c
github.com/onflow/crypto.(*prKeyECDSA).signHash(0x140002001e0, {0x140001b4480?, 0x14000064ea8?, 0x104487d7c?})
	/Users/justin/go/pkg/mod/github.com/onflow/[email protected]/ecdsa.go:80 +0x54
github.com/onflow/crypto.(*prKeyECDSA).Sign(0x140002001e0, {0x140001f4660, 0xc, 0xc}, {0x1047f9880, 0x14000216000})
	/Users/justin/go/pkg/mod/github.com/onflow/[email protected]/ecdsa.go:118 +0x1c0
github.com/onflow/flow-go-sdk/crypto.InMemorySigner.Sign(...)
	/Users/justin/go/pkg/mod/github.com/onflow/[email protected]/crypto/crypto.go:133
github.com/sul3n3t/flow-panic_test.TestSign(0x14000184c40)
	/Users/justin/go/src/flow-panic/sign_test.go:20 +0x124
testing.tRunner(0x14000184c40, 0x1047f4bc8)
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/testing/testing.go:1792 +0xe4
created by testing.(*T).Run in goroutine 1
	/Users/justin/go/pkg/mod/golang.org/[email protected]/src/testing/testing.go:1851 +0x374
FAIL	github.com/sul3n3t/flow-panic	0.209s

Acceptance Criteria

The test is expected to pass without calling the .PublicKey() method

Context

I came across this while updating go in a much larger repo. I have a workaround by calling crypto.PrivateKey#PublicKey().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

1 participant