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 }