go_study/fabric-main/integration/msp/msp_test.go

249 lines
8.6 KiB
Go

/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package msp
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"syscall"
docker "github.com/fsouza/go-dockerclient"
"github.com/hyperledger/fabric/integration/channelparticipation"
"github.com/hyperledger/fabric/integration/nwo"
"github.com/hyperledger/fabric/integration/nwo/commands"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
"github.com/tedsuo/ifrit"
ginkgomon "github.com/tedsuo/ifrit/ginkgomon_v2"
)
var _ = Describe("MSP identity test on a network with mutual TLS required", func() {
var (
client *docker.Client
tempDir string
network *nwo.Network
ordererRunner *ginkgomon.Runner
ordererProcess, peerProcess ifrit.Process
)
BeforeEach(func() {
var err error
tempDir, err = ioutil.TempDir("", "msp")
Expect(err).NotTo(HaveOccurred())
client, err = docker.NewClientFromEnv()
Expect(err).NotTo(HaveOccurred())
network = nwo.New(nwo.BasicEtcdRaft(), tempDir, client, StartPort(), components)
})
AfterEach(func() {
if ordererProcess != nil {
ordererProcess.Signal(syscall.SIGTERM)
Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive())
}
if peerProcess != nil {
peerProcess.Signal(syscall.SIGTERM)
Eventually(peerProcess.Wait(), network.EventuallyTimeout).Should(Receive())
}
if network != nil {
network.Cleanup()
}
os.RemoveAll(tempDir)
})
It("invokes chaincode on a peer that does not have a valid endorser identity", func() {
By("setting TLS ClientAuthRequired to be true for all peers and orderers")
network.ClientAuthRequired = true
By("disabling NodeOU for org2")
// Org2 Peer0 is used to test chaincode endorsement policy not satisfied due to peer's MSP
// does not define Node OU.
Org2 := network.Organization("Org2")
Org2.EnableNodeOUs = false
network.GenerateConfigTree()
network.Bootstrap()
By("starting all processes for fabric")
ordererRunner, ordererProcess, peerProcess = network.StartSingleOrdererNetwork("orderer")
org1Peer0 := network.Peer("Org1", "peer0")
org2Peer0 := network.Peer("Org2", "peer0")
orderer := network.Orderer("orderer")
By("creating and joining channels")
channelparticipation.JoinOrdererJoinPeersAppChannel(network, "testchannel", orderer, ordererRunner)
By("enabling new lifecycle capabilities")
nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
chaincode := nwo.Chaincode{
Name: "mycc",
Version: "0.0",
Path: "github.com/hyperledger/fabric/integration/chaincode/simple/cmd",
Lang: "golang",
PackageFile: filepath.Join(tempDir, "simplecc.tar.gz"),
Ctor: `{"Args":["init","a","100","b","200"]}`,
SignaturePolicy: `OR ('Org1MSP.peer', 'Org2MSP.peer')`,
Sequence: "1",
InitRequired: true,
Label: "my_simple_chaincode",
}
By("deploying the chaincode")
nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
By("querying and invoking chaincode with mutual TLS enabled")
RunQueryInvokeQuery(network, orderer, org1Peer0, 100)
By("querying the chaincode with org2 peer")
sess, err := network.PeerUserSession(org2Peer0, "User1", commands.ChaincodeQuery{
ChannelID: "testchannel",
Name: "mycc",
Ctor: `{"Args":["query","a"]}`,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say("90"))
// Testing scenario one: chaincode endorsement policy not satisfied due to peer's MSP does not define
// the peer node OU.
By("attempting to invoke chaincode on a peer that does not have a valid endorser identity (endorsing peer has member identity)")
sess, err = network.PeerUserSession(org2Peer0, "User1", commands.ChaincodeInvoke{
ChannelID: "testchannel",
Orderer: network.OrdererAddress(orderer, nwo.ListenPort),
Name: "mycc",
Ctor: `{"Args":["invoke","a","b","10"]}`,
PeerAddresses: []string{
network.PeerAddress(network.Peer("Org2", "peer0"), nwo.ListenPort),
},
WaitForEvent: true,
ClientAuth: network.ClientAuthRequired,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
Expect(sess.Err).To(gbytes.Say(`(ENDORSEMENT_POLICY_FAILURE)`))
By("reverifying the channel was not affected by the unauthorized endorsement")
sess, err = network.PeerUserSession(org2Peer0, "User1", commands.ChaincodeQuery{
ChannelID: "testchannel",
Name: "mycc",
Ctor: `{"Args":["query","a"]}`,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say("90"))
// Testing scenario two: chaincode endorsement policy not satisfied due to peer's signer cert does not
// satisfy endorsement policy.
By("replacing org1peer0's identity with a client identity")
// Org1 peer0 is used to test chaincode endorsement policy not satisfied due to peer's signer
// cert does not satisfy endorsement policy.
org1Peer0MSPDir := network.PeerLocalMSPDir(org1Peer0)
org1User1MSPDir := network.PeerUserMSPDir(org1Peer0, "User1")
_, err = copyFile(filepath.Join(org1User1MSPDir, "signcerts", "User1@org1.example.com-cert.pem"), filepath.Join(org1Peer0MSPDir, "signcerts", "peer0.org1.example.com-cert.pem"))
Expect(err).NotTo(HaveOccurred())
_, err = copyFile(filepath.Join(org1User1MSPDir, "keystore", "priv_sk"), filepath.Join(org1Peer0MSPDir, "keystore", "priv_sk"))
Expect(err).NotTo(HaveOccurred())
By("restarting all fabric processes to reload MSP identities")
ordererRunner, ordererProcess, peerProcess = nwo.RestartSingleOrdererNetwork(ordererProcess, peerProcess, network)
By("attempting to invoke chaincode on a peer that does not have a valid endorser identity (endorsing peer has client identity)")
sess, err = network.PeerUserSession(org1Peer0, "User1", commands.ChaincodeInvoke{
ChannelID: "testchannel",
Orderer: network.OrdererAddress(orderer, nwo.ListenPort),
Name: "mycc",
Ctor: `{"Args":["invoke","a","b","10"]}`,
PeerAddresses: []string{
network.PeerAddress(network.Peer("Org1", "peer0"), nwo.ListenPort),
},
WaitForEvent: true,
ClientAuth: network.ClientAuthRequired,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
Expect(sess.Err).To(gbytes.Say(`(ENDORSEMENT_POLICY_FAILURE)`))
By("reverifying the channel was not affected by the unauthorized endorsement")
sess, err = network.PeerUserSession(org1Peer0, "User1", commands.ChaincodeQuery{
ChannelID: "testchannel",
Name: "mycc",
Ctor: `{"Args":["query","a"]}`,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say("90"))
Expect("To fail")
})
})
func RunQueryInvokeQuery(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, initialQueryResult int) {
sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
ChannelID: "testchannel",
Name: "mycc",
Ctor: `{"Args":["query","a"]}`,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say(fmt.Sprint(initialQueryResult)))
sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
ChannelID: "testchannel",
Orderer: n.OrdererAddress(orderer, nwo.ListenPort),
Name: "mycc",
Ctor: `{"Args":["invoke","a","b","10"]}`,
PeerAddresses: []string{
n.PeerAddress(n.Peer("Org1", "peer0"), nwo.ListenPort),
n.PeerAddress(n.Peer("Org2", "peer0"), nwo.ListenPort),
},
WaitForEvent: true,
ClientAuth: n.ClientAuthRequired,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200"))
sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
ChannelID: "testchannel",
Name: "mycc",
Ctor: `{"Args":["query","a"]}`,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say(fmt.Sprint(initialQueryResult - 10)))
}
func copyFile(src, dst string) (int64, error) {
source, err := os.Open(src)
if err != nil {
return 0, err
}
defer source.Close()
err = os.Remove(dst)
if err != nil {
return 0, err
}
destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer destination.Close()
nBytes, err := io.Copy(destination, source)
return nBytes, err
}