Skip to content

Commit

Permalink
Rework of MSP (config and factories)
Browse files Browse the repository at this point in the history
This change-set introduces a local MSP and per-chain MSPs for the peer to use.
The local MSP is configured from local config files and is used to get the
signing identity for the peer. Per-chain MSPs are used on each chain to
validate creators/signatures on the various messages. Additionally, in
msp/configfilegenerator there is a sample program file that shows how the
client config may be built out of certificates and keys. It can be removed
later on but it is useful for now to show how to construct that file.

Change-Id: Id9b92a96800a67b27124cc98a6228ad3e03f531a
Signed-off-by: Alessandro Sorniotti <ale.linux@sopit.net>
  • Loading branch information
ale-linux committed Dec 8, 2016
1 parent 3ea19f3 commit 96637cf
Show file tree
Hide file tree
Showing 33 changed files with 727 additions and 546 deletions.
8 changes: 3 additions & 5 deletions core/chaincode/exectransaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
putils "github.com/hyperledger/fabric/protos/utils"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/core/config"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/common"
Expand Down Expand Up @@ -1061,11 +1062,8 @@ func TestMain(m *testing.M) {

// setup the MSP manager so that we can sign/verify
mspMgrConfigFile := "../../msp/peer-config.json"
msp.GetManager().Setup(mspMgrConfigFile)
mspID := "DEFAULT"
id := "PEER"
signingIdentity := &msp.IdentityIdentifier{Mspid: msp.ProviderIdentifier{Value: mspID}, Value: id}
signer, err = msp.GetManager().GetSigningIdentity(signingIdentity)
config.SetupFakeMSPInfrastructureForTests(mspMgrConfigFile)
signer, err = msp.GetLocalMSP().GetDefaultSigningIdentity()
if err != nil {
os.Exit(-1)
fmt.Printf("Could not initialize msp/signer")
Expand Down
2 changes: 1 addition & 1 deletion core/chaincode/importsysccs.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var systemChaincodes = []*SystemChaincode{
Enabled: true,
Name: "escc",
Path: "github.com/hyperledger/fabric/core/system_chaincode/escc",
InitArgs: [][]byte{[]byte("DEFAULT"), []byte("PEER")}, // TODO: retrieve these aruments properly
InitArgs: [][]byte{[]byte("")},
Chaincode: &escc.EndorserOneValidSignature{},
},
{
Expand Down
61 changes: 61 additions & 0 deletions core/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import (
"runtime"
"strings"

"encoding/json"
"io/ioutil"

"github.com/hyperledger/fabric/core/util"
"github.com/hyperledger/fabric/msp"
"github.com/op/go-logging"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -75,3 +80,59 @@ func SetupTestConfig(pathToOpenchainYaml string) {
configLogger.Debugf("setting Number of procs to %d, was %d\n", numProcsDesired, runtime.GOMAXPROCS(2))

}

func getPeerConfFromFile(configFile string) (*msp.NodeLocalConfig, error) {
file, err := ioutil.ReadFile(configFile)
if err != nil {
return nil, fmt.Errorf("Could not read file %s, err %s", configFile, err)
}

var localConf msp.NodeLocalConfig
err = json.Unmarshal(file, &localConf)
if err != nil {
return nil, fmt.Errorf("Could not unmarshal config, err %s", err)
}

return &localConf, nil
}

func LoadLocalMSPConfig(configFile string) error {
localConf, err := getPeerConfFromFile(configFile)
if err != nil {
return err
}

if localConf.LocalMSP == nil {
return fmt.Errorf("nil LocalMSP")
}

err = msp.GetLocalMSP().Setup(localConf.LocalMSP)
if err != nil {
return fmt.Errorf("Could not setup local msp, err %s", err)
}

// TODO: setup BCCSP here using localConf.BCCSP

return nil
}

func SetupFakeMSPInfrastructureForTests(configFile string) error {
err := LoadLocalMSPConfig(configFile)
if err != nil {
return err
}

localConf, err := getPeerConfFromFile(configFile)
if err != nil {
return err
}

mgrconf := &msp.MSPManagerConfig{MspList: []*msp.MSPConfig{localConf.LocalMSP}, Name: "MGRFORTESTCHAIN"}

err = msp.GetManagerForChain(util.GetTestChainID()).Setup(mgrconf)
if err != nil {
return err
}

return nil
}
8 changes: 3 additions & 5 deletions core/endorser/endorser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/core/chaincode"
"github.com/hyperledger/fabric/core/config"
"github.com/hyperledger/fabric/core/container"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/ledger/kvledger"
Expand Down Expand Up @@ -369,11 +370,8 @@ func TestMain(m *testing.M) {

// setup the MSP manager so that we can sign/verify
mspMgrConfigFile := "../../msp/peer-config.json"
msp.GetManager().Setup(mspMgrConfigFile)
mspID := "DEFAULT"
id := "PEER"
signingIdentity := &msp.IdentityIdentifier{Mspid: msp.ProviderIdentifier{Value: mspID}, Value: id}
signer, err = msp.GetManager().GetSigningIdentity(signingIdentity)
config.SetupFakeMSPInfrastructureForTests(mspMgrConfigFile)
signer, err = msp.GetLocalMSP().GetDefaultSigningIdentity()
if err != nil {
os.Exit(-1)
fmt.Printf("Could not initialize msp/signer")
Expand Down
11 changes: 5 additions & 6 deletions core/peer/fullflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"fmt"
"os"

"github.com/hyperledger/fabric/core/config"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/util"
"github.com/hyperledger/fabric/msp"
Expand Down Expand Up @@ -160,7 +161,7 @@ func TestBadProp(t *testing.T) {
}

// get a bad signing identity
badSigner, err := msp.NewNoopMsp().GetSigningIdentity(nil)
badSigner, err := msp.NewNoopMsp().GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("Couldn't get noop signer")
return
Expand Down Expand Up @@ -316,16 +317,14 @@ func TestMain(m *testing.M) {
primitives.SetSecurityLevel("SHA2", 256)
// setup the MSP manager so that we can sign/verify
mspMgrConfigFile := "../../msp/peer-config.json"
err := msp.GetManager().Setup(mspMgrConfigFile)
err := config.SetupFakeMSPInfrastructureForTests(mspMgrConfigFile)
if err != nil {
os.Exit(-1)
fmt.Printf("Could not initialize msp")
return
}
mspId := "DEFAULT"
id := "PEER"
signingIdentity := &msp.IdentityIdentifier{Mspid: msp.ProviderIdentifier{Value: mspId}, Value: id}
signer, err = msp.GetManager().GetSigningIdentity(signingIdentity)

signer, err = msp.GetLocalMSP().GetDefaultSigningIdentity()
if err != nil {
os.Exit(-1)
fmt.Printf("Could not get signer")
Expand Down
8 changes: 4 additions & 4 deletions core/peer/msgvalidation.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func ValidateProposalMessage(signedProp *pb.SignedProposal) (*pb.Proposal, *comm
}

// validate the signature
err = checkSignatureFromCreator(hdr.SignatureHeader.Creator, signedProp.Signature, signedProp.ProposalBytes)
err = checkSignatureFromCreator(hdr.SignatureHeader.Creator, signedProp.Signature, signedProp.ProposalBytes, hdr.ChainHeader.ChainID)
if err != nil {
return nil, nil, nil, err
}
Expand All @@ -105,7 +105,7 @@ func ValidateProposalMessage(signedProp *pb.SignedProposal) (*pb.Proposal, *comm
// given a creator, a message and a signature,
// this function returns nil if the creator
// is a valid cert and the signature is valid
func checkSignatureFromCreator(creatorBytes []byte, sig []byte, msg []byte) error {
func checkSignatureFromCreator(creatorBytes []byte, sig []byte, msg []byte, ChainID string) error {
putilsLogger.Infof("checkSignatureFromCreator starts")

// check for nil argument
Expand All @@ -114,7 +114,7 @@ func checkSignatureFromCreator(creatorBytes []byte, sig []byte, msg []byte) erro
}

// get the identity of the creator
creator, err := msp.GetManager().DeserializeIdentity(creatorBytes)
creator, err := msp.GetManagerForChain(ChainID).DeserializeIdentity(creatorBytes)
if err != nil {
return fmt.Errorf("Failed to deserialize creator identity, err %s", err)
}
Expand Down Expand Up @@ -321,7 +321,7 @@ func ValidateTransaction(e *common.Envelope) (*common.Payload, []*pb.Transaction
}

// validate the signature in the envelope
err = checkSignatureFromCreator(payload.Header.SignatureHeader.Creator, e.Signature, e.Payload)
err = checkSignatureFromCreator(payload.Header.SignatureHeader.Creator, e.Signature, e.Payload, payload.Header.ChainHeader.ChainID)
if err != nil {
return nil, nil, err
}
Expand Down
33 changes: 9 additions & 24 deletions core/system_chaincode/escc/endorser_onevalidsignature.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,11 @@ var logger = logging.MustGetLogger("escc")
// EndorserOneValidSignature implements the default endorsement policy, which is to
// sign the proposal hash and the read-write set
type EndorserOneValidSignature struct {
signerId *msp.IdentityIdentifier
}

// Init is called once when the chaincode started the first time
// There are 2 mandatory arguments
// args[0] the msp identifier for the ESCC's signer
// args[1] the identifier for the ESCC's signer within the msp
func (e *EndorserOneValidSignature) Init(stub shim.ChaincodeStubInterface) ([]byte, error) {
// Obtain the identifier of the identity that will be used to sign
// Note that we cache this identity once and for all. If there is
// the need to change the signing identity, there are several options:
// 1) pass the desired signing identity as an optional argument to ESCC
// 2) expose an ESCC Invoke function that changes the siging identity
args := stub.GetArgs()
if len(args) != 2 {
return nil, fmt.Errorf("Incorrect number of arguments (expected 2, provided %d)", len(args))
}
e.signerId = &msp.IdentityIdentifier{Mspid: msp.ProviderIdentifier{Value: string(args[0])}, Value: string(args[1])}

logger.Infof("Successfully initialized ESCC with identity: %s", e.signerId)
logger.Infof("Successfully initialized ESCC")

return nil, nil
}
Expand Down Expand Up @@ -127,15 +112,15 @@ func (e *EndorserOneValidSignature) Invoke(stub shim.ChaincodeStubInterface) ([]
visibility = args[5]
}

// obtain the identity that will sign this proposal response
// NOTE: we must obtain it every time: while e.signerId remains
// constant, the corresponding cert might (and will) change
// and so we cannot cache the result of this call; GetSigningIdentity
// on the other hand will cache the identity as long as it
// doesn't change
signingEndorser, err := msp.GetManager().GetSigningIdentity(e.signerId)
// obtain the default signing identity for this peer; it will be used to sign this proposal response
localMsp := msp.GetLocalMSP()
if localMsp == nil {
return nil, fmt.Errorf("Nil local MSP manager")
}

signingEndorser, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
return nil, fmt.Errorf("Could not obtain the signing identity for %s, err %s", e.signerId, err)
return nil, fmt.Errorf("Could not obtain the default signing identity, err %s", err)
}

// obtain a proposal response
Expand Down
9 changes: 5 additions & 4 deletions core/system_chaincode/escc/endorser_onevalidsignature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"os"

"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/core/config"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/peer"
"github.com/hyperledger/fabric/core/util"
Expand Down Expand Up @@ -101,7 +102,7 @@ func TestInvoke(t *testing.T) {

cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: cs}

sId, err := msp.GetManager().GetSigningIdentity(&msp.IdentityIdentifier{Mspid: msp.ProviderIdentifier{Value: "DEFAULT"}, Value: "PEER"})
sId, err := msp.GetLocalMSP().GetDefaultSigningIdentity()
if err != nil {
t.Fail()
t.Fatalf("couldn't obtain identity: err %s", err)
Expand Down Expand Up @@ -235,7 +236,7 @@ func validateProposalResponse(prBytes []byte, proposal *pb.Proposal, visibility
}

// get the identity of the endorser
endorser, err := msp.GetManager().DeserializeIdentity(pResp.Endorsement.Endorser)
endorser, err := msp.GetManagerForChain(util.GetTestChainID()).DeserializeIdentity(pResp.Endorsement.Endorser)
if err != nil {
return fmt.Errorf("Failed to deserialize endorser identity, err %s", err)
}
Expand All @@ -258,7 +259,7 @@ func validateProposalResponse(prBytes []byte, proposal *pb.Proposal, visibility
// as extra, we assemble a transaction, sign it and then validate it

// obtain signer for the transaction
sId, err := msp.GetManager().GetSigningIdentity(&msp.IdentityIdentifier{Mspid: msp.ProviderIdentifier{Value: "DEFAULT"}, Value: "PEER"})
sId, err := msp.GetLocalMSP().GetDefaultSigningIdentity()
if err != nil {
return fmt.Errorf("couldn't obtain identity: err %s", err)
}
Expand All @@ -283,7 +284,7 @@ func TestMain(m *testing.M) {
// setup the MSP manager so that we can sign/verify
// TODO: determine the config file for the MSP
mspMgrConfigFile := "../../../msp/peer-config.json"
msp.GetManager().Setup(mspMgrConfigFile)
config.SetupFakeMSPInfrastructureForTests(mspMgrConfigFile)

os.Exit(m.Run())
}
2 changes: 1 addition & 1 deletion core/system_chaincode/vscc/validator_onevalidsignature.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (vscc *ValidatorOneValidSignature) Invoke(stub shim.ChaincodeStubInterface)
// loop through each of the endorsements
for _, endorsement := range cap.Action.Endorsements {
// extract the identity of the signer
end, err := msp.GetManager().DeserializeIdentity(endorsement.Endorser)
end, err := msp.GetManagerForChain(payl.Header.ChainHeader.ChainID).DeserializeIdentity(endorsement.Endorser)
if err != nil {
logger.Errorf("VSCC error: DeserializeIdentity failed, err %s", err)
return nil, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"os"

"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/core/config"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/util"
"github.com/hyperledger/fabric/msp"
Expand Down Expand Up @@ -103,9 +104,9 @@ func TestMain(m *testing.M) {
primitives.InitSecurityLevel("SHA2", 256)
// setup the MSP manager so that we can sign/verify
mspMgrConfigFile := "../../../msp/peer-config.json"
msp.GetManager().Setup(mspMgrConfigFile)
config.SetupFakeMSPInfrastructureForTests(mspMgrConfigFile)

id, err = msp.GetManager().GetSigningIdentity(&msp.IdentityIdentifier{Mspid: msp.ProviderIdentifier{Value: "DEFAULT"}, Value: "PEER"})
id, err = msp.GetLocalMSP().GetDefaultSigningIdentity()
if err != nil {
fmt.Printf("GetSigningIdentity failed with err %s", err)
os.Exit(-1)
Expand Down
32 changes: 0 additions & 32 deletions msp/FABRIC-MSPconfig.json

This file was deleted.

19 changes: 0 additions & 19 deletions msp/MSPManager-config.json

This file was deleted.

0 comments on commit 96637cf

Please sign in to comment.