Skip to content

Commit

Permalink
simplify key interface
Browse files Browse the repository at this point in the history
Signed-off-by: Asra Ali <[email protected]>
  • Loading branch information
asraa committed Sep 7, 2021
1 parent d5bb678 commit 6323948
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 143 deletions.
8 changes: 4 additions & 4 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ func (s *ClientSuite) TestNewRoot(c *C) {
for _, id := range ids {
key, err := client.db.GetKey(id)
c.Assert(err, IsNil)
c.Assert(key.IDs(), DeepEquals, ids)
c.Assert(key.MarshalKey().IDs(), DeepEquals, ids)
}
role := client.db.GetRole(name)
c.Assert(role, NotNil)
Expand Down Expand Up @@ -413,7 +413,7 @@ func (s *ClientSuite) TestNewTimestampKey(c *C) {
for _, newID := range newIDs {
key, err := client.db.GetKey(newID)
c.Assert(err, IsNil)
c.Assert(key.IDs(), DeepEquals, newIDs)
c.Assert(key.MarshalKey().IDs(), DeepEquals, newIDs)
}
role := client.db.GetRole("timestamp")
c.Assert(role, NotNil)
Expand Down Expand Up @@ -453,7 +453,7 @@ func (s *ClientSuite) TestNewSnapshotKey(c *C) {
for _, newID := range newIDs {
key, err := client.db.GetKey(newID)
c.Assert(err, IsNil)
c.Assert(key.IDs(), DeepEquals, newIDs)
c.Assert(key.MarshalKey().IDs(), DeepEquals, newIDs)
}
role := client.db.GetRole("snapshot")
c.Assert(role, NotNil)
Expand Down Expand Up @@ -496,7 +496,7 @@ func (s *ClientSuite) TestNewTargetsKey(c *C) {
for _, newID := range newIDs {
key, err := client.db.GetKey(newID)
c.Assert(err, IsNil)
c.Assert(key.IDs(), DeepEquals, newIDs)
c.Assert(key.MarshalKey().IDs(), DeepEquals, newIDs)
}
role := client.db.GetRole("targets")
c.Assert(role, NotNil)
Expand Down
2 changes: 1 addition & 1 deletion client/testdata/go-tuf-transition-M3/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func revokeKeys(repo *tuf.Repo, role string, keyList []*data.PrivateKey) {
for _, key := range keyList {
signer, err := keys.GetSigner(key)
assertNotNil(err)
assertNotNil(repo.RevokeKeyWithExpires(role, signer.IDs()[0], expirationDate))
assertNotNil(repo.RevokeKeyWithExpires(role, signer.PublicData().IDs()[0], expirationDate))
}
}

Expand Down
2 changes: 1 addition & 1 deletion client/testdata/go-tuf/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func revokeKeys(repo *tuf.Repo, role string, keyList []*data.PrivateKey) {
for _, key := range keyList {
signer, err := keys.GetSigner(key)
assertNotNil(err)
assertNotNil(repo.RevokeKeyWithExpires(role, signer.IDs()[0], expirationDate))
assertNotNil(repo.RevokeKeyWithExpires(role, signer.PublicData().IDs()[0], expirationDate))
}
}

Expand Down
12 changes: 4 additions & 8 deletions keys/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ import (
)

func init() {
KeyMap.Store(data.KeyTypeECDSA_SHA2_P256, NewEcdsa)
VerifierMap.Store(data.KeyTypeECDSA_SHA2_P256, NewEcdsaVerifier)
}

func NewEcdsa() SignerVerifier {
sv := SignerVerifier{
Signer: nil,
Verifier: &p256Verifier{},
}
return sv
func NewEcdsaVerifier() Verifier {
return &p256Verifier{}
}

type ecdsaSignature struct {
Expand Down Expand Up @@ -58,7 +54,7 @@ func (p *p256Verifier) Verify(msg, sigBytes []byte) error {
return nil
}

func (p *p256Verifier) Key() *data.Key {
func (p *p256Verifier) MarshalKey() *data.Key {
return p.key
}

Expand Down
63 changes: 19 additions & 44 deletions keys/ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@ import (
"crypto/rand"
"encoding/json"
"errors"
"sync"

"github.com/theupdateframework/go-tuf/data"
)

func init() {
KeyMap.Store(data.KeySchemeEd25519, NewP256)
SignerMap.Store(data.KeySchemeEd25519, NewP256Signer)
VerifierMap.Store(data.KeySchemeEd25519, NewP256Verifier)

}

func NewP256() SignerVerifier {
sv := SignerVerifier{
Signer: &ed25519Signer{},
Verifier: &ed25519Verifier{},
}
return sv
func NewP256Signer() Signer {
return &ed25519Signer{}
}

func NewP256Verifier() Verifier {
return &ed25519Verifier{}
}

type ed25519Verifier struct {
Expand All @@ -38,7 +39,7 @@ func (e *ed25519Verifier) Verify(msg, sig []byte) error {
return nil
}

func (e *ed25519Verifier) Key() *data.Key {
func (e *ed25519Verifier) MarshalKey() *data.Key {
return e.key
}

Expand All @@ -62,6 +63,14 @@ type ed25519PrivateKeyValue struct {
Private data.HexBytes `json:"private"`
}

type ed25519Signer struct {
ed25519.PrivateKey

keyType string
keyScheme string
keyAlgorithms []string
}

func GenerateEd25519Key() (*ed25519Signer, error) {
_, private, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
Expand All @@ -78,7 +87,7 @@ func GenerateEd25519Key() (*ed25519Signer, error) {
}, nil
}

func (e *ed25519Signer) MarshalPrivate() (*data.PrivateKey, error) {
func (e *ed25519Signer) MarshalSigner() (*data.PrivateKey, error) {
valueBytes, err := json.Marshal(ed25519PrivateKeyValue{
Public: data.HexBytes([]byte(e.PrivateKey.Public().(ed25519.PublicKey))),
Private: data.HexBytes(e.PrivateKey),
Expand Down Expand Up @@ -117,37 +126,3 @@ func (e *ed25519Signer) PublicData() *data.Key {
Value: keyValBytes,
}
}

type ed25519Signer struct {
ed25519.PrivateKey

keyType string
keyScheme string
keyAlgorithms []string
ids []string
idOnce sync.Once
}

// var _ Signer = &ed25519Signer{}

func (s *ed25519Signer) IDs() []string {
s.idOnce.Do(func() { s.ids = s.PublicData().IDs() })
return s.ids
}

func (s *ed25519Signer) ContainsID(id string) bool {
for _, keyid := range s.IDs() {
if id == keyid {
return true
}
}
return false
}

func (s *ed25519Signer) Type() string {
return s.keyType
}

func (s *ed25519Signer) Scheme() string {
return s.keyScheme
}
24 changes: 24 additions & 0 deletions keys/ed25519_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package keys

import (
"crypto"
"crypto/rand"

. "gopkg.in/check.v1"
)

type Ed25519Suite struct{}

var _ = Suite(&Ed25519Suite{})

func (Ed25519Suite) TestSignVerify(c *C) {
key, err := GenerateEd25519Key()
c.Assert(err, IsNil)
msg := []byte("foo")
sig, err := key.Sign(rand.Reader, msg, crypto.Hash(0))
c.Assert(err, IsNil)
publicData := key.PublicData()

This comment has been minimized.

Copy link
@trishankatdatadog

trishankatdatadog Sep 7, 2021

Member

I might be missing something, but why can't GetVerifier() be a method of the key?

pubKey, err := GetVerifier(publicData)
c.Assert(err, IsNil)
c.Assert(pubKey.Verify(msg, sig), IsNil)
}
55 changes: 16 additions & 39 deletions keys/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import (
"github.com/theupdateframework/go-tuf/data"
)

// KeyMap stores mapping between key type strings and verifier constructors.
var KeyMap sync.Map
// SignerMap stores mapping between key type strings and signer constructors.
var SignerMap sync.Map

type SignerVerifier struct {
Signer Signer
Verifier Verifier
}
// Verifier stores mapping between key type strings and verifier constructors.
var VerifierMap sync.Map

var (
ErrInvalid = errors.New("tuf: signature verification failed")
Expand All @@ -28,75 +26,54 @@ type Verifier interface {
// to verify signatures.
UnmarshalKey(key *data.Key) error

// Key returns the data.Key object associated with the verifier.
MarshalKey() *data.Key

// This is the public string used as a unique identifier for the verifier instance.
Public() string

// IDs returns the TUF key ids
IDs() []string

// Verify takes a message and signature, all as byte slices,
// and determines whether the signature is valid for the given
// key and message.
Verify(msg, sig []byte) error

// Key returns the data.Key object associated with the verifier.
Key() *data.Key
}

type Signer interface {
// Marshal into a private key.
MarshalPrivate() (*data.PrivateKey, error)
MarshalSigner() (*data.PrivateKey, error)

// UnmarshalKey takes private key data to a working Signer implementation for the key type.
UnmarshalSigner(key *data.PrivateKey) error

// Returns the public data.Key from the private key
PublicData() *data.Key

// IDs returns the TUF key ids
IDs() []string

// ContainsID returns if the signer contains the key id
ContainsID(id string) bool

// Type returns the TUF key type
Type() string

// Scheme returns the TUF key scheme
Scheme() string

// Signer is used to sign messages and provides access to the public key.
// The signer is expected to do its own hashing, so the full message will be
// provided as the message to Sign with a zero opts.HashFunc().
crypto.Signer
}

func GetVerifier(key *data.Key) (Verifier, error) {
st, ok := KeyMap.Load(key.Type)
st, ok := VerifierMap.Load(key.Type)
if !ok {
return nil, ErrInvalidKey
}
s := st.(func() SignerVerifier)()
if s.Verifier == nil {
s := st.(func() Verifier)()
if err := s.UnmarshalKey(key); err != nil {
return nil, ErrInvalidKey
}
if err := s.Verifier.UnmarshalKey(key); err != nil {
return nil, ErrInvalidKey
}
return s.Verifier, nil
return s, nil
}

func GetSigner(key *data.PrivateKey) (Signer, error) {
st, ok := KeyMap.Load(key.Type)
st, ok := SignerMap.Load(key.Type)
if !ok {
return nil, ErrInvalidKey
}
s := st.(func() SignerVerifier)()
if s.Signer == nil {
return nil, ErrInvalidKey
}
if err := s.Signer.UnmarshalSigner(key); err != nil {
s := st.(func() Signer)()
if err := s.UnmarshalSigner(key); err != nil {
return nil, ErrInvalidKey
}
return s.Signer, nil
return s, nil
}
7 changes: 2 additions & 5 deletions keys/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,23 @@ var _ = Suite(&KeysSuite{})
func (KeysSuite) TestSignerKeyIDs(c *C) {
key, err := GenerateEd25519Key()
c.Assert(err, IsNil)
c.Assert(key.PublicData().IDs(), DeepEquals, key.IDs())

// If we have a TUF-0.9 key, we won't have a scheme.
key, err = GenerateEd25519Key()
c.Assert(err, IsNil)
privKey, err := key.MarshalPrivate()
privKey, err := key.MarshalSigner()
c.Assert(err, IsNil)
privKey.Scheme = ""
err = key.UnmarshalSigner(privKey)
c.Assert(err, IsNil)
c.Assert(key.PublicData().IDs(), DeepEquals, key.IDs())

// Make sure we preserve ids if we don't have any
// keyid_hash_algorithms.
key, err = GenerateEd25519Key()
c.Assert(err, IsNil)
privKey, err = key.MarshalPrivate()
privKey, err = key.MarshalSigner()
c.Assert(err, IsNil)
privKey.Algorithms = []string{}
err = key.UnmarshalSigner(privKey)
c.Assert(err, IsNil)
c.Assert(key.PublicData().IDs(), DeepEquals, key.IDs())
}
4 changes: 2 additions & 2 deletions repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ func (r *Repo) AddPrivateKeyWithExpires(keyRole string, key keys.Signer, expires
return ErrInvalidExpires{expires}
}

privKey, err := key.MarshalPrivate()
privKey, err := key.MarshalSigner()
if err != nil {
return err
}
Expand Down Expand Up @@ -640,7 +640,7 @@ func (r *Repo) getSigningKeys(name string) ([]keys.Signer, error) {
}
keys := make([]keys.Signer, 0, len(role.KeyIDs))
for _, key := range signingKeys {
for _, id := range key.IDs() {
for _, id := range key.PublicData().IDs() {
if _, ok := role.KeyIDs[id]; ok {
keys = append(keys, key)
}
Expand Down
Loading

0 comments on commit 6323948

Please sign in to comment.