-
Notifications
You must be signed in to change notification settings - Fork 709
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is the first step of integrating BCCSP into COP. One of the purposes is to provide HSM support. In particular, this change set: 1) Adds the lib/csp package which support BCCSP configuration 2) Uses lib/csp to initialize BCCSP in the COP server The next step will be use the BCCSP for: 1) authorization header sign and verification 2) tcerts including key derivation https://jira.hyperledger.org/browse/FAB-1461 Change-Id: Icdc286118fe2c61d907046e8083e318fd85e5e77 Signed-off-by: Keith Smith <[email protected]>
- Loading branch information
Keith Smith
committed
Jan 19, 2017
1 parent
8894989
commit 606fbdc
Showing
11 changed files
with
239 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* | ||
Copyright IBM Corp. 2016 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 csp | ||
|
||
import ( | ||
"crypto" | ||
"encoding/pem" | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"path" | ||
|
||
"github.com/hyperledger/fabric/core/crypto/bccsp" | ||
"github.com/hyperledger/fabric/core/crypto/bccsp/factory" | ||
"github.com/hyperledger/fabric/core/crypto/bccsp/signer" | ||
"github.com/hyperledger/fabric/core/crypto/bccsp/sw" | ||
) | ||
|
||
const ( | ||
// SKIPEM is the PEM type to identify an SKI (Subject Key Identifier) | ||
SKIPEM = "BCCSP SKI" | ||
) | ||
|
||
// Get returns an instance of the CSP (Crypto Service Provider) | ||
// given some config. If config is nil, return the default instance. | ||
func Get(cfg *Config) (bccsp.BCCSP, error) { | ||
if cfg != nil { | ||
return cfg.Get() | ||
} | ||
return factory.GetDefault() | ||
} | ||
|
||
// Config is the configuration for CSP (Crypto Service Provider) | ||
// which allows plugging in support for HSMs (Hardware Service Modules) | ||
// Currently supported types are: 'software' | ||
type Config struct { | ||
SW *SWConfig `json:"software,omitempty"` | ||
} | ||
|
||
// Get returns the instance of BCCSP for the config | ||
func (c *Config) Get() (bccsp.BCCSP, error) { | ||
if c.SW != nil { | ||
return c.SW.Get() | ||
} | ||
return nil, fmt.Errorf("Invalid configuration; must contain one of: 'software'") | ||
} | ||
|
||
// SWConfig is configuration for the software implementation of CSP | ||
type SWConfig struct { | ||
KeyStoreDir string `json:"key_store_dir,omitempty"` | ||
HashFamily string `json:"hash_family,omitempty"` | ||
SecurityLevel int `json:"security_level,omitempty"` | ||
Ephemeral bool `json:"ephemeral,omitempty"` | ||
} | ||
|
||
// Get returns the instance of the software CSP | ||
func (sc *SWConfig) Get() (bccsp.BCCSP, error) { | ||
// Set defaults | ||
keyStoreDir := getStrVal(sc.KeyStoreDir, path.Join(os.Getenv("HOME"), ".bccsp", "ks")) | ||
hashFamily := getStrVal(sc.HashFamily, "SHA2") | ||
secLevel := getIntVal(sc.SecurityLevel, 256) | ||
// Init keystore | ||
ks := &sw.FileBasedKeyStore{} | ||
err := ks.Init(nil, keyStoreDir, false) | ||
if err != nil { | ||
return nil, fmt.Errorf("Failed initializing software key store: %s", err) | ||
} | ||
// Return BCCSP instance | ||
bccspOpts := &factory.SwOpts{KeyStore: ks, SecLevel: secLevel, HashFamily: hashFamily, Ephemeral_: sc.Ephemeral} | ||
return factory.GetBCCSP(bccspOpts) | ||
} | ||
|
||
// GetSignerFromSKIFile returns a signer for an SKI file | ||
func GetSignerFromSKIFile(skiFile string, csp bccsp.BCCSP) (crypto.Signer, error) { | ||
if csp == nil { | ||
return nil, fmt.Errorf("csp is nil") | ||
} | ||
keyBuff, err := ioutil.ReadFile(skiFile) | ||
if err != nil { | ||
return nil, fmt.Errorf("Could not read SKI file [%s]: %s", skiFile, err) | ||
} | ||
|
||
block, _ := pem.Decode(keyBuff) | ||
if block == nil { | ||
return nil, fmt.Errorf("Failed decoding SKI file [%s]", skiFile) | ||
} | ||
|
||
if block.Type != SKIPEM { | ||
return nil, fmt.Errorf("Invalid PEM type in file %s; expecting '%s' but found '%s'", skiFile, SKIPEM, block.Type) | ||
} | ||
|
||
privateKey, err := csp.GetKey(block.Bytes) | ||
if err != nil { | ||
return nil, fmt.Errorf("Failed to get key from SKI file [%s]: %s", skiFile, err) | ||
} | ||
|
||
signer := &signer.CryptoSigner{} | ||
if err = signer.Init(csp, privateKey); err != nil { | ||
return nil, fmt.Errorf("Failed to initialize signer from SKI file [%s]: %s", skiFile, err) | ||
} | ||
|
||
return signer, nil | ||
} | ||
|
||
// GenRootKey generates a new root key | ||
func GenRootKey(csp bccsp.BCCSP) (bccsp.Key, error) { | ||
opts := &bccsp.AES256KeyGenOpts{Temporary: true} | ||
return csp.KeyGen(opts) | ||
} | ||
|
||
func getStrVal(val, def string) string { | ||
if val != "" { | ||
return val | ||
} | ||
return def | ||
} | ||
|
||
func getIntVal(val, def int) int { | ||
if val != 0 { | ||
return val | ||
} | ||
return def | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
Copyright IBM Corp. 2016 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 csp_test | ||
|
||
import ( | ||
"path" | ||
"testing" | ||
|
||
"github.com/hyperledger/fabric-ca/lib/csp" | ||
"github.com/hyperledger/fabric/core/crypto/bccsp" | ||
) | ||
|
||
func TestBCCSP(t *testing.T) { | ||
_, err := csp.Get(nil) | ||
if err != nil { | ||
t.Fatalf("Failed to get default BCCSP instance: %s", err) | ||
} | ||
_, err = csp.Get(&csp.Config{}) | ||
if err == nil { | ||
t.Fatal("Empty config should have failed but didn't") | ||
} | ||
cfg := &csp.Config{SW: &csp.SWConfig{KeyStoreDir: getTestFile("ks")}} | ||
bccsp, err := csp.Get(cfg) | ||
if err != nil { | ||
t.Fatalf("Failed to get test BCCSP instance: %s", err) | ||
} | ||
// GetSignerFromSKIFile test cases | ||
// 1st is positive and others are negative | ||
getSignerFromSKIFile("ec-key.ski", bccsp, "", t) | ||
getSignerFromSKIFile("bogus-file", bccsp, "bad file", t) | ||
getSignerFromSKIFile("", bccsp, "no file", t) | ||
getSignerFromSKIFile("ec-key.ski", nil, "nil bccsp", t) | ||
} | ||
|
||
func getSignerFromSKIFile(name string, bccsp bccsp.BCCSP, expectFailure string, t *testing.T) { | ||
file := getTestFile(name) | ||
_, err := csp.GetSignerFromSKIFile(file, bccsp) | ||
if err != nil { | ||
if expectFailure == "" { | ||
t.Errorf("Failed in GetSignerFromSKIFIle for file %s: %s", name, err) | ||
} | ||
} else { | ||
if expectFailure != "" { | ||
t.Errorf("Expected failure but passed: %s", expectFailure) | ||
} | ||
} | ||
} | ||
|
||
func getTestFile(name string) string { | ||
return path.Join(".", "testdata", name) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
-----BEGIN BCCSP SKI----- | ||
sLJGcSFzmXHJlmULJ9Ne8//jZlTKnS8dsZvbQu4i27c= | ||
-----END BCCSP SKI----- |
5 changes: 5 additions & 0 deletions
5
lib/csp/testdata/ks/50ab2450784f4f5b4a0c03062309ac503adaacb3a6520565c6e01ad8726e71e8_sk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
-----BEGIN ECDSA PRIVATE KEY----- | ||
MHcCAQEEIOvM4nwA6Aes5Epz8jAB0x/A1btNmByakm8+i9PtBLn1oAoGCCqGSM49 | ||
AwEHoUQDQgAENVNQtk56NgFCVPdw35unp3/jYvH4H4QLQaBuLcn3g2opRfRJBPQl | ||
E4wvGWozO4qyjg2TkGoQ0tPOr31uNgGr6Q== | ||
-----END ECDSA PRIVATE KEY----- |
5 changes: 5 additions & 0 deletions
5
lib/csp/testdata/ks/b0b2467121739971c996650b27d35ef3ffe36654ca9d2f1db19bdb42ee22dbb7_sk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
-----BEGIN ECDSA PRIVATE KEY----- | ||
MHcCAQEEINs5XopZVBEWTsUCCF8mU4H14/UN1alo+j5BzBQZ0PKtoAoGCCqGSM49 | ||
AwEHoUQDQgAEogflvYlpKaqJBcfKoL5yaScgJwWLkB11WOxCLMNXq5ni/qz49aIn | ||
LN8D+tO0y9gA+r/J4QekFQHWPTnebGekyw== | ||
-----END ECDSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
-----BEGIN BCCSP SKI----- | ||
UKskUHhPT1tKDAMGIwmsUDrarLOmUgVlxuAa2HJuceg= | ||
-----END BCCSP SKI----- |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.