Skip to content

Commit

Permalink
MSP crytpo and HASH cleanup
Browse files Browse the repository at this point in the history
This change-sets removes all dependencies to the crytpo/primitives package
from the msp package. The MSP uses now only the BCCSP for its cryptographic
operations.
This change-sets also removes all dependencies to the
primitives.Hash function. The BCCSP is used to replace thos calls.

Change-Id: Ia1432fac29745bb4f42b9acb8334caf69f115b3d
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
  • Loading branch information
adecaro committed Dec 13, 2016
1 parent e8daa0e commit 4464f6c
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 43 deletions.
9 changes: 9 additions & 0 deletions core/crypto/bccsp/factory/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ func GetDefault() (bccsp.BCCSP, error) {
return defaultBCCSP, nil
}

// GetDefaultOrPanic returns a non-ephemeral (long-term) BCCSP or panic if an error occurs.
func GetDefaultOrPanic() bccsp.BCCSP {
if err := initFactories(); err != nil {
panic(err)
}

return defaultBCCSP
}

// GetBCCSP returns a BCCSP created according to the options passed in input.
func GetBCCSP(opts Opts) (bccsp.BCCSP, error) {
if err := initFactories(); err != nil {
Expand Down
28 changes: 28 additions & 0 deletions core/crypto/bccsp/sw/dummyks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package sw

import (
"errors"

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

// DummyKeyStore is a read-only KeyStore that neither loads nor stores keys.
type DummyKeyStore struct {
}

// ReadOnly returns true if this KeyStore is read only, false otherwise.
// If ReadOnly is true then StoreKey will fail.
func (ks *DummyKeyStore) ReadOnly() bool {
return true
}

// GetKey returns a key object whose SKI is the one passed.
func (ks *DummyKeyStore) GetKey(ski []byte) (k bccsp.Key, err error) {
return nil, errors.New("Key not found. This is a dummy KeyStore")
}

// StoreKey stores the key k in this KeyStore.
// If this KeyStore is read only then the method will fail.
func (ks *DummyKeyStore) StoreKey(k bccsp.Key) (err error) {
return errors.New("Cannot store key. This is a dummy read-only KeyStore")
}
12 changes: 9 additions & 3 deletions core/crypto/bccsp/sw/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var (
)

// NewDefaultSecurityLevel returns a new instance of the software-based BCCSP
// at security level 256, hash family SHA2 and using FolderBasedKeyStore as keystore.
// at security level 256, hash family SHA2 and using FolderBasedKeyStore as KeyStore.
func NewDefaultSecurityLevel(keyStorePath string) (bccsp.BCCSP, error) {
ks := &FileBasedKeyStore{}
if err := ks.Init(nil, keyStorePath, false); err != nil {
Expand All @@ -56,8 +56,14 @@ func NewDefaultSecurityLevel(keyStorePath string) (bccsp.BCCSP, error) {
return New(256, "SHA2", ks)
}

// NewDefaultSecurityLevel returns a new instance of the software-based BCCSP
// at security level 256, hash family SHA2 and using the passed KeyStore.
func NewDefaultSecurityLevelWithKeystore(keyStore bccsp.KeyStore) (bccsp.BCCSP, error) {
return New(256, "SHA2", keyStore)
}

// New returns a new instance of the software-based BCCSP
// set at the passed security level, hash family and keystore.
// set at the passed security level, hash family and KeyStore.
func New(securityLevel int, hashFamily string, keyStore bccsp.KeyStore) (bccsp.BCCSP, error) {
// Init config
conf := &config{}
Expand All @@ -66,7 +72,7 @@ func New(securityLevel int, hashFamily string, keyStore bccsp.KeyStore) (bccsp.B
return nil, fmt.Errorf("Failed initializing configuration [%s]", err)
}

// Check keystore
// Check KeyStore
if keyStore == nil {
return nil, errors.New("Invalid bccsp.KeyStore instance. It must be different from nil.")
}
Expand Down
43 changes: 26 additions & 17 deletions msp/identities.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ import (

"encoding/asn1"

"errors"

"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/primitives"
)

type identity struct {
Expand All @@ -42,12 +42,12 @@ type identity struct {
pk bccsp.Key

// reference to the MSP that "owns" this identity
myMsp MSP
msp *bccspmsp
}

func newIdentity(id *IdentityIdentifier, cert *x509.Certificate, pk bccsp.Key, myMsp MSP) Identity {
func newIdentity(id *IdentityIdentifier, cert *x509.Certificate, pk bccsp.Key, msp *bccspmsp) Identity {
mspLogger.Infof("Creating identity instance for ID %s", id)
return &identity{id: id, cert: cert, pk: pk, myMsp: myMsp}
return &identity{id: id, cert: cert, pk: pk, msp: msp}
}

// GetIdentifier returns the identifier (MSPID/IDID) for this instance
Expand All @@ -62,7 +62,7 @@ func (id *identity) GetMSPIdentifier() string {

// IsValid returns nil if this instance is a valid identity or an error otherwise
func (id *identity) IsValid() error {
return id.myMsp.Validate(id)
return id.msp.Validate(id)
}

// GetOrganizationUnits returns the OU for this instance
Expand All @@ -76,21 +76,22 @@ func (id *identity) GetOrganizationUnits() string {
// signature; it returns nil if so or an error otherwise
func (id *identity) Verify(msg []byte, sig []byte) error {
mspLogger.Infof("Verifying signature")
bccsp, err := factory.GetDefault()

// Compute Hash
digest, err := id.msp.bccsp.Hash(msg, &bccsp.SHAOpts{})
if err != nil {
return fmt.Errorf("Failed getting default BCCSP [%s]", err)
} else if bccsp == nil {
return fmt.Errorf("Failed getting default BCCSP. Nil instance.")
return fmt.Errorf("Failed computing digest [%s]", err)
}

valid, err := bccsp.Verify(id.pk, sig, primitives.Hash(msg), nil)
// Verify signature
valid, err := id.msp.bccsp.Verify(id.pk, sig, digest, nil)
if err != nil {
return fmt.Errorf("Could not determine the validity of the signature, err %s", err)
} else if !valid {
return fmt.Errorf("The signature is invalid")
} else {
return nil
return errors.New("The signature is invalid")
}

return nil
}

func (id *identity) VerifyOpts(msg []byte, sig []byte, opts SignatureOpts) error {
Expand Down Expand Up @@ -131,15 +132,23 @@ type signingidentity struct {
signer *signer.CryptoSigner
}

func newSigningIdentity(id *IdentityIdentifier, cert *x509.Certificate, pk bccsp.Key, signer *signer.CryptoSigner, myMsp MSP) SigningIdentity {
func newSigningIdentity(id *IdentityIdentifier, cert *x509.Certificate, pk bccsp.Key, signer *signer.CryptoSigner, msp *bccspmsp) SigningIdentity {
mspLogger.Infof("Creating signing identity instance for ID %s", id)
return &signingidentity{identity{id: id, cert: cert, pk: pk, myMsp: myMsp}, signer}
return &signingidentity{identity{id: id, cert: cert, pk: pk, msp: msp}, signer}
}

// Sign produces a signature over msg, signed by this instance
func (id *signingidentity) Sign(msg []byte) ([]byte, error) {
mspLogger.Infof("Signing message")
return id.signer.Sign(rand.Reader, primitives.Hash(msg), nil)

// Compute Hash
digest, err := id.msp.bccsp.Hash(msg, &bccsp.SHAOpts{})
if err != nil {
return nil, fmt.Errorf("Failed computing digest [%s]", err)
}

// Sign
return id.signer.Sign(rand.Reader, digest, nil)
}

func (id *signingidentity) SignOpts(msg []byte, opts SignatureOpts) ([]byte, error) {
Expand Down
4 changes: 0 additions & 4 deletions msp/msp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"os"
"reflect"
"testing"

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

var localMsp MSP
Expand Down Expand Up @@ -158,8 +156,6 @@ func TestSignAndVerify(t *testing.T) {
}

func TestMain(m *testing.M) {
primitives.SetSecurityLevel("SHA2", 256)

retVal := m.Run()
os.Exit(retVal)
}
11 changes: 5 additions & 6 deletions msp/mspimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import (
"encoding/asn1"

"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"
)

// This is an instantiation of an MSP that
Expand Down Expand Up @@ -58,12 +58,11 @@ type bccspmsp struct {
func NewBccspMsp() (MSP, error) {
mspLogger.Infof("Creating BCCSP-based MSP instance")

/* TODO: is the default BCCSP okay here?*/
bccsp, err := factory.GetDefault()
// TODO: security level, hash family and keystore should
// be probably set in the appropriate way.
bccsp, err := sw.NewDefaultSecurityLevelWithKeystore(&sw.DummyKeyStore{})
if err != nil {
return nil, fmt.Errorf("Failed getting default BCCSP [%s]", err)
} else if bccsp == nil {
return nil, fmt.Errorf("Failed getting default BCCSP. Nil instance.")
return nil, fmt.Errorf("Failed initiliazing BCCSP [%s]", err)
}

theMsp := &bccspmsp{}
Expand Down
4 changes: 0 additions & 4 deletions peer/chaincode/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"github.com/hyperledger/fabric/peer/common"
pb "github.com/hyperledger/fabric/protos/peer"
// "github.com/hyperledger/fabric/protos/utils"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/peer/msp"
)

Expand Down Expand Up @@ -55,7 +54,6 @@ func initMSP() {
}

func TestUpgradeCmd(t *testing.T) {
primitives.SetSecurityLevel("SHA2", 256)
InitMSP()

signer, err := common.GetDefaultSigner()
Expand Down Expand Up @@ -90,7 +88,6 @@ func TestUpgradeCmd(t *testing.T) {
}

func TestUpgradeCmdEndorseFail(t *testing.T) {
primitives.SetSecurityLevel("SHA2", 256)
InitMSP()

signer, err := common.GetDefaultSigner()
Expand Down Expand Up @@ -129,7 +126,6 @@ func TestUpgradeCmdEndorseFail(t *testing.T) {
}

func TestUpgradeCmdSendTXFail(t *testing.T) {
primitives.SetSecurityLevel("SHA2", 256)
InitMSP()

signer, err := common.GetDefaultSigner()
Expand Down
24 changes: 15 additions & 9 deletions protos/utils/txutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import (
"bytes"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/crypto/bccsp"
"github.com/hyperledger/fabric/core/crypto/bccsp/factory"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/peer"
Expand Down Expand Up @@ -255,11 +256,11 @@ func GetBytesProposalPayloadForTx(payload *peer.ChaincodeProposalPayload, visibi
// here, as an example, I'll code the visibility policy that allows the
// full header but only the hash of the payload

// TODO: use bccsp interfaces and providers as soon as they are ready!
hash := primitives.GetDefaultHash()()
hash.Write(cppBytes) // hash the serialized ChaincodeProposalPayload object (stripped of the transient bytes)

return hash.Sum(nil), nil
digest, err := factory.GetDefaultOrPanic().Hash(cppBytes, &bccsp.SHAOpts{})
if err != nil {
return nil, fmt.Errorf("Failed computing digest [%s]", err)
}
return digest, nil
}

// GetProposalHash2 gets the proposal hash - this version
Expand All @@ -272,8 +273,10 @@ func GetProposalHash2(header []byte, ccPropPayl []byte) ([]byte, error) {
return nil, fmt.Errorf("Nil arguments")
}

// TODO: use bccsp interfaces and providers as soon as they are ready!
hash := primitives.GetDefaultHash()()
hash, err := factory.GetDefaultOrPanic().GetHash(&bccsp.SHAOpts{})
if err != nil {
return nil, fmt.Errorf("Failed instantiating hash function [%s]", err)
}
hash.Write(header) // hash the serialized Header object
hash.Write(ccPropPayl) // hash the bytes of the chaincode proposal payload that we are given

Expand Down Expand Up @@ -301,7 +304,10 @@ func GetProposalHash1(header []byte, ccPropPayl []byte, visibility []byte) ([]by
}

// TODO: use bccsp interfaces and providers as soon as they are ready!
hash2 := primitives.GetDefaultHash()()
hash2, err := factory.GetDefaultOrPanic().GetHash(&bccsp.SHAOpts{})
if err != nil {
return nil, fmt.Errorf("Failed instantiating hash function [%s]", err)
}
hash2.Write(header) // hash the serialized Header object
hash2.Write(ppBytes) // hash of the part of the chaincode proposal payload that will go to the tx

Expand Down

0 comments on commit 4464f6c

Please sign in to comment.