Skip to content

Commit

Permalink
chore: migrate to crypto/ecdh
Browse files Browse the repository at this point in the history
Signed-off-by: Shiwei Zhang <[email protected]>
  • Loading branch information
shizhMSFT committed Dec 13, 2023
1 parent 5de23d9 commit 88e4632
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 27 deletions.
12 changes: 0 additions & 12 deletions ecdsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,18 +172,6 @@ func generateTestECDSAKey(t *testing.T) *ecdsa.PrivateKey {
return key
}

func Test_customCurveKeySigner(t *testing.T) {
// https://github.com/veraison/go-cose/issues/59
pCustom := *elliptic.P256().Params()
pCustom.Name = "P-custom"
pCustom.BitSize /= 2
key, err := ecdsa.GenerateKey(&pCustom, rand.Reader)
if err != nil {
t.Fatalf("ecdsa.GenerateKey() error = %v", err)
}
testSignVerify(t, AlgorithmES256, key, false)
}

func Test_ecdsaKeySigner(t *testing.T) {
key := generateTestECDSAKey(t)
testSignVerify(t, AlgorithmES256, key, false)
Expand Down
46 changes: 34 additions & 12 deletions key.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package cose

import (
"crypto"
"crypto/ecdh"

Check failure on line 5 in key.go

View workflow job for this annotation

GitHub Actions / tests (1.18)

package crypto/ecdh is not in GOROOT (/opt/hostedtoolcache/go/1.18.10/x64/src/crypto/ecdh)

Check failure on line 5 in key.go

View workflow job for this annotation

GitHub Actions / tests (1.19)

package crypto/ecdh is not in GOROOT (/opt/hostedtoolcache/go/1.19.13/x64/src/crypto/ecdh)
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/x509"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -703,27 +705,47 @@ func (k *Key) PrivateKey() (crypto.PrivateKey, error) {

switch alg {
case AlgorithmES256, AlgorithmES384, AlgorithmES512:
var curve elliptic.Curve

switch alg {
case AlgorithmES256:
curve = elliptic.P256()
case AlgorithmES384:
curve = elliptic.P384()
case AlgorithmES512:
curve = elliptic.P521()
}

_, x, y, d := k.EC2()
var bx, by *big.Int
if len(x) == 0 || len(y) == 0 {
bx, by = curve.ScalarBaseMult(d)
var curve ecdh.Curve
switch alg {
case AlgorithmES256:
curve = ecdh.P256()
case AlgorithmES384:
curve = ecdh.P384()
case AlgorithmES512:
curve = ecdh.P521()
}
privateKey, err := curve.NewPrivateKey(d)
if err != nil {
return nil, err
}
encodedKey, err := x509.MarshalPKIXPublicKey(privateKey.PublicKey())
if err != nil {
return nil, err
}
decodedKey, err := x509.ParsePKIXPublicKey(encodedKey)
if err != nil {
return nil, err
}
publicKey := decodedKey.(*ecdsa.PublicKey)
bx, by = publicKey.X, publicKey.Y
} else {
bx = new(big.Int).SetBytes(x)
by = new(big.Int).SetBytes(y)
}
bd := new(big.Int).SetBytes(d)

var curve elliptic.Curve
switch alg {
case AlgorithmES256:
curve = elliptic.P256()
case AlgorithmES384:
curve = elliptic.P384()
case AlgorithmES512:
curve = elliptic.P521()
}
return &ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{Curve: curve, X: bx, Y: by},
D: bd,
Expand Down
9 changes: 7 additions & 2 deletions verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ type DigestVerifier interface {
// NewVerifier returns a verifier with a given public key.
// Only golang built-in crypto public keys of type `*rsa.PublicKey`,
// `*ecdsa.PublicKey`, and `ed25519.PublicKey` are accepted.
// When `*ecdsa.PublicKey` is specified, its curve must be supported by
// crypto/ecdh.
//
// The returned signer for rsa and ecdsa keys also implements `cose.DigestSigner`.
func NewVerifier(alg Algorithm, key crypto.PublicKey) (Verifier, error) {
Expand All @@ -60,8 +62,11 @@ func NewVerifier(alg Algorithm, key crypto.PublicKey) (Verifier, error) {
if !ok {
return nil, fmt.Errorf("%v: %w", alg, ErrInvalidPubKey)
}
if !vk.Curve.IsOnCurve(vk.X, vk.Y) {
return nil, errors.New("public key point is not on curve")
if _, err := vk.ECDH(); err != nil {
if err.Error() == "ecdsa: invalid public key" {
return nil, fmt.Errorf("%v: %w", alg, ErrInvalidPubKey)
}
return nil, fmt.Errorf("%v: %w: %v", alg, ErrInvalidPubKey, err)
}
return &ecdsaVerifier{
alg: alg,
Expand Down
15 changes: 14 additions & 1 deletion verifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ func TestNewVerifier(t *testing.T) {
// craft an EC public key with the x-coord not on curve
ecdsaKeyPointNotOnCurve := generateBogusECKey()

// craft an EC public key with a curve not supported by crypto/ecdh
ecdsaKeyUnsupportedCurve := &ecdsa.PublicKey{
Curve: ecdsaKey.Curve.Params(),
X: ecdsaKey.X,
Y: ecdsaKey.Y,
}

// run tests
tests := []struct {
name string
Expand Down Expand Up @@ -125,7 +132,13 @@ func TestNewVerifier(t *testing.T) {
name: "bogus ecdsa public key (point not on curve)",
alg: AlgorithmES256,
key: ecdsaKeyPointNotOnCurve,
wantErr: "public key point is not on curve",
wantErr: "ES256: invalid public key",
},
{
name: "ecdsa public key with unsupported curve",
alg: AlgorithmES256,
key: ecdsaKeyUnsupportedCurve,
wantErr: "ES256: invalid public key: ecdsa: unsupported curve by crypto/ecdh",
},
}
for _, tt := range tests {
Expand Down

0 comments on commit 88e4632

Please sign in to comment.