blob: 2fe6348e4afcaa7a04c37f069ffb0922a88b4589 [file] [log] [blame]
package keys
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/hex"
"encoding/json"
"errors"
"io"
"strings"
fuzz "github.com/google/gofuzz"
"github.com/theupdateframework/go-tuf/data"
. "gopkg.in/check.v1"
)
type ECDSASuite struct{}
var _ = Suite(ECDSASuite{})
func (ECDSASuite) TestSignVerify(c *C) {
signer, err := GenerateEcdsaKey()
c.Assert(err, IsNil)
msg := []byte("foo")
sig, err := signer.SignMessage(msg)
c.Assert(err, IsNil)
publicData := signer.PublicData()
pubKey, err := GetVerifier(publicData)
c.Assert(err, IsNil)
c.Assert(pubKey.Verify(msg, sig), IsNil)
}
func (ECDSASuite) TestECDSAVerifyMismatchMessage(c *C) {
signer, err := GenerateEcdsaKey()
c.Assert(err, IsNil)
msg := []byte("foo")
sig, err := signer.SignMessage(msg)
c.Assert(err, IsNil)
publicData := signer.PublicData()
pubKey, err := GetVerifier(publicData)
c.Assert(err, IsNil)
c.Assert(pubKey.Verify([]byte("notfoo"), sig), ErrorMatches, "tuf: ecdsa signature verification failed")
}
func (ECDSASuite) TestECDSAVerifyMismatchPubKey(c *C) {
signer, err := GenerateEcdsaKey()
c.Assert(err, IsNil)
msg := []byte("foo")
sig, err := signer.SignMessage(msg)
c.Assert(err, IsNil)
signerNew, err := GenerateEcdsaKey()
c.Assert(err, IsNil)
pubKey, err := GetVerifier(signerNew.PublicData())
c.Assert(err, IsNil)
c.Assert(pubKey.Verify([]byte("notfoo"), sig), ErrorMatches, "tuf: ecdsa signature verification failed")
}
func (ECDSASuite) TestSignVerifyDeprecatedFails(c *C) {
// Create an ecdsa key with a deprecated format.
signer, err := GenerateEcdsaKey()
c.Assert(err, IsNil)
type deprecatedP256Verifier struct {
PublicKey data.HexBytes `json:"public"`
}
pub := signer.PublicKey
keyValBytes, err := json.Marshal(&deprecatedP256Verifier{PublicKey: elliptic.Marshal(pub.Curve, pub.X, pub.Y)})
c.Assert(err, IsNil)
publicData := &data.PublicKey{
Type: data.KeyTypeECDSA_SHA2_P256,
Scheme: data.KeySchemeECDSA_SHA2_P256,
Algorithms: data.HashAlgorithms,
Value: keyValBytes,
}
_, err = GetVerifier(publicData)
c.Assert(err, ErrorMatches, "tuf: error unmarshalling key: invalid PEM value")
}
func (ECDSASuite) TestMarshalUnmarshalPublicKey(c *C) {
signer, err := GenerateEcdsaKey()
c.Assert(err, IsNil)
publicData := signer.PublicData()
pubKey, err := GetVerifier(publicData)
c.Assert(err, IsNil)
c.Assert(pubKey.MarshalPublicKey(), DeepEquals, publicData)
}
func (ECDSASuite) TestMarshalUnmarshalPrivateKey(c *C) {
signer, err := GenerateEcdsaKey()
c.Assert(err, IsNil)
privateData, err := signer.MarshalPrivateKey()
c.Assert(err, IsNil)
c.Assert(privateData.Type, Equals, data.KeyTypeECDSA_SHA2_P256)
c.Assert(privateData.Scheme, Equals, data.KeySchemeECDSA_SHA2_P256)
c.Assert(privateData.Algorithms, DeepEquals, data.HashAlgorithms)
s, err := GetSigner(privateData)
c.Assert(err, IsNil)
c.Assert(s, DeepEquals, signer)
}
func (ECDSASuite) TestUnmarshalECDSA(c *C) {
priv, err := ecdsa.GenerateKey(elliptic.P256(), strings.NewReader("00001-deterministic-buffer-for-key-generation"))
c.Assert(err, IsNil)
signer := &ecdsaSigner{priv}
goodKey := signer.PublicData()
verifier := NewEcdsaVerifier()
c.Assert(verifier.UnmarshalPublicKey(goodKey), IsNil)
}
func (ECDSASuite) TestUnmarshalECDSA_Invalid(c *C) {
badKeyValue, err := json.Marshal(true)
c.Assert(err, IsNil)
badKey := &data.PublicKey{
Type: data.KeyTypeECDSA_SHA2_P256,
Scheme: data.KeySchemeECDSA_SHA2_P256,
Algorithms: data.HashAlgorithms,
Value: badKeyValue,
}
verifier := NewEcdsaVerifier()
c.Assert(verifier.UnmarshalPublicKey(badKey), ErrorMatches, "json: cannot unmarshal.*")
}
func (ECDSASuite) TestUnmarshalECDSA_FastFuzz(c *C) {
verifier := NewEcdsaVerifier()
for i := 0; i < 50; i++ {
// Ensure no basic panic
f := fuzz.New()
var publicData data.PublicKey
f.Fuzz(&publicData)
verifier.UnmarshalPublicKey(&publicData)
}
}
func (ECDSASuite) TestUnmarshalECDSA_TooLongContent(c *C) {
randomSeed := make([]byte, MaxJSONKeySize)
_, err := io.ReadFull(rand.Reader, randomSeed)
c.Assert(err, IsNil)
tooLongPayload, err := json.Marshal(
&ed25519Verifier{
PublicKey: data.HexBytes(hex.EncodeToString(randomSeed)),
},
)
c.Assert(err, IsNil)
badKey := &data.PublicKey{
Type: data.KeyTypeECDSA_SHA2_P256,
Scheme: data.KeySchemeECDSA_SHA2_P256,
Algorithms: data.HashAlgorithms,
Value: tooLongPayload,
}
verifier := NewEcdsaVerifier()
err = verifier.UnmarshalPublicKey(badKey)
c.Assert(errors.Is(err, io.ErrUnexpectedEOF), Equals, true)
}