Commit 07ceffb7 authored by Jonathan Levi (HACERA)'s avatar Jonathan Levi (HACERA) Committed by Gerrit Code Review
Browse files

Merge "[FAB-12784] In-memory keystore for BCCSP"

parents a2427b0d 2c8240b1
......@@ -52,8 +52,10 @@ func (f *SWFactory) Get(config *FactoryOpts) (bccsp.BCCSP, error) {
return nil, errors.Wrapf(err, "Failed to initialize software key store")
}
ks = fks
} else if swOpts.InmemKeystore != nil {
ks = sw.NewInMemoryKeyStore()
} else {
// Default to DummyKeystore
// Default to ephemeral key store
ks = sw.NewDummyKeyStore()
}
......@@ -70,6 +72,7 @@ type SwOpts struct {
Ephemeral bool `mapstructure:"tempkeys,omitempty" json:"tempkeys,omitempty"`
FileKeystore *FileKeystoreOpts `mapstructure:"filekeystore,omitempty" json:"filekeystore,omitempty" yaml:"FileKeyStore"`
DummyKeystore *DummyKeystoreOpts `mapstructure:"dummykeystore,omitempty" json:"dummykeystore,omitempty"`
InmemKeystore *InmemKeystoreOpts `mapstructure:"inmemkeystore,omitempty" json:"inmemkeystore,omitempty"`
}
// Pluggable Keystores, could add JKS, P12, etc..
......@@ -78,3 +81,6 @@ type FileKeystoreOpts struct {
}
type DummyKeystoreOpts struct{}
// InmemKeystoreOpts - empty, as there is no config for the in-memory keystore
type InmemKeystoreOpts struct{}
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package sw
import (
"encoding/hex"
"sync"
"github.com/hyperledger/fabric/bccsp"
"github.com/pkg/errors"
)
// NewInMemoryKeyStore instantiates an ephemeral in-memory keystore
func NewInMemoryKeyStore() bccsp.KeyStore {
eks := &inmemoryKeyStore{}
eks.keys = make(map[string]bccsp.Key)
return eks
}
type inmemoryKeyStore struct {
// keys maps the hex-encoded SKI to keys
keys map[string]bccsp.Key
m sync.RWMutex
}
// ReadOnly returns false - the key store is not read-only
func (ks *inmemoryKeyStore) ReadOnly() bool {
return false
}
// GetKey returns a key object whose SKI is the one passed.
func (ks *inmemoryKeyStore) GetKey(ski []byte) (bccsp.Key, error) {
if len(ski) == 0 {
return nil, errors.New("ski is nil or empty")
}
skiStr := hex.EncodeToString(ski)
ks.m.RLock()
defer ks.m.RUnlock()
if key, found := ks.keys[skiStr]; found {
return key, nil
}
return nil, errors.Errorf("no key found for ski %x", ski)
}
// StoreKey stores the key k in this KeyStore.
func (ks *inmemoryKeyStore) StoreKey(k bccsp.Key) error {
if k == nil {
return errors.New("key is nil")
}
ski := hex.EncodeToString(k.SKI())
ks.m.Lock()
defer ks.m.Unlock()
if _, found := ks.keys[ski]; found {
return errors.Errorf("ski %x already exists in the keystore", k.SKI())
}
ks.keys[ski] = k
return nil
}
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package sw
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestInvalidStore(t *testing.T) {
t.Parallel()
ks := NewInMemoryKeyStore()
err := ks.StoreKey(nil)
assert.EqualError(t, err, "key is nil")
}
func TestInvalidLoad(t *testing.T) {
t.Parallel()
ks := NewInMemoryKeyStore()
_, err := ks.GetKey(nil)
assert.EqualError(t, err, "ski is nil or empty")
}
func TestNoKeyFound(t *testing.T) {
t.Parallel()
ks := NewInMemoryKeyStore()
ski := []byte("foo")
_, err := ks.GetKey(ski)
assert.EqualError(t, err, fmt.Sprintf("no key found for ski %x", ski))
}
func TestStoreLoad(t *testing.T) {
t.Parallel()
ks := NewInMemoryKeyStore()
// generate a key for the keystore to find
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
assert.NoError(t, err)
cspKey := &ecdsaPrivateKey{privKey}
// store key
err = ks.StoreKey(cspKey)
assert.NoError(t, err)
// load key
key, err := ks.GetKey(cspKey.SKI())
assert.NoError(t, err)
assert.Equal(t, cspKey, key)
}
func TestReadOnly(t *testing.T) {
t.Parallel()
ks := NewInMemoryKeyStore()
readonly := ks.ReadOnly()
assert.Equal(t, false, readonly)
}
func TestStoreExisting(t *testing.T) {
t.Parallel()
ks := NewInMemoryKeyStore()
// generate a key for the keystore to find
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
assert.NoError(t, err)
cspKey := &ecdsaPrivateKey{privKey}
// store key
err = ks.StoreKey(cspKey)
assert.NoError(t, err)
// store key a second time
err = ks.StoreKey(cspKey)
assert.EqualError(t, err, fmt.Sprintf("ski %x already exists in the keystore", cspKey.SKI()))
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment