Permalink
Browse files

Separate Signer from Keymaster operations (#497)

Separate Signer from Keymaster operations

Establishes a 1:1 relationship between the signer and
DigitallySigned.

Keymaster operations on groups of signers and verifiers are
in a separate package with a separate protobuf serialization.
  • Loading branch information...
1 parent 585b370 commit 7e09e1aead633f455fb8e18c3bc4a6c689691106 @gdbelvin gdbelvin committed with cesarghali Feb 17, 2017
@@ -25,8 +25,8 @@ import (
"github.com/google/keytransparency/cmd/keytransparency-client/grpcc"
"github.com/google/keytransparency/core/client/ctlog"
"github.com/google/keytransparency/core/client/kt"
+ "github.com/google/keytransparency/core/crypto/keymaster"
"github.com/google/keytransparency/core/crypto/signatures"
- "github.com/google/keytransparency/core/crypto/signatures/factory"
"github.com/google/keytransparency/core/vrf"
"github.com/google/keytransparency/core/vrf/p256"
"github.com/google/keytransparency/impl/google/authentication"
@@ -179,7 +179,7 @@ func readSignatureVerifier(ktPEM string) (signatures.Verifier, error) {
if err != nil {
return nil, err
}
- ver, err := factory.VerifierFromPEM(pem)
+ ver, err := keymaster.NewVerifierFromPEM(pem)
if err != nil {
return nil, err
}
@@ -73,7 +73,7 @@ func openPrivateKey() signatures.Signer {
if err != nil {
log.Fatalf("Failed to read file %v: %v", *signingKey, err)
}
- sig, err := factory.SignerFromPEM(pem)
+ sig, err := factory.NewSignerFromPEM(pem)
if err != nil {
log.Fatalf("Failed to create signer: %v", err)
}
@@ -0,0 +1,52 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package keymaster
+
+import (
+ "github.com/google/keytransparency/core/crypto/signatures"
+
+ kmpb "github.com/google/keytransparency/core/proto/keymaster"
+)
+
+// Signer represents an object that can generate signatures with a single key.
+type Signer interface {
+ signatures.Signer
+ // Status returns the status of the signer.
+ Status() kmpb.SigningKey_KeyStatus
+ // Activate activates the signer.
+ Activate()
+ // Deactivate deactivates the signer.
+ Deactivate()
+ // Deprecate sets the signer status to DEPRECATED.
+ Deprecate()
+ // Marshal marshals a signer object into a keymaster SigningKey message.
+ Marshal() (*kmpb.SigningKey, error)
+ // Clone creates a new instance of the signer object
+ Clone() Signer
+}
+
+// Verifier represents an object that can verify signatures with a single key.
+type Verifier interface {
+ signatures.Verifier
+ // Status returns the status of the verifier.
+ Status() kmpb.VerifyingKey_KeyStatus
+ // Deprecate sets the verifier status to DEPRECATED.
+ Deprecate()
+ // Marshal marshals a verifier object into a keymaster VerifyingKey
+ // message.
+ Marshal() (*kmpb.VerifyingKey, error)
+ // Clone creates a new instance of the verifier object
+ Clone() Verifier
+}
@@ -37,16 +37,16 @@ var (
// KeyMaster contains all update signing and verification keys.
type KeyMaster struct {
- signers map[string]signatures.Signer
- verifiers map[string]signatures.Verifier
- activeSigner signatures.Signer
+ signers map[string]Signer
+ verifiers map[string]Verifier
+ activeSigner Signer
}
// New creates a new instance of an empty key store.
func New() *KeyMaster {
return &KeyMaster{
- signers: make(map[string]signatures.Signer),
- verifiers: make(map[string]signatures.Verifier),
+ signers: make(map[string]Signer),
+ verifiers: make(map[string]Verifier),
}
}
@@ -58,34 +58,37 @@ func Unmarshal(buf []byte, store *KeyMaster) error {
}
// Populate signers map.
- var activeSigner signatures.Signer
- signers := make(map[string]signatures.Signer)
+ var activeSigner Signer
+ signers := make(map[string]Signer)
for id, key := range set.SigningKeys {
addedAt, err := ptypes.Timestamp(key.Metadata.AddedAt)
if err != nil {
return err
}
- signer, err := factory.NewSigner(key.KeyMaterial, addedAt, key.Metadata.Description, key.Status)
+
+ s, err := factory.NewSignerFromPEM(key.KeyMaterial)
if err != nil {
return err
}
+ signer := NewSigner(s, addedAt, key.Metadata.Description, key.Status)
signers[id] = signer
if key.Status == kmpb.SigningKey_ACTIVE {
activeSigner = signer
}
}
// Populate verifiers map.
- verifiers := make(map[string]signatures.Verifier)
+ verifiers := make(map[string]Verifier)
for id, key := range set.VerifyingKeys {
addedAt, err := ptypes.Timestamp(key.Metadata.AddedAt)
if err != nil {
return err
}
- verifier, err := factory.NewVerifier(key.KeyMaterial, addedAt, key.Metadata.Description, key.Status)
+ v, err := factory.NewVerifierFromPEM(key.KeyMaterial)
if err != nil {
return err
}
+ verifier := NewVerifier(v, addedAt, key.Metadata.Description, key.Status)
verifiers[id] = verifier
}
@@ -130,10 +133,11 @@ func (s *KeyMaster) Marshal() ([]byte, error) {
// AddSigningKey adds a new private key to the store.
func (s *KeyMaster) AddSigningKey(status kmpb.SigningKey_KeyStatus, description string, key []byte) (string, error) {
- signer, err := factory.NewSigner(key, time.Now(), description, status)
+ sig, err := factory.NewSignerFromPEM(key)
if err != nil {
return "", nil
}
+ signer := NewSigner(sig, time.Now(), description, status)
mapID := signer.KeyID()
if _, ok := s.signers[mapID]; ok {
@@ -152,10 +156,11 @@ func (s *KeyMaster) AddSigningKey(status kmpb.SigningKey_KeyStatus, description
// AddVerifyingKey adds a new public key to the store.
func (s *KeyMaster) AddVerifyingKey(description string, key []byte) (string, error) {
- verifier, err := factory.NewVerifier(key, time.Now(), description, kmpb.VerifyingKey_ACTIVE)
+ v, err := factory.NewVerifierFromPEM(key)
if err != nil {
return "", err
}
+ verifier := NewVerifier(v, time.Now(), description, kmpb.VerifyingKey_ACTIVE)
mapID := verifier.KeyID()
if _, ok := s.verifiers[mapID]; ok {
@@ -292,7 +297,7 @@ func (s *KeyMaster) Info() ([]*kmpb.SigningKey, []*kmpb.VerifyingKey, error) {
}
// Signer returns a signer object given the corresponding key ID.
-func (s *KeyMaster) Signer(keyID string) (signatures.Signer, error) {
+func (s *KeyMaster) Signer(keyID string) (Signer, error) {
signer, ok := s.signers[keyID]
if !ok {
return nil, ErrKeyNotExist
@@ -0,0 +1,118 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package keymaster
+
+import (
+ "time"
+
+ "github.com/golang/protobuf/ptypes"
+ "github.com/google/keytransparency/core/crypto/signatures"
+ "github.com/google/keytransparency/core/crypto/signatures/factory"
+ kmpb "github.com/google/keytransparency/core/proto/keymaster"
+)
+
+type signer struct {
+ signatures.Signer
+ addedAt time.Time // time when key is added to keymaster.
+ description string
+ status kmpb.SigningKey_KeyStatus
+}
+
+// NewSigner creates a signer object from a private key.
+func NewSigner(s signatures.Signer, addedAt time.Time,
+ description string, status kmpb.SigningKey_KeyStatus) Signer {
+ return &signer{
+ Signer: s,
+ addedAt: addedAt,
+ description: description,
+ status: status,
+ }
+}
+
+// NewSignerFromPEM parses a PEM formatted block and returns a signer object created
+// using that block.
+func NewSignerFromPEM(pemKey []byte) (Signer, error) {
+ s, err := factory.NewSignerFromPEM(pemKey)
+ if err != nil {
+ return nil, err
+ }
+ return &signer{
+ Signer: s,
+ addedAt: time.Now(),
+ description: "Signer created from PEM",
+ status: kmpb.SigningKey_ACTIVE,
+ }, nil
+}
+
+// NewSignerFromRawKey creates a signer object from given raw key bytes.
+func NewSignerFromRawKey(b []byte) (signatures.Signer, error) {
+ s, err := factory.NewSignerFromBytes(b)
+ if err != nil {
+ return nil, err
+ }
+ return &signer{
+ Signer: s,
+ addedAt: time.Now(),
+ description: "Signer created from raw key",
+ status: kmpb.SigningKey_ACTIVE,
+ }, nil
+}
+
+// Status returns the status of the signer.
+func (s *signer) Status() kmpb.SigningKey_KeyStatus {
+ return s.status
+}
+
+// Activate activates the signer.
+func (s *signer) Activate() {
+ s.status = kmpb.SigningKey_ACTIVE
+}
+
+// Deactivate deactivates the signer.
+func (s *signer) Deactivate() {
+ s.status = kmpb.SigningKey_INACTIVE
+}
+
+// Deprecate sets the signer status to DEPRECATED.
+func (s *signer) Deprecate() {
+ s.status = kmpb.SigningKey_DEPRECATED
+}
+
+// Marshal marshals a signer object into a keymaster SigningKey message.
+func (s *signer) Marshal() (*kmpb.SigningKey, error) {
+ skPEM, err := s.PrivateKeyPEM()
+ if err != nil {
+ return nil, err
+ }
+ timestamp, err := ptypes.TimestampProto(s.addedAt)
+ if err != nil {
+ return nil, err
+ }
+ return &kmpb.SigningKey{
+ Metadata: &kmpb.Metadata{
+ KeyId: s.KeyID(),
+ AddedAt: timestamp,
+ Description: s.description,
+ },
+ KeyMaterial: skPEM,
+ Status: s.status,
+ }, nil
+}
+
+// Clone creates a new instance of the signer object
+func (s *signer) Clone() Signer {
+ clone := *s
+ return &clone
+}
@@ -0,0 +1,58 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package keymaster
+
+import (
+ "encoding/pem"
+ "testing"
+
+ "github.com/google/keytransparency/core/crypto/signatures"
+)
+
+const (
+ // openssl ecparam -name prime256v1 -genkey -out p256-key.pem
+ testPrivKey = `-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIGbhE2+z8d5lHzb0gmkS78d86gm5gHUtXCpXveFbK3pcoAoGCCqGSM49
+AwEHoUQDQgAEUxX42oxJ5voiNfbjoz8UgsGqh1bD1NXK9m8VivPmQSoYUdVFgNav
+csFaQhohkiCEthY51Ga6Xa+ggn+eTZtf9Q==
+-----END EC PRIVATE KEY-----`
+)
+
+func TestSignerFromPEM(t *testing.T) {
+ signatures.Rand = DevZero{}
+ for _, priv := range []string{
+ testPrivKey,
+ } {
+ _, err := NewSignerFromPEM([]byte(priv))
+ if err != nil {
+ t.Errorf("SignerFromPEM(): %v", err)
+ }
+ }
+}
+
+func TestSignerFromKey(t *testing.T) {
+ signatures.Rand = DevZero{}
+ for _, priv := range []string{
+ testPrivKey,
+ } {
+ p, _ := pem.Decode([]byte(priv))
+ if p == nil {
+ t.Error("pem.Decode() failed")
+ }
+ if _, err := NewSignerFromRawKey(p.Bytes); err != nil {
+ t.Errorf("SignerFromRawKey(): %v", err)
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 7e09e1a

Please sign in to comment.