| 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) |
| } |