From 167a07c8945e2a4b202e7254f9e4e12db61ec10e Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Wed, 15 Jul 2015 17:06:17 -0700 Subject: [PATCH] Change notary-signer to use gotuf's key types This causes notary-signer to use gotuf's Key interface instead of defining its own redundant types. We can go further with this in the future by removing the redundant ED25519 implementation. This would be refactored into the cryptoservice package, and notary-signer would be changed to use that package's cryptoservice for key creation and signing operations. Signed-off-by: Aaron Lehmann --- cmd/notary-signer/main.go | 5 +- signer/api/api.go | 3 +- signer/api/api_test.go | 25 +++++----- signer/api/ed25519_signer.go | 13 ++--- signer/api/ed25519_signer_test.go | 8 ++-- signer/api/ed25519_signing_service.go | 13 ++--- signer/api/ed25519_signing_service_test.go | 9 ++-- signer/api/rpc_api.go | 3 +- signer/api/rpc_api_test.go | 15 +++--- signer/api/rsa_signing_service.go | 26 ++++------ signer/keys/key_db.go | 19 ++++---- signer/keys/keys.go | 56 +++++++++++++++++----- signer/signer.go | 8 ++-- 13 files changed, 112 insertions(+), 91 deletions(-) diff --git a/cmd/notary-signer/main.go b/cmd/notary-signer/main.go index 1ed4764387..bf6c6aa57b 100644 --- a/cmd/notary-signer/main.go +++ b/cmd/notary-signer/main.go @@ -17,6 +17,7 @@ import ( "github.com/docker/notary/signer" "github.com/docker/notary/signer/api" "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" "github.com/miekg/pkcs11" pb "github.com/docker/notary/proto" @@ -78,10 +79,10 @@ func main() { defer cleanup(ctx, session) - sigServices[api.RSAAlgorithm] = api.NewRSASigningService(ctx, session) + sigServices[data.RSAKey] = api.NewRSASigningService(ctx, session) } - sigServices[api.ED25519] = api.EdDSASigningService{KeyDB: keys.NewKeyDB()} + sigServices[data.ED25519Key] = api.EdDSASigningService{KeyDB: keys.NewKeyDB()} //RPC server setup kms := &api.KeyManagementServer{SigServices: sigServices} diff --git a/signer/api/api.go b/signer/api/api.go index 8f8a7480b9..84dd3be48f 100644 --- a/signer/api/api.go +++ b/signer/api/api.go @@ -6,6 +6,7 @@ import ( "github.com/docker/notary/signer" "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" "github.com/gorilla/mux" pb "github.com/docker/notary/proto" @@ -32,7 +33,7 @@ func getSigningService(w http.ResponseWriter, algorithm string, sigServices sign return nil } - service := sigServices[algorithm] + service := sigServices[data.KeyAlgorithm(algorithm)] if service == nil { http.Error(w, "algorithm "+algorithm+" not supported", http.StatusBadRequest) diff --git a/signer/api/api_test.go b/signer/api/api_test.go index 462c505578..14f7090be7 100644 --- a/signer/api/api_test.go +++ b/signer/api/api_test.go @@ -14,6 +14,7 @@ import ( "github.com/docker/notary/signer" "github.com/docker/notary/signer/api" "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" "github.com/miekg/pkcs11" "github.com/stretchr/testify/assert" @@ -76,7 +77,7 @@ func TestDeleteKeyHandlerReturns404WithNonexistentKey(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) fakeID := "c62e6d68851cef1f7e55a9d56e3b0c05f3359f16838cad43600f0554e7d3b54d" @@ -97,7 +98,7 @@ func TestDeleteKeyHandler(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) key, _ := sigService.CreateKey() @@ -117,7 +118,7 @@ func TestKeyInfoHandler(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) key, _ := sigService.CreateKey() @@ -144,7 +145,7 @@ func TestKeyInfoHandlerReturns404WithNonexistentKey(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) fakeID := "c62e6d68851cef1f7e55a9d56e3b0c05f3359f16838cad43600f0554e7d3b54d" keyInfoURL := fmt.Sprintf("%s/%s", keyInfoBaseURL, fakeID) @@ -168,9 +169,9 @@ func TestHSMCreateKeyHandler(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewRSASigningService(ctx, session) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) - createKeyURL := fmt.Sprintf("%s/%s", createKeyBaseURL, api.RSAAlgorithm) + createKeyURL := fmt.Sprintf("%s/%s", createKeyBaseURL, data.RSAKey) request, err := http.NewRequest("POST", createKeyURL, nil) assert.Nil(t, err) @@ -192,9 +193,9 @@ func TestSoftwareCreateKeyHandler(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) - createKeyURL := fmt.Sprintf("%s/%s", createKeyBaseURL, api.ED25519) + createKeyURL := fmt.Sprintf("%s/%s", createKeyBaseURL, data.ED25519Key) request, err := http.NewRequest("POST", createKeyURL, nil) assert.Nil(t, err) @@ -222,7 +223,7 @@ func TestHSMSignHandler(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewRSASigningService(ctx, session) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) key, _ := sigService.CreateKey() @@ -253,7 +254,7 @@ func TestSoftwareSignHandler(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) key, err := sigService.CreateKey() assert.Nil(t, err) @@ -286,7 +287,7 @@ func TestSoftwareSignWithInvalidRequestHandler(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) requestJson := "{\"blob\":\"7d16f1d0b95310a7bc557747fc4f20fcd41c1c5095ae42f189df0717e7d7f4a0a2b55debce630f43c4ac099769c612965e3fda3cd4c0078ee6a460f14fa19307\"}" reader = strings.NewReader(requestJson) @@ -311,7 +312,7 @@ func TestSignHandlerReturns404WithNonexistentKey(t *testing.T) { // We associate both key types with this signing service to bypass the // ID -> keyType logic in the tests sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - setup(signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService}) + setup(signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService}) fakeID := "c62e6d68851cef1f7e55a9d56e3b0c05f3359f16838cad43600f0554e7d3b54d" diff --git a/signer/api/ed25519_signer.go b/signer/api/ed25519_signer.go index 844ea57232..1c83c14bcc 100644 --- a/signer/api/ed25519_signer.go +++ b/signer/api/ed25519_signer.go @@ -2,29 +2,26 @@ package api import ( "github.com/agl/ed25519" - "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" pb "github.com/docker/notary/proto" ) -// ED25519 represents an ed25519 algorithm -const ED25519 string = "ed25519" - // Ed25519Signer implements the Signer interface for Ed25519 keys type Ed25519Signer struct { - privateKey *keys.Key + privateKey data.Key } // Sign returns a signature for a given blob func (s *Ed25519Signer) Sign(request *pb.SignatureRequest) (*pb.Signature, error) { priv := [ed25519.PrivateKeySize]byte{} - copy(priv[:], s.privateKey.Private[:]) + copy(priv[:], s.privateKey.Private()) sig := ed25519.Sign(&priv, request.Content) - return &pb.Signature{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: s.privateKey.ID}, Algorithm: &pb.Algorithm{Algorithm: ED25519}}, Content: sig[:]}, nil + return &pb.Signature{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: s.privateKey.ID()}, Algorithm: &pb.Algorithm{Algorithm: data.ED25519Key.String()}}, Content: sig[:]}, nil } // NewEd25519Signer returns a Ed25519Signer, given a private key -func NewEd25519Signer(key *keys.Key) *Ed25519Signer { +func NewEd25519Signer(key data.Key) *Ed25519Signer { return &Ed25519Signer{privateKey: key} } diff --git a/signer/api/ed25519_signer_test.go b/signer/api/ed25519_signer_test.go index e3514e1f5f..e3a4a30234 100644 --- a/signer/api/ed25519_signer_test.go +++ b/signer/api/ed25519_signer_test.go @@ -8,6 +8,7 @@ import ( "github.com/agl/ed25519" "github.com/docker/notary/signer/api" "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" "github.com/stretchr/testify/assert" pb "github.com/docker/notary/proto" @@ -31,16 +32,17 @@ func TestSign(t *testing.T) { directSig := ed25519.Sign(private, blob) directSigHex := hex.EncodeToString(directSig[:]) - signer := api.NewEd25519Signer(&keys.Key{Private: private, Public: *public, ID: "fake_id"}) + key := data.NewPrivateKey(data.ED25519Key, public[:], private[:]) + signer := api.NewEd25519Signer(key) - sigRequest := &pb.SignatureRequest{KeyID: &pb.KeyID{ID: "fake_id"}, Content: blob} + sigRequest := &pb.SignatureRequest{KeyID: &pb.KeyID{ID: key.ID()}, Content: blob} sig, err := signer.Sign(sigRequest) assert.Nil(t, err) signatureHex := fmt.Sprintf("%x", sig.Content) assert.Equal(t, directSigHex, signatureHex) - assert.Equal(t, sig.KeyInfo.KeyID.ID, "fake_id") + assert.Equal(t, sig.KeyInfo.KeyID.ID, key.ID()) } func BenchmarkSign(b *testing.B) { diff --git a/signer/api/ed25519_signing_service.go b/signer/api/ed25519_signing_service.go index 2b8b6be722..d3210e855d 100644 --- a/signer/api/ed25519_signing_service.go +++ b/signer/api/ed25519_signing_service.go @@ -2,12 +2,11 @@ package api import ( "crypto/rand" - "crypto/sha256" - "encoding/hex" "github.com/agl/ed25519" "github.com/docker/notary/signer" "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" pb "github.com/docker/notary/proto" ) @@ -23,20 +22,14 @@ func (s EdDSASigningService) CreateKey() (*pb.PublicKey, error) { if err != nil { return nil, err } - k := &keys.Key{ - Algorithm: ED25519, - Public: *pub, - Private: priv, - } - digest := sha256.Sum256(k.Public[:]) - k.ID = hex.EncodeToString(digest[:]) + k := data.NewPrivateKey(data.ED25519Key, pub[:], priv[:]) err = s.KeyDB.AddKey(k) if err != nil { return nil, err } - pubKey := &pb.PublicKey{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: k.ID}, Algorithm: &pb.Algorithm{Algorithm: k.Algorithm}}, PublicKey: k.Public[:]} + pubKey := &pb.PublicKey{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: k.ID()}, Algorithm: &pb.Algorithm{Algorithm: k.Algorithm().String()}}, PublicKey: pub[:]} return pubKey, nil } diff --git a/signer/api/ed25519_signing_service_test.go b/signer/api/ed25519_signing_service_test.go index 0f43ada8c1..b9b6a78ceb 100644 --- a/signer/api/ed25519_signing_service_test.go +++ b/signer/api/ed25519_signing_service_test.go @@ -5,6 +5,7 @@ import ( "github.com/docker/notary/signer/api" "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -20,7 +21,7 @@ func (m *FakeKeyDB) CreateKey() (*pb.PublicKey, error) { return args.Get(0).(*pb.PublicKey), args.Error(1) } -func (m *FakeKeyDB) AddKey(key *keys.Key) error { +func (m *FakeKeyDB) AddKey(key data.Key) error { args := m.Mock.Called() return args.Error(0) } @@ -35,9 +36,9 @@ func (m *FakeKeyDB) KeyInfo(keyID *pb.KeyID) (*pb.PublicKey, error) { return args.Get(0).(*pb.PublicKey), args.Error(1) } -func (m *FakeKeyDB) GetKey(keyID *pb.KeyID) (*keys.Key, error) { +func (m *FakeKeyDB) GetKey(keyID *pb.KeyID) (data.Key, error) { args := m.Mock.Called(keyID.ID) - return args.Get(0).(*keys.Key), args.Error(1) + return args.Get(0).(data.Key), args.Error(1) } func TestDeleteKey(t *testing.T) { @@ -83,7 +84,7 @@ func TestSigner(t *testing.T) { m := FakeKeyDB{} sigService := api.NewEdDSASigningService(&m) - m.On("GetKey", fakeKeyID).Return(&keys.Key{}, nil).Once() + m.On("GetKey", fakeKeyID).Return(&data.PrivateKey{}, nil).Once() _, err := sigService.Signer(&pb.KeyID{ID: fakeKeyID}) m.Mock.AssertExpectations(t) diff --git a/signer/api/rpc_api.go b/signer/api/rpc_api.go index 0e653687ee..3f25276366 100644 --- a/signer/api/rpc_api.go +++ b/signer/api/rpc_api.go @@ -6,6 +6,7 @@ import ( "github.com/docker/notary/signer" "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" "golang.org/x/net/context" "google.golang.org/grpc" @@ -26,7 +27,7 @@ type SignerServer struct { //CreateKey returns a PublicKey created using KeyManagementServer's SigningService func (s *KeyManagementServer) CreateKey(ctx context.Context, algorithm *pb.Algorithm) (*pb.PublicKey, error) { - service := s.SigServices[algorithm.Algorithm] + service := s.SigServices[data.KeyAlgorithm(algorithm.Algorithm)] if service == nil { return nil, fmt.Errorf("algorithm %s not supported for create key", algorithm.Algorithm) diff --git a/signer/api/rpc_api_test.go b/signer/api/rpc_api_test.go index 9acfafcb83..39c633d500 100644 --- a/signer/api/rpc_api_test.go +++ b/signer/api/rpc_api_test.go @@ -9,6 +9,7 @@ import ( "github.com/docker/notary/signer" "github.com/docker/notary/signer/api" "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" "github.com/stretchr/testify/assert" "golang.org/x/net/context" "google.golang.org/grpc" @@ -26,7 +27,7 @@ var ( func init() { sigService := api.NewEdDSASigningService(keys.NewKeyDB()) - sigServices := signer.SigningServiceIndex{api.ED25519: sigService, api.RSAAlgorithm: sigService} + sigServices := signer.SigningServiceIndex{data.ED25519Key: sigService, data.RSAKey: sigService} void = &pb.Void{} //server setup kms := &api.KeyManagementServer{SigServices: sigServices} @@ -61,7 +62,7 @@ func TestDeleteKeyHandlerReturnsNotFoundWithNonexistentKey(t *testing.T) { } func TestCreateKeyHandlerCreatesKey(t *testing.T) { - publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: api.ED25519}) + publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()}) assert.NotNil(t, publicKey) assert.NotEmpty(t, publicKey.PublicKey) assert.NotEmpty(t, publicKey.KeyInfo) @@ -70,14 +71,14 @@ func TestCreateKeyHandlerCreatesKey(t *testing.T) { } func TestDeleteKeyHandlerDeletesCreatedKey(t *testing.T) { - publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: api.ED25519}) + publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()}) ret, err := kmClient.DeleteKey(context.Background(), publicKey.KeyInfo.KeyID) assert.Nil(t, err) assert.Equal(t, ret, void) } func TestKeyInfoReturnsCreatedKeys(t *testing.T) { - publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: api.ED25519}) + publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()}) fmt.Println("Pubkey ID: " + publicKey.GetKeyInfo().KeyID.ID) returnedPublicKey, err := kmClient.GetKeyInfo(context.Background(), publicKey.KeyInfo.KeyID) fmt.Println("returnedPublicKey ID: " + returnedPublicKey.GetKeyInfo().KeyID.ID) @@ -88,9 +89,9 @@ func TestKeyInfoReturnsCreatedKeys(t *testing.T) { } func TestCreateKeyCreatesNewKeys(t *testing.T) { - publicKey1, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: api.ED25519}) + publicKey1, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()}) assert.Nil(t, err) - publicKey2, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: api.ED25519}) + publicKey2, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()}) assert.Nil(t, err) assert.NotEqual(t, publicKey1, publicKey2) assert.NotEqual(t, publicKey1.KeyInfo, publicKey2.KeyInfo) @@ -110,7 +111,7 @@ func TestGetKeyInfoReturnsNotFoundOnNonexistKeys(t *testing.T) { func TestCreatedKeysCanBeUsedToSign(t *testing.T) { message := []byte{0, 0, 0, 0} - publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: api.ED25519}) + publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()}) assert.Nil(t, err) assert.NotNil(t, publicKey) diff --git a/signer/api/rsa_signing_service.go b/signer/api/rsa_signing_service.go index 8e4e2c2e4f..d997cc8e78 100644 --- a/signer/api/rsa_signing_service.go +++ b/signer/api/rsa_signing_service.go @@ -6,7 +6,6 @@ import ( "crypto/rsa" "crypto/sha256" "crypto/x509" - "encoding/hex" "errors" "log" "math/big" @@ -18,9 +17,6 @@ import ( pb "github.com/docker/notary/proto" ) -// RSAAlgorithm represents the rsa signing algorithm -const RSAAlgorithm string = "rsa" - // RSASigningService is an implementation of SigningService type RSASigningService struct { keys map[string]*keys.HSMRSAKey @@ -99,19 +95,13 @@ func (s RSASigningService) CreateKey() (*pb.PublicKey, error) { } // (diogo): Ideally I would like to return base64 PEM encoded public keys to the client - k := &keys.HSMRSAKey{ - Algorithm: RSAAlgorithm, - Public: pubBytes, - Private: priv, - } + k := keys.NewHSMRSAKey(pubBytes, priv) - // (diogo): Change this to be consistent with how TUF does (canonical JSON) - digest := sha256.Sum256(k.Public[:]) - k.ID = hex.EncodeToString(digest[:]) + keyID := k.ID() - s.keys[k.ID] = k + s.keys[keyID] = k - pubKey := &pb.PublicKey{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: k.ID}, Algorithm: &pb.Algorithm{Algorithm: k.Algorithm}}, PublicKey: k.Public[:]} + pubKey := &pb.PublicKey{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: keyID}, Algorithm: &pb.Algorithm{Algorithm: k.Algorithm().String()}}, PublicKey: k.Public()} return pubKey, nil } @@ -133,7 +123,7 @@ func (s RSASigningService) KeyInfo(keyID *pb.KeyID) (*pb.PublicKey, error) { return nil, keys.ErrInvalidKeyID } - pubKey := &pb.PublicKey{KeyInfo: &pb.KeyInfo{KeyID: keyID, Algorithm: &pb.Algorithm{Algorithm: k.Algorithm}}, PublicKey: k.Public[:]} + pubKey := &pb.PublicKey{KeyInfo: &pb.KeyInfo{KeyID: keyID, Algorithm: &pb.Algorithm{Algorithm: k.Algorithm().String()}}, PublicKey: k.Public()} return pubKey, nil } @@ -157,7 +147,7 @@ type RSASigner struct { // Sign returns a signature for a given signature request func (s *RSASigner) Sign(request *pb.SignatureRequest) (*pb.Signature, error) { - priv := s.privateKey.Private + priv := s.privateKey.PKCS11ObjectHandle() var sig []byte var err error for i := 0; i < 3; i++ { @@ -172,7 +162,7 @@ func (s *RSASigner) Sign(request *pb.SignatureRequest) (*pb.Signature, error) { // (diogo): XXX: Remove this before shipping digest := sha256.Sum256(request.Content) - pub, err := x509.ParsePKIXPublicKey(s.privateKey.Public) + pub, err := x509.ParsePKIXPublicKey(s.privateKey.Public()) if err != nil { log.Printf("Failed to parse public key: %s\n", err) return nil, err @@ -197,7 +187,7 @@ func (s *RSASigner) Sign(request *pb.SignatureRequest) (*pb.Signature, error) { return nil, errors.New("Failed to create signature") } - returnSig := &pb.Signature{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: s.privateKey.ID}, Algorithm: &pb.Algorithm{Algorithm: RSAAlgorithm}}, Content: sig[:]} + returnSig := &pb.Signature{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: s.privateKey.ID()}, Algorithm: &pb.Algorithm{Algorithm: s.privateKey.Algorithm().String()}}, Content: sig[:]} log.Printf("[Notary-signer Server] Signature request JSON: %s , response: %s", string(request.Content), returnSig) return returnSig, nil } diff --git a/signer/keys/key_db.go b/signer/keys/key_db.go index 89e181fb52..c42341619c 100644 --- a/signer/keys/key_db.go +++ b/signer/keys/key_db.go @@ -1,10 +1,13 @@ package keys -import pb "github.com/docker/notary/proto" +import ( + pb "github.com/docker/notary/proto" + "github.com/endophage/gotuf/data" +) // KeyDB represents an in-memory key keystore type KeyDB struct { - keys map[string]*Key + keys map[string]data.Key } // CreateKey is needed to implement KeyManager. Returns an empty key. @@ -15,17 +18,17 @@ func (db *KeyDB) CreateKey() (*pb.PublicKey, error) { } // AddKey Adds a new key to the database -func (db *KeyDB) AddKey(key *Key) error { - if _, ok := db.keys[key.ID]; ok { +func (db *KeyDB) AddKey(key data.Key) error { + if _, ok := db.keys[key.ID()]; ok { return ErrExists } - db.keys[key.ID] = key + db.keys[key.ID()] = key return nil } // GetKey returns the private bits of a key -func (db *KeyDB) GetKey(keyID *pb.KeyID) (*Key, error) { +func (db *KeyDB) GetKey(keyID *pb.KeyID) (data.Key, error) { if key, ok := db.keys[keyID.ID]; ok { return key, nil } @@ -48,12 +51,12 @@ func (db *KeyDB) KeyInfo(keyID *pb.KeyID) (*pb.PublicKey, error) { if err != nil { return nil, err } - return &pb.PublicKey{KeyInfo: &pb.KeyInfo{KeyID: keyID, Algorithm: &pb.Algorithm{Algorithm: key.Algorithm}}, PublicKey: key.Public[:]}, nil + return &pb.PublicKey{KeyInfo: &pb.KeyInfo{KeyID: keyID, Algorithm: &pb.Algorithm{Algorithm: key.Algorithm().String()}}, PublicKey: key.Public()}, nil } // NewKeyDB returns an instance of KeyDB func NewKeyDB() *KeyDB { return &KeyDB{ - keys: make(map[string]*Key), + keys: make(map[string]data.Key), } } diff --git a/signer/keys/keys.go b/signer/keys/keys.go index 232233aba3..d44fd033b2 100644 --- a/signer/keys/keys.go +++ b/signer/keys/keys.go @@ -3,7 +3,7 @@ package keys import ( "errors" - "github.com/agl/ed25519" + "github.com/endophage/gotuf/data" "github.com/miekg/pkcs11" ) @@ -16,18 +16,48 @@ var ( ErrFailedKeyGeneration = errors.New("notary-signer: failed to generate new key") ) -// Key represents all the information of a key, including the private and public bits -type Key struct { - ID string - Algorithm string - Public [ed25519.PublicKeySize]byte - Private *[ed25519.PrivateKeySize]byte -} - // HSMRSAKey represents the information for an HSMRSAKey with ObjectHandle for private portion type HSMRSAKey struct { - ID string - Algorithm string - Public []byte - Private pkcs11.ObjectHandle + id string + public []byte + private pkcs11.ObjectHandle +} + +// NewHSMRSAKey returns a HSMRSAKey +func NewHSMRSAKey(public []byte, private pkcs11.ObjectHandle) *HSMRSAKey { + return &HSMRSAKey{ + public: public, + private: private, + } +} + +// Algorithm implements a method of the data.Key interface +func (rsa *HSMRSAKey) Algorithm() data.KeyAlgorithm { + return data.RSAKey +} + +// ID implements a method of the data.Key interface +func (rsa *HSMRSAKey) ID() string { + if rsa.id == "" { + pubK := data.NewTUFKey(rsa.Algorithm(), rsa.Public(), nil) + rsa.id = pubK.ID() + } + return rsa.id +} + +// Public implements a method of the data.Key interface +func (rsa *HSMRSAKey) Public() []byte { + return rsa.public +} + +// Private implements a method of the data.Key interface +func (rsa *HSMRSAKey) Private() []byte { + // Not possible to return private key bytes from a hardware device + return nil +} + +// PKCS11ObjectHandle returns the PKCS11 object handle stored in the HSMRSAKey +// structure +func (rsa *HSMRSAKey) PKCS11ObjectHandle() pkcs11.ObjectHandle { + return rsa.private } diff --git a/signer/signer.go b/signer/signer.go index 6a5de127c6..3b504da270 100644 --- a/signer/signer.go +++ b/signer/signer.go @@ -2,7 +2,7 @@ package signer import ( pb "github.com/docker/notary/proto" - "github.com/docker/notary/signer/keys" + "github.com/endophage/gotuf/data" ) // SigningService is the interface to implement a key management and signing service @@ -15,7 +15,7 @@ type SigningService interface { // SigningServiceIndex represents a mapping between a service algorithm string // and a signing service -type SigningServiceIndex map[string]SigningService +type SigningServiceIndex map[data.KeyAlgorithm]SigningService // KeyManager is the interface to implement key management (possibly a key database) type KeyManager interface { @@ -39,8 +39,8 @@ type KeyDatabase interface { KeyManager // GetKey returns the private key to do signing operations - GetKey(keyID *pb.KeyID) (*keys.Key, error) + GetKey(keyID *pb.KeyID) (data.Key, error) // AddKey allows the direct addition and removal of keys from the database - AddKey(key *keys.Key) error + AddKey(key data.Key) error }