diff --git a/core/chaincode/handler.go b/core/chaincode/handler.go index 74d21abc773..4338786ba08 100644 --- a/core/chaincode/handler.go +++ b/core/chaincode/handler.go @@ -1262,6 +1262,12 @@ func (handler *Handler) enterBusyState(e *fsm.Event, state string) { errHandler([]byte(err.Error()), "[%s]Failed to get chaincoed data (%s) for invoked chaincode. Sending %s", shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR) return } + + err = ccprovider.CheckInsantiationPolicy(calledCcIns.ChaincodeName, cd.Version, cd) + if err != nil { + errHandler([]byte(err.Error()), "[%s]CheckInsantiationPolicy, error %s. Sending %s", shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR) + return + } } else { //this is a system cc, just call it directly cd = &ccprovider.ChaincodeData{Name: calledCcIns.ChaincodeName, Version: util.GetSysCCVersion()} diff --git a/core/common/ccprovider/ccprovider.go b/core/common/ccprovider/ccprovider.go index f18aa80e866..1155bd263dd 100644 --- a/core/common/ccprovider/ccprovider.go +++ b/core/common/ccprovider/ccprovider.go @@ -26,6 +26,8 @@ import ( "github.com/golang/protobuf/proto" + "bytes" + "github.com/hyperledger/fabric/common/flogging" "github.com/hyperledger/fabric/core/ledger" pb "github.com/hyperledger/fabric/protos/peer" @@ -217,6 +219,37 @@ func PutChaincodeIntoFS(depSpec *pb.ChaincodeDeploymentSpec) error { } } +func CheckInsantiationPolicy(name, version string, cdLedger *ChaincodeData) error { + // we retrieve info about this chaincode from the file system + ccpack, err := GetChaincodeFromFS(name, version) + if err != nil { + return fmt.Errorf("Chaincode data for cc %s/%s was not found, error %s", name, version, err) + } + + // ccpack is guaranteed to be non-nil + cdLocalFS := ccpack.GetChaincodeData() + + // we have the info from the fs, check that the policy + // matches the one on the file system if one was specified; + // this check is required because the admin of this peer + // might have specified instantiation policies for their + // chaincode, for example to make sure that the chaincode + // is only instantiated on certain channels; a malicious + // peer on the other hand might have created a deploy + // transaction that attempts to bypass the instantiation + // policy. This check is there to ensure that this will not + // happen, i.e. that the peer will refuse to invoke the + // chaincode under these conditions. More info on + // https://jira.hyperledger.org/browse/FAB-3156 + if cdLocalFS.InstantiationPolicy != nil { + if !bytes.Equal(cdLocalFS.InstantiationPolicy, cdLedger.InstantiationPolicy) { + return fmt.Errorf("Instantiation policy mismatch for cc %s/%s", name, version) + } + } + + return nil +} + // GetCCPackage tries each known package implementation one by one // till the right package is found func GetCCPackage(buf []byte) (CCPackage, error) { diff --git a/core/endorser/endorser.go b/core/endorser/endorser.go index b4ae6a16d73..2f779002e6c 100644 --- a/core/endorser/endorser.go +++ b/core/endorser/endorser.go @@ -15,8 +15,6 @@ import ( "errors" - "bytes" - "github.com/hyperledger/fabric/common/policies" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/chaincode" @@ -234,30 +232,9 @@ func (e *Endorser) simulateProposal(ctx context.Context, chainID string, txid st } version = cdLedger.Version - // we retrieve info about this chaincode from the file system - ccpack, err := ccprovider.GetChaincodeFromFS(cid.Name, version) + err = ccprovider.CheckInsantiationPolicy(cid.Name, version, cdLedger) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("chaincode %s/%s not found on the file system, error %s", cid.Name, version, err) - } - // ccpack is guaranteed to be non-nil - cdLocalFS := ccpack.GetChaincodeData() - - // we have the info from the fs, check that the policy - // matches the one on the file system if one was specified; - // this check is required because the admin of this peer - // might have specified instantiation policies for their - // chaincode, for example to make sure that the chaincode - // is only instantiated on certain channels; a malicious - // peer on the other hand might have created a deploy - // transaction that attempts to bypass the instantiation - // policy. This check is there to ensure that this will not - // happen, i.e. that the peer will refuse to invoke the - // chaincode under these conditions. More info on - // https://jira.hyperledger.org/browse/FAB-3156 - if cdLocalFS.InstantiationPolicy != nil { - if !bytes.Equal(cdLocalFS.InstantiationPolicy, cdLedger.InstantiationPolicy) { - return nil, nil, nil, nil, fmt.Errorf("instantiation policy mismatch for cc %s/%s", cid.Name, version) - } + return nil, nil, nil, nil, err } } else { version = util.GetSysCCVersion()