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