Skip to content

Commit 2013daa

Browse files
committed
BCCSP KeyStore
This change-set introduce the concept of KeyStore at the BCCSP level. A KeyStore represents a storage system for cryptographic keys. It allows to store and retrieve bccsp.Key objects. The key store can be read only, in that case storing a key will return an error. Now, to initialize a software-based BCCSP, a key store must be specified. A file based keystore is provided. In addition, all the dependencies from viper has been removed. In order to do that, some assumptions has been made on default security level. The organization of this paramenters will be better addressed in a subsequent change-set. This change-set comes in the context of: https://jira.hyperledger.org/browse/FAB-354 Change-Id: I7e96eea7e5e89ecec86863ebc11b919d29c0019a Signed-off-by: Angelo De Caro <[email protected]>
1 parent 68aef4e commit 2013daa

File tree

10 files changed

+505
-388
lines changed

10 files changed

+505
-388
lines changed

core/crypto/bccsp/factory/factory.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ import (
2020
"fmt"
2121
"sync"
2222

23+
"os"
24+
2325
"github.com/hyperledger/fabric/core/crypto/bccsp"
24-
"github.com/spf13/viper"
26+
"github.com/hyperledger/fabric/core/crypto/bccsp/sw"
2527
)
2628

2729
var (
@@ -104,12 +106,7 @@ func initFactoriesMap() error {
104106
}
105107

106108
func createDefaultBCCSP() (bccsp.BCCSP, error) {
107-
defaultBCCSPFactoryName := viper.GetString("bccsp.default")
108-
if defaultBCCSPFactoryName == "" {
109-
defaultBCCSPFactoryName = SoftwareBasedFactoryName
110-
}
111-
112-
return getBCCSPInternal(&DefaultOpts{defaultBCCSPFactoryName, false})
109+
return sw.NewDefaultSecurityLevel(os.TempDir())
113110
}
114111

115112
func getBCCSPInternal(opts Opts) (bccsp.BCCSP, error) {

core/crypto/bccsp/factory/factory_test.go

+20-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ limitations under the License.
1515
*/
1616
package factory
1717

18-
import "testing"
18+
import (
19+
"os"
20+
"testing"
21+
22+
"github.com/hyperledger/fabric/core/crypto/bccsp/sw"
23+
)
1924

2025
func TestGetDefault(t *testing.T) {
2126
bccsp, err := GetDefault()
@@ -28,12 +33,17 @@ func TestGetDefault(t *testing.T) {
2833
}
2934

3035
func TestGetBCCPEphemeral(t *testing.T) {
31-
bccsp1, err := GetBCCSP(&SwOpts{EphemeralFlag: true})
36+
ks := &sw.FileBasedKeyStore{}
37+
if err := ks.Init(nil, os.TempDir(), false); err != nil {
38+
t.Fatalf("Failed initializing key store [%s]", err)
39+
}
40+
41+
bccsp1, err := GetBCCSP(&SwOpts{Ephemeral_: true, SecLevel: 256, HashFamily: "SHA2", KeyStore: ks})
3242
if err != nil {
3343
t.Fatalf("Failed getting ephemeral software-based BCCSP [%s]", err)
3444
}
3545

36-
bccsp2, err := GetBCCSP(&SwOpts{EphemeralFlag: true})
46+
bccsp2, err := GetBCCSP(&SwOpts{Ephemeral_: true, SecLevel: 256, HashFamily: "SHA2", KeyStore: ks})
3747
if err != nil {
3848
t.Fatalf("Failed getting ephemeral software-based BCCSP [%s]", err)
3949
}
@@ -44,12 +54,17 @@ func TestGetBCCPEphemeral(t *testing.T) {
4454
}
4555

4656
func TestGetBCCP2Ephemeral(t *testing.T) {
47-
bccsp1, err := GetBCCSP(&SwOpts{EphemeralFlag: false})
57+
ks := &sw.FileBasedKeyStore{}
58+
if err := ks.Init(nil, os.TempDir(), false); err != nil {
59+
t.Fatalf("Failed initializing key store [%s]", err)
60+
}
61+
62+
bccsp1, err := GetBCCSP(&SwOpts{Ephemeral_: false, SecLevel: 256, HashFamily: "SHA2", KeyStore: ks})
4863
if err != nil {
4964
t.Fatalf("Failed getting non-ephemeral software-based BCCSP [%s]", err)
5065
}
5166

52-
bccsp2, err := GetBCCSP(&SwOpts{EphemeralFlag: false})
67+
bccsp2, err := GetBCCSP(&SwOpts{Ephemeral_: false, SecLevel: 256, HashFamily: "SHA2", KeyStore: ks})
5368
if err != nil {
5469
t.Fatalf("Failed getting non-ephemeral software-based BCCSP [%s]", err)
5570
}

core/crypto/bccsp/factory/sw_factory.go core/crypto/bccsp/factory/swfactory.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,28 @@ func (f *SWFactory) Get(opts Opts) (bccsp.BCCSP, error) {
5252
return nil, fmt.Errorf("Invalid Provider Name [%s]. Opts must refer to [%s].", opts.FactoryName(), f.Name())
5353
}
5454

55+
swOpts, ok := opts.(*SwOpts)
56+
if !ok {
57+
return nil, errors.New("Invalid opts. They must be of type SwOpts.")
58+
}
59+
5560
if !opts.Ephemeral() {
5661
f.initOnce.Do(func() {
57-
f.bccsp, f.err = sw.NewDefaultSecurityLevel()
62+
f.bccsp, f.err = sw.New(swOpts.SecLevel, swOpts.HashFamily, swOpts.KeyStore)
5863
return
5964
})
6065
return f.bccsp, f.err
6166
}
6267

63-
return sw.NewDefaultSecurityLevel()
68+
return sw.New(swOpts.SecLevel, swOpts.HashFamily, swOpts.KeyStore)
6469
}
6570

6671
// SwOpts contains options for the SWFactory
6772
type SwOpts struct {
68-
EphemeralFlag bool
73+
Ephemeral_ bool
74+
SecLevel int
75+
HashFamily string
76+
KeyStore bccsp.KeyStore
6977
}
7078

7179
// FactoryName returns the name of the provider
@@ -75,5 +83,5 @@ func (o *SwOpts) FactoryName() string {
7583

7684
// Ephemeral returns true if the CSP has to be ephemeral, false otherwise
7785
func (o *SwOpts) Ephemeral() bool {
78-
return o.EphemeralFlag
86+
return o.Ephemeral_
7987
}

core/crypto/bccsp/keystore.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package bccsp
17+
18+
// KeyStore represents a storage system for cryptographic keys.
19+
// It allows to store and retrieve bccsp.Key objects.
20+
// The KeyStore can be read only, in that case StoreKey will return
21+
// an error.
22+
type KeyStore interface {
23+
24+
// ReadOnly returns true if this KeyStore is read only, false otherwise.
25+
// If ReadOnly is true then StoreKey will fail.
26+
ReadOnly() bool
27+
28+
// GetKey returns a key object whose SKI is the one passed.
29+
GetKey(ski []byte) (k Key, err error)
30+
31+
// StoreKey stores the key k in this KeyStore.
32+
// If this KeyStore is read only then the method will fail.
33+
StoreKey(k Key) (err error)
34+
}

core/crypto/bccsp/signer/signer_test.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/hyperledger/fabric/core/crypto/bccsp"
2424
"github.com/hyperledger/fabric/core/crypto/bccsp/sw"
25-
"github.com/spf13/viper"
2625
)
2726

2827
var (
@@ -31,10 +30,8 @@ var (
3130

3231
func getBCCSP(t *testing.T) bccsp.BCCSP {
3332
if swBCCSPInstance == nil {
34-
viper.Set("security.bccsp.default.keyStorePath", os.TempDir())
35-
3633
var err error
37-
swBCCSPInstance, err = sw.NewDefaultSecurityLevel()
34+
swBCCSPInstance, err = sw.NewDefaultSecurityLevel(os.TempDir())
3835
if err != nil {
3936
t.Fatalf("Failed initializing key store [%s]", err)
4037
}

core/crypto/bccsp/sw/conf.go

+5-54
Original file line numberDiff line numberDiff line change
@@ -16,57 +16,24 @@ limitations under the License.
1616
package sw
1717

1818
import (
19-
"errors"
20-
"path/filepath"
21-
22-
"os"
23-
2419
"crypto/elliptic"
2520
"crypto/sha256"
2621
"crypto/sha512"
2722
"fmt"
2823
"hash"
2924

30-
"github.com/spf13/viper"
3125
"golang.org/x/crypto/sha3"
3226
)
3327

3428
type config struct {
35-
keystorePath string
29+
keyStorePath string
3630
securityLevel int
3731
hashFamily string
3832

39-
configurationPathProperty string
40-
ellipticCurve elliptic.Curve
41-
hashFunction func() hash.Hash
42-
aesBitLength int
43-
rsaBitLength int
44-
}
45-
46-
func (conf *config) init(securityLevel int, hashFamily string) error {
47-
// Set security level
48-
err := conf.setSecurityLevel(securityLevel, hashFamily)
49-
if err != nil {
50-
return fmt.Errorf("Failed initliazing security level [%s]", err)
51-
}
52-
// Set ks path
53-
conf.configurationPathProperty = "security.bccsp.default.keyStorePath"
54-
55-
// Check mandatory fields
56-
var rootPath string
57-
if err := conf.checkProperty(conf.configurationPathProperty); err != nil {
58-
logger.Warning("'security.bccsp.default.keyStorePath' not set. Using the default directory [%s] for temporary files", os.TempDir())
59-
rootPath = os.TempDir()
60-
} else {
61-
rootPath = viper.GetString(conf.configurationPathProperty)
62-
}
63-
logger.Infof("Root Path [%s]", rootPath)
64-
// Set configuration path
65-
rootPath = filepath.Join(rootPath, "crypto")
66-
67-
conf.keystorePath = filepath.Join(rootPath, "ks")
68-
69-
return nil
33+
ellipticCurve elliptic.Curve
34+
hashFunction func() hash.Hash
35+
aesBitLength int
36+
rsaBitLength int
7037
}
7138

7239
func (conf *config) setSecurityLevel(securityLevel int, hashFamily string) (err error) {
@@ -116,19 +83,3 @@ func (conf *config) setSecurityLevelSHA3(level int) (err error) {
11683
}
11784
return
11885
}
119-
120-
func (conf *config) checkProperty(property string) error {
121-
res := viper.GetString(property)
122-
if res == "" {
123-
return errors.New("Property not specified in configuration file. Please check that property is set: " + property)
124-
}
125-
return nil
126-
}
127-
128-
func (conf *config) getKeyStorePath() string {
129-
return conf.keystorePath
130-
}
131-
132-
func (conf *config) getPathForAlias(alias, suffix string) string {
133-
return filepath.Join(conf.getKeyStorePath(), alias+"_"+suffix)
134-
}

0 commit comments

Comments
 (0)