github.com/defanghe/fabric@v2.1.1+incompatible/core/common/validation/msgvalidation_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package validation 8 9 import ( 10 "fmt" 11 "strconv" 12 "testing" 13 14 "github.com/golang/protobuf/proto" 15 "github.com/hyperledger/fabric-protos-go/common" 16 "github.com/hyperledger/fabric-protos-go/peer" 17 "github.com/hyperledger/fabric/bccsp/sw" 18 "github.com/hyperledger/fabric/msp" 19 "github.com/hyperledger/fabric/protoutil" 20 "github.com/stretchr/testify/assert" 21 ) 22 23 func createTestTransactionEnvelope(channel string, response *peer.Response, simRes []byte) (*common.Envelope, error) { 24 prop, err := createTestProposalAndSignedProposal(channel) 25 if err != nil { 26 return nil, fmt.Errorf("failed to create test proposal and signed proposal, err %s", err) 27 } 28 29 // endorse it to get a proposal response 30 presp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, response, simRes, nil, getChaincodeID(), signer) 31 if err != nil { 32 return nil, fmt.Errorf("CreateProposalResponse failed, err %s", err) 33 } 34 35 // assemble a transaction from that proposal and endorsement 36 tx, err := protoutil.CreateSignedTx(prop, signer, presp) 37 if err != nil { 38 return nil, fmt.Errorf("CreateSignedTx failed, err %s", err) 39 } 40 41 return tx, nil 42 } 43 44 func createTestProposalAndSignedProposal(channel string) (*peer.Proposal, error) { 45 // get a toy proposal 46 prop, err := getProposal(channel) 47 if err != nil { 48 return nil, fmt.Errorf("getProposal failed, err %s", err) 49 } 50 51 return prop, nil 52 } 53 54 func protoMarshal(t *testing.T, m proto.Message) []byte { 55 bytes, err := proto.Marshal(m) 56 assert.NoError(t, err) 57 return bytes 58 } 59 60 // createTestHeader creates a header for a given transaction type, channel id, and creator 61 // Based on useGoodTxid, the returned header will have either a good or bad txid for testing purpose 62 func createTestHeader(t *testing.T, txType common.HeaderType, channelId string, creator []byte, useGoodTxid bool) (*common.Header, error) { 63 nonce := []byte("nonce-abc-12345") 64 65 // useGoodTxid is used to for testing purpose. When it is true, we use a bad value for txid 66 txid := "bad" 67 if useGoodTxid { 68 txid = protoutil.ComputeTxID(nonce, creator) 69 } 70 71 chdr := &common.ChannelHeader{ 72 Type: int32(txType), 73 ChannelId: channelId, 74 TxId: txid, 75 Epoch: uint64(0), 76 } 77 78 shdr := &common.SignatureHeader{ 79 Creator: creator, 80 Nonce: nonce, 81 } 82 83 return &common.Header{ 84 ChannelHeader: protoMarshal(t, chdr), 85 SignatureHeader: protoMarshal(t, shdr), 86 }, nil 87 } 88 89 func createTestEnvelope(t *testing.T, data []byte, header *common.Header, signer msp.SigningIdentity) (*common.Envelope, error) { 90 payload := &common.Payload{ 91 Header: header, 92 Data: data, 93 } 94 payloadBytes := protoMarshal(t, payload) 95 96 signature, err := signer.Sign(payloadBytes) 97 assert.NoError(t, err) 98 99 return &common.Envelope{ 100 Payload: payloadBytes, 101 Signature: signature, 102 }, nil 103 } 104 105 func TestCheckSignatureFromCreator(t *testing.T) { 106 response := &peer.Response{Status: 200} 107 simRes := []byte("simulation_result") 108 109 env, err := createTestTransactionEnvelope("testchannelid", response, simRes) 110 assert.Nil(t, err, "failed to create test transaction: %s", err) 111 assert.NotNil(t, env) 112 113 // get the payload from the envelope 114 payload, err := protoutil.UnmarshalPayload(env.Payload) 115 assert.NoError(t, err, "GetPayload returns err %s", err) 116 117 // validate the header 118 chdr, shdr, err := validateCommonHeader(payload.Header) 119 assert.NoError(t, err, "validateCommonHeader returns err %s", err) 120 121 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 122 assert.NoError(t, err) 123 124 // validate the signature in the envelope 125 err = checkSignatureFromCreator(shdr.Creator, env.Signature, env.Payload, chdr.ChannelId, cryptoProvider) 126 assert.NoError(t, err, "checkSignatureFromCreator returns err %s", err) 127 128 // corrupt the creator 129 err = checkSignatureFromCreator([]byte("junk"), env.Signature, env.Payload, chdr.ChannelId, cryptoProvider) 130 assert.Error(t, err) 131 assert.Contains(t, err.Error(), "MSP error: could not deserialize") 132 133 // check nonexistent channel 134 err = checkSignatureFromCreator(shdr.Creator, env.Signature, env.Payload, "junkchannel", cryptoProvider) 135 assert.Error(t, err) 136 assert.Contains(t, err.Error(), "MSP error: channel doesn't exist") 137 } 138 139 func ToHex(q uint64) string { 140 return "0x" + strconv.FormatUint(q, 16) 141 }