github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/peer/gossip/mcs_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package gossip
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"github.com/golang/protobuf/proto"
    24  	"github.com/hyperledger/fabric/bccsp"
    25  	"github.com/hyperledger/fabric/bccsp/factory"
    26  	"github.com/hyperledger/fabric/common/crypto"
    27  	"github.com/hyperledger/fabric/common/localmsp"
    28  	mockscrypto "github.com/hyperledger/fabric/common/mocks/crypto"
    29  	"github.com/hyperledger/fabric/common/policies"
    30  	"github.com/hyperledger/fabric/common/util"
    31  	"github.com/hyperledger/fabric/gossip/api"
    32  	"github.com/hyperledger/fabric/msp"
    33  	"github.com/hyperledger/fabric/msp/mgmt"
    34  	"github.com/hyperledger/fabric/peer/gossip/mocks"
    35  	"github.com/hyperledger/fabric/protos/common"
    36  	protospeer "github.com/hyperledger/fabric/protos/peer"
    37  	"github.com/hyperledger/fabric/protos/utils"
    38  	"github.com/stretchr/testify/assert"
    39  )
    40  
    41  func TestPKIidOfCert(t *testing.T) {
    42  	deserializersManager := &mocks.DeserializersManager{
    43  		LocalDeserializer: &mocks.IdentityDeserializer{[]byte("Alice"), []byte("msg1")},
    44  	}
    45  	msgCryptoService := NewMCS(&mocks.ChannelPolicyManagerGetterWithManager{},
    46  		&mockscrypto.LocalSigner{Identity: []byte("Alice")},
    47  		deserializersManager,
    48  	)
    49  
    50  	peerIdentity := []byte("Alice")
    51  	pkid := msgCryptoService.GetPKIidOfCert(peerIdentity)
    52  
    53  	// Check pkid is not nil
    54  	assert.NotNil(t, pkid, "PKID must be different from nil")
    55  	// Check that pkid is correctly computed
    56  	id, err := deserializersManager.Deserialize(peerIdentity)
    57  	assert.NoError(t, err, "Failed getting validated identity from [% x]", []byte(peerIdentity))
    58  	idRaw := append([]byte(id.Mspid), id.IdBytes...)
    59  	assert.NoError(t, err, "Failed marshalling identity identifier [% x]: [%s]", peerIdentity, err)
    60  	digest, err := factory.GetDefault().Hash(idRaw, &bccsp.SHA256Opts{})
    61  	assert.NoError(t, err, "Failed computing digest of serialized identity [% x]", []byte(peerIdentity))
    62  	assert.Equal(t, digest, []byte(pkid), "PKID must be the SHA2-256 of peerIdentity")
    63  
    64  	//  The PKI-ID is calculated by concatenating the MspId with IdBytes. Ensure that additional fields haven't been introduced in the code
    65  	v := reflect.Indirect(reflect.ValueOf(id))
    66  	assert.Equal(t, 2, v.NumField())
    67  }
    68  
    69  func TestPKIidOfNil(t *testing.T) {
    70  	msgCryptoService := NewMCS(&mocks.ChannelPolicyManagerGetter{}, localmsp.NewSigner(), mgmt.NewDeserializersManager())
    71  
    72  	pkid := msgCryptoService.GetPKIidOfCert(nil)
    73  	// Check pkid is not nil
    74  	assert.Nil(t, pkid, "PKID must be nil")
    75  }
    76  
    77  func TestValidateIdentity(t *testing.T) {
    78  	deserializersManager := &mocks.DeserializersManager{
    79  		LocalDeserializer: &mocks.IdentityDeserializer{[]byte("Alice"), []byte("msg1")},
    80  		ChannelDeserializers: map[string]msp.IdentityDeserializer{
    81  			"A": &mocks.IdentityDeserializer{[]byte("Bob"), []byte("msg2")},
    82  		},
    83  	}
    84  	msgCryptoService := NewMCS(
    85  		&mocks.ChannelPolicyManagerGetterWithManager{},
    86  		&mockscrypto.LocalSigner{Identity: []byte("Charlie")},
    87  		deserializersManager,
    88  	)
    89  
    90  	err := msgCryptoService.ValidateIdentity([]byte("Alice"))
    91  	assert.NoError(t, err)
    92  
    93  	err = msgCryptoService.ValidateIdentity([]byte("Bob"))
    94  	assert.NoError(t, err)
    95  
    96  	err = msgCryptoService.ValidateIdentity([]byte("Charlie"))
    97  	assert.Error(t, err)
    98  
    99  	err = msgCryptoService.ValidateIdentity(nil)
   100  	assert.Error(t, err)
   101  }
   102  
   103  func TestSign(t *testing.T) {
   104  	msgCryptoService := NewMCS(
   105  		&mocks.ChannelPolicyManagerGetter{},
   106  		&mockscrypto.LocalSigner{Identity: []byte("Alice")},
   107  		mgmt.NewDeserializersManager(),
   108  	)
   109  
   110  	msg := []byte("Hello World!!!")
   111  	sigma, err := msgCryptoService.Sign(msg)
   112  	assert.NoError(t, err, "Failed generating signature")
   113  	assert.NotNil(t, sigma, "Signature must be different from nil")
   114  }
   115  
   116  func TestVerify(t *testing.T) {
   117  	msgCryptoService := NewMCS(
   118  		&mocks.ChannelPolicyManagerGetterWithManager{
   119  			map[string]policies.Manager{
   120  				"A": &mocks.ChannelPolicyManager{&mocks.Policy{&mocks.IdentityDeserializer{[]byte("Bob"), []byte("msg2")}}},
   121  				"B": &mocks.ChannelPolicyManager{&mocks.Policy{&mocks.IdentityDeserializer{[]byte("Charlie"), []byte("msg3")}}},
   122  				"C": nil,
   123  			},
   124  		},
   125  		&mockscrypto.LocalSigner{Identity: []byte("Alice")},
   126  		&mocks.DeserializersManager{
   127  			LocalDeserializer: &mocks.IdentityDeserializer{[]byte("Alice"), []byte("msg1")},
   128  			ChannelDeserializers: map[string]msp.IdentityDeserializer{
   129  				"A": &mocks.IdentityDeserializer{[]byte("Bob"), []byte("msg2")},
   130  				"B": &mocks.IdentityDeserializer{[]byte("Charlie"), []byte("msg3")},
   131  				"C": &mocks.IdentityDeserializer{[]byte("Dave"), []byte("msg4")},
   132  			},
   133  		},
   134  	)
   135  
   136  	msg := []byte("msg1")
   137  	sigma, err := msgCryptoService.Sign(msg)
   138  	assert.NoError(t, err, "Failed generating signature")
   139  
   140  	err = msgCryptoService.Verify(api.PeerIdentityType("Alice"), sigma, msg)
   141  	assert.NoError(t, err, "Alice should verify the signature")
   142  
   143  	err = msgCryptoService.Verify(api.PeerIdentityType("Bob"), sigma, msg)
   144  	assert.Error(t, err, "Bob should not verify the signature")
   145  
   146  	err = msgCryptoService.Verify(api.PeerIdentityType("Charlie"), sigma, msg)
   147  	assert.Error(t, err, "Charlie should not verify the signature")
   148  
   149  	sigma, err = msgCryptoService.Sign(msg)
   150  	assert.NoError(t, err)
   151  	err = msgCryptoService.Verify(api.PeerIdentityType("Dave"), sigma, msg)
   152  	assert.Error(t, err)
   153  	assert.Contains(t, err.Error(), "Could not acquire policy manager")
   154  
   155  	// Check invalid args
   156  	assert.Error(t, msgCryptoService.Verify(nil, sigma, msg))
   157  }
   158  
   159  func TestVerifyBlock(t *testing.T) {
   160  	aliceSigner := &mockscrypto.LocalSigner{Identity: []byte("Alice")}
   161  	policyManagerGetter := &mocks.ChannelPolicyManagerGetterWithManager{
   162  		map[string]policies.Manager{
   163  			"A": &mocks.ChannelPolicyManager{&mocks.Policy{&mocks.IdentityDeserializer{[]byte("Bob"), []byte("msg2")}}},
   164  			"B": &mocks.ChannelPolicyManager{&mocks.Policy{&mocks.IdentityDeserializer{[]byte("Charlie"), []byte("msg3")}}},
   165  			"C": &mocks.ChannelPolicyManager{&mocks.Policy{&mocks.IdentityDeserializer{[]byte("Alice"), []byte("msg1")}}},
   166  			"D": &mocks.ChannelPolicyManager{&mocks.Policy{&mocks.IdentityDeserializer{[]byte("Alice"), []byte("msg1")}}},
   167  		},
   168  	}
   169  
   170  	msgCryptoService := NewMCS(
   171  		policyManagerGetter,
   172  		aliceSigner,
   173  		&mocks.DeserializersManager{
   174  			LocalDeserializer: &mocks.IdentityDeserializer{[]byte("Alice"), []byte("msg1")},
   175  			ChannelDeserializers: map[string]msp.IdentityDeserializer{
   176  				"A": &mocks.IdentityDeserializer{[]byte("Bob"), []byte("msg2")},
   177  				"B": &mocks.IdentityDeserializer{[]byte("Charlie"), []byte("msg3")},
   178  			},
   179  		},
   180  	)
   181  
   182  	// - Prepare testing valid block, Alice signs it.
   183  	blockRaw, msg := mockBlock(t, "C", 42, aliceSigner, nil)
   184  	policyManagerGetter.Managers["C"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg
   185  	blockRaw2, msg2 := mockBlock(t, "D", 42, aliceSigner, nil)
   186  	policyManagerGetter.Managers["D"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg2
   187  
   188  	// - Verify block
   189  	assert.NoError(t, msgCryptoService.VerifyBlock([]byte("C"), 42, blockRaw))
   190  	// Wrong sequence number claimed
   191  	err := msgCryptoService.VerifyBlock([]byte("C"), 43, blockRaw)
   192  	assert.Error(t, err)
   193  	assert.Contains(t, err.Error(), "but actual seqNum inside block is")
   194  	delete(policyManagerGetter.Managers, "D")
   195  	nilPolMgrErr := msgCryptoService.VerifyBlock([]byte("D"), 42, blockRaw2)
   196  	assert.Contains(t, nilPolMgrErr.Error(), "Could not acquire policy manager")
   197  	assert.Error(t, nilPolMgrErr)
   198  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("A"), 42, blockRaw))
   199  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("B"), 42, blockRaw))
   200  
   201  	// - Prepare testing invalid block (wrong data has), Alice signs it.
   202  	blockRaw, msg = mockBlock(t, "C", 42, aliceSigner, []byte{0})
   203  	policyManagerGetter.Managers["C"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg
   204  
   205  	// - Verify block
   206  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("C"), 42, blockRaw))
   207  
   208  	// Check invalid args
   209  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("C"), 42, []byte{0, 1, 2, 3, 4}))
   210  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("C"), 42, nil))
   211  }
   212  
   213  func mockBlock(t *testing.T, channel string, seqNum uint64, localSigner crypto.LocalSigner, dataHash []byte) ([]byte, []byte) {
   214  	block := common.NewBlock(seqNum, nil)
   215  
   216  	// Add a fake transaction to the block referring channel "C"
   217  	sProp, _ := utils.MockSignedEndorserProposalOrPanic(channel, &protospeer.ChaincodeSpec{}, []byte("transactor"), []byte("transactor's signature"))
   218  	sPropRaw, err := utils.Marshal(sProp)
   219  	assert.NoError(t, err, "Failed marshalling signed proposal")
   220  	block.Data.Data = [][]byte{sPropRaw}
   221  
   222  	// Compute hash of block.Data and put into the Header
   223  	if len(dataHash) != 0 {
   224  		block.Header.DataHash = dataHash
   225  	} else {
   226  		block.Header.DataHash = block.Data.Hash()
   227  	}
   228  
   229  	// Add signer's signature to the block
   230  	shdr, err := localSigner.NewSignatureHeader()
   231  	assert.NoError(t, err, "Failed generating signature header")
   232  
   233  	blockSignature := &common.MetadataSignature{
   234  		SignatureHeader: utils.MarshalOrPanic(shdr),
   235  	}
   236  
   237  	// Note, this value is intentionally nil, as this metadata is only about the signature, there is no additional metadata
   238  	// information required beyond the fact that the metadata item is signed.
   239  	blockSignatureValue := []byte(nil)
   240  
   241  	msg := util.ConcatenateBytes(blockSignatureValue, blockSignature.SignatureHeader, block.Header.Bytes())
   242  	blockSignature.Signature, err = localSigner.Sign(msg)
   243  	assert.NoError(t, err, "Failed signing block")
   244  
   245  	block.Metadata.Metadata[common.BlockMetadataIndex_SIGNATURES] = utils.MarshalOrPanic(&common.Metadata{
   246  		Value: blockSignatureValue,
   247  		Signatures: []*common.MetadataSignature{
   248  			blockSignature,
   249  		},
   250  	})
   251  
   252  	blockRaw, err := proto.Marshal(block)
   253  	assert.NoError(t, err, "Failed marshalling block")
   254  
   255  	return blockRaw, msg
   256  }