Skip to content

Commit

Permalink
BCCSP improved test coverage
Browse files Browse the repository at this point in the history
This change-set improves the test coverage of the BCCSP package
and fix a few bugs found during the process.

This change-set comes in the context of:
https://jira.hyperledger.org/browse/FAB-354

Change-Id: I78ed4a36ca32166c6271b98935569eb3d997475e
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
  • Loading branch information
adecaro committed Nov 25, 2016
1 parent 9cd44a1 commit 7ea7554
Show file tree
Hide file tree
Showing 8 changed files with 541 additions and 207 deletions.
6 changes: 3 additions & 3 deletions core/crypto/bccsp/sw/aeskey.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ import (
)

type aesPrivateKey struct {
k []byte
privKey []byte
exportable bool
}

// Bytes converts this key to its byte representation,
// if this operation is allowed.
func (k *aesPrivateKey) Bytes() (raw []byte, err error) {
if k.exportable {
return k.k, nil
return k.privKey, nil
}

return nil, errors.New("Not supported.")
Expand All @@ -41,7 +41,7 @@ func (k *aesPrivateKey) Bytes() (raw []byte, err error) {
// SKI returns the subject key identifier of this key.
func (k *aesPrivateKey) SKI() (ski []byte) {
hash := sha256.New()
hash.Write(k.k)
hash.Write(k.privKey)
return hash.Sum(nil)
}

Expand Down
20 changes: 11 additions & 9 deletions core/crypto/bccsp/sw/ecdsakey.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,30 @@ import (

"crypto/sha256"

"errors"

"github.com/hyperledger/fabric/core/crypto/bccsp"
"github.com/hyperledger/fabric/core/crypto/primitives"
)

type ecdsaPrivateKey struct {
k *ecdsa.PrivateKey
privKey *ecdsa.PrivateKey
}

// FIXME: remove as soon as there's a way to import the key more properly
func NewEcdsaPrivateKey(k *ecdsa.PrivateKey) bccsp.Key {
return &ecdsaPrivateKey{k: k}
return &ecdsaPrivateKey{privKey: k}
}

// Bytes converts this key to its byte representation,
// if this operation is allowed.
func (k *ecdsaPrivateKey) Bytes() (raw []byte, err error) {
return
return nil, errors.New("Not supported.")
}

// SKI returns the subject key identifier of this key.
func (k *ecdsaPrivateKey) SKI() (ski []byte) {
raw, _ := primitives.PrivateKeyToDER(k.k)
raw, _ := primitives.PrivateKeyToDER(k.privKey)
// TODO: Error should not be thrown. Anyway, move the marshalling at initialization.

hash := sha256.New()
Expand All @@ -66,22 +68,22 @@ func (k *ecdsaPrivateKey) Private() bool {
// PublicKey returns the corresponding public key part of an asymmetric public/private key pair.
// This method returns an error in symmetric key schemes.
func (k *ecdsaPrivateKey) PublicKey() (bccsp.Key, error) {
return &ecdsaPublicKey{&k.k.PublicKey}, nil
return &ecdsaPublicKey{&k.privKey.PublicKey}, nil
}

type ecdsaPublicKey struct {
k *ecdsa.PublicKey
pubKey *ecdsa.PublicKey
}

// FIXME: remove as soon as there's a way to import the key more properly
func NewEcdsaPublicKey(k *ecdsa.PublicKey) bccsp.Key {
return &ecdsaPublicKey{k: k}
return &ecdsaPublicKey{pubKey: k}
}

// Bytes converts this key to its byte representation,
// if this operation is allowed.
func (k *ecdsaPublicKey) Bytes() (raw []byte, err error) {
raw, err = x509.MarshalPKIXPublicKey(k.k)
raw, err = x509.MarshalPKIXPublicKey(k.pubKey)
if err != nil {
return nil, fmt.Errorf("Failed marshalling key [%s]", err)
}
Expand All @@ -90,7 +92,7 @@ func (k *ecdsaPublicKey) Bytes() (raw []byte, err error) {

// SKI returns the subject key identifier of this key.
func (k *ecdsaPublicKey) SKI() (ski []byte) {
raw, _ := primitives.PublicKeyToPEM(k.k, nil)
raw, _ := primitives.PublicKeyToPEM(k.pubKey, nil)
// TODO: Error should not be thrown. Anyway, move the marshalling at initialization.

hash := sha256.New()
Expand Down
43 changes: 23 additions & 20 deletions core/crypto/bccsp/sw/fileks.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (ks *FileBasedKeyStore) GetKey(ski []byte) (k bccsp.Key, err error) {
// Load the private key
key, err := ks.loadPrivateKey(hex.EncodeToString(ski))
if err != nil {
return nil, fmt.Errorf("Failed loading key [%x] [%s]", ski, err)
return nil, fmt.Errorf("Failed loading secret key [%x] [%s]", ski, err)
}

switch key.(type) {
Expand All @@ -134,10 +134,25 @@ func (ks *FileBasedKeyStore) GetKey(ski []byte) (k bccsp.Key, err error) {
case *rsa.PrivateKey:
return &rsaPrivateKey{key.(*rsa.PrivateKey)}, nil
default:
return nil, errors.New("Key type not recognized")
return nil, errors.New("Secret key type not recognized")
}
case "pk":
// Load the public key
key, err := ks.loadPublicKey(hex.EncodeToString(ski))
if err != nil {
return nil, fmt.Errorf("Failed loading public key [%x] [%s]", ski, err)
}

switch key.(type) {
case *ecdsa.PublicKey:
return &ecdsaPublicKey{key.(*ecdsa.PublicKey)}, nil
case *rsa.PublicKey:
return &rsaPublicKey{key.(*rsa.PublicKey)}, nil
default:
return nil, errors.New("Public key type not recognized")
}
default:
return nil, errors.New("Key not recognized")
return nil, errors.New("Key type not recognized")
}
}

Expand All @@ -155,39 +170,39 @@ func (ks *FileBasedKeyStore) StoreKey(k bccsp.Key) (err error) {
case *ecdsaPrivateKey:
kk := k.(*ecdsaPrivateKey)

err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.k)
err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey)
if err != nil {
return fmt.Errorf("Failed storing ECDSA private key [%s]", err)
}

case *ecdsaPublicKey:
kk := k.(*ecdsaPublicKey)

err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.k)
err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.pubKey)
if err != nil {
return fmt.Errorf("Failed storing ECDSA public key [%s]", err)
}

case *rsaPrivateKey:
kk := k.(*rsaPrivateKey)

err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.k)
err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey)
if err != nil {
return fmt.Errorf("Failed storing RSA private key [%s]", err)
}

case *rsaPublicKey:
kk := k.(*rsaPublicKey)

err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.k)
err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.pubKey)
if err != nil {
return fmt.Errorf("Failed storing RSA public key [%s]", err)
}

case *aesPrivateKey:
kk := k.(*aesPrivateKey)

err = ks.storeKey(hex.EncodeToString(k.SKI()), kk.k)
err = ks.storeKey(hex.EncodeToString(k.SKI()), kk.privKey)
if err != nil {
return fmt.Errorf("Failed storing AES key [%s]", err)
}
Expand Down Expand Up @@ -219,10 +234,6 @@ func (ks *FileBasedKeyStore) getSuffix(alias string) string {
}

func (ks *FileBasedKeyStore) storePrivateKey(alias string, privateKey interface{}) error {
if ks.readOnly {
return errors.New("Read only KeyStore.")
}

rawKey, err := primitives.PrivateKeyToPEM(privateKey, ks.pwd)
if err != nil {
logger.Errorf("Failed converting private key to PEM [%s]: [%s]", alias, err)
Expand All @@ -239,10 +250,6 @@ func (ks *FileBasedKeyStore) storePrivateKey(alias string, privateKey interface{
}

func (ks *FileBasedKeyStore) storePublicKey(alias string, publicKey interface{}) error {
if ks.readOnly {
return errors.New("Read only KeyStore.")
}

rawKey, err := primitives.PublicKeyToPEM(publicKey, ks.pwd)
if err != nil {
logger.Errorf("Failed converting public key to PEM [%s]: [%s]", alias, err)
Expand All @@ -259,10 +266,6 @@ func (ks *FileBasedKeyStore) storePublicKey(alias string, publicKey interface{})
}

func (ks *FileBasedKeyStore) storeKey(alias string, key []byte) error {
if ks.readOnly {
return errors.New("Read only KeyStore.")
}

pem, err := primitives.AEStoEncryptedPEM(key, ks.pwd)
if err != nil {
logger.Errorf("Failed converting key to PEM [%s]: [%s]", alias, err)
Expand Down
66 changes: 66 additions & 0 deletions core/crypto/bccsp/sw/fileks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
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 sw

import (
"fmt"
"os"
"path/filepath"
"testing"
)

func TestInvalidStoreKey(t *testing.T) {
ks := &FileBasedKeyStore{}
if err := ks.Init(nil, filepath.Join(os.TempDir(), "bccspks"), false); err != nil {
fmt.Printf("Failed initiliazing KeyStore [%s]", err)
os.Exit(-1)
}

err := ks.StoreKey(nil)
if err == nil {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&ecdsaPrivateKey{nil})
if err == nil {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&ecdsaPublicKey{nil})
if err == nil {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&rsaPublicKey{nil})
if err == nil {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&rsaPrivateKey{nil})
if err == nil {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&aesPrivateKey{nil, false})
if err == nil {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&aesPrivateKey{nil, true})
if err == nil {
t.Fatal("Error should be different from nil in this case")
}
}

0 comments on commit 7ea7554

Please sign in to comment.