github.com/defanghe/fabric@v2.1.1+incompatible/internal/peer/gossip/mcs_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package gossip
     8  
     9  import (
    10  	"crypto/sha256"
    11  	"errors"
    12  	"reflect"
    13  	"strings"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/golang/protobuf/proto"
    18  	"github.com/hyperledger/fabric-protos-go/common"
    19  	pmsp "github.com/hyperledger/fabric-protos-go/msp"
    20  	protospeer "github.com/hyperledger/fabric-protos-go/peer"
    21  	"github.com/hyperledger/fabric/bccsp/sw"
    22  	"github.com/hyperledger/fabric/common/policies"
    23  	"github.com/hyperledger/fabric/common/util"
    24  	"github.com/hyperledger/fabric/gossip/api"
    25  	"github.com/hyperledger/fabric/internal/peer/gossip/mocks"
    26  	"github.com/hyperledger/fabric/internal/pkg/identity"
    27  	"github.com/hyperledger/fabric/msp"
    28  	"github.com/hyperledger/fabric/msp/mgmt"
    29  	"github.com/hyperledger/fabric/protoutil"
    30  	"github.com/stretchr/testify/assert"
    31  	"github.com/stretchr/testify/mock"
    32  )
    33  
    34  //go:generate counterfeiter -o mocks/policy_manager.go -fake-name PolicyManager . policyManager
    35  
    36  type policyManager interface {
    37  	policies.Manager
    38  }
    39  
    40  //go:generate counterfeiter -o mocks/signer_serializer.go --fake-name SignerSerializer . signerSerializer
    41  
    42  type signerSerializer interface {
    43  	identity.SignerSerializer
    44  }
    45  
    46  func TestPKIidOfCert(t *testing.T) {
    47  	deserializersManager := &mocks.DeserializersManager{
    48  		LocalDeserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}},
    49  	}
    50  	signer := &mocks.SignerSerializer{}
    51  	signer.SerializeReturns([]byte("Alice"), nil)
    52  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    53  	assert.NoError(t, err)
    54  	msgCryptoService := NewMCS(
    55  		&mocks.ChannelPolicyManagerGetterWithManager{},
    56  		signer,
    57  		deserializersManager,
    58  		cryptoProvider,
    59  	)
    60  
    61  	peerIdentity := []byte("Alice")
    62  	pkid := msgCryptoService.GetPKIidOfCert(peerIdentity)
    63  
    64  	// Check pkid is not nil
    65  	assert.NotNil(t, pkid, "PKID must be different from nil")
    66  	// Check that pkid is correctly computed
    67  	id, err := deserializersManager.Deserialize(peerIdentity)
    68  	assert.NoError(t, err, "Failed getting validated identity from [% x]", []byte(peerIdentity))
    69  	idRaw := append([]byte(id.Mspid), id.IdBytes...)
    70  	assert.NoError(t, err, "Failed marshalling identity identifier [% x]: [%s]", peerIdentity, err)
    71  	h := sha256.New()
    72  	h.Write(idRaw)
    73  	digest := h.Sum(nil)
    74  	assert.Equal(t, digest, []byte(pkid), "PKID must be the SHA2-256 of peerIdentity")
    75  
    76  	//  The PKI-ID is calculated by concatenating the MspId with IdBytes.
    77  	// Ensure that additional fields haven't been introduced in the code
    78  	v := reflect.Indirect(reflect.ValueOf(id)).Type()
    79  	fieldsThatStartWithXXX := 0
    80  	for i := 0; i < v.NumField(); i++ {
    81  		if strings.Index(v.Field(i).Name, "XXX_") == 0 {
    82  			fieldsThatStartWithXXX++
    83  		}
    84  	}
    85  	assert.Equal(t, 2+fieldsThatStartWithXXX, v.NumField())
    86  }
    87  
    88  func TestPKIidOfNil(t *testing.T) {
    89  	signer := &mocks.SignerSerializer{}
    90  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    91  	assert.NoError(t, err)
    92  	msgCryptoService := NewMCS(&mocks.ChannelPolicyManagerGetter{}, signer, mgmt.NewDeserializersManager(cryptoProvider), cryptoProvider)
    93  
    94  	pkid := msgCryptoService.GetPKIidOfCert(nil)
    95  	// Check pkid is not nil
    96  	assert.Nil(t, pkid, "PKID must be nil")
    97  }
    98  
    99  func TestValidateIdentity(t *testing.T) {
   100  	deserializersManager := &mocks.DeserializersManager{
   101  		LocalDeserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}},
   102  		ChannelDeserializers: map[string]msp.IdentityDeserializer{
   103  			"A": &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}},
   104  		},
   105  	}
   106  	signer := &mocks.SignerSerializer{}
   107  	signer.SerializeReturns([]byte("Charlie"), nil)
   108  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   109  	assert.NoError(t, err)
   110  	msgCryptoService := NewMCS(
   111  		&mocks.ChannelPolicyManagerGetterWithManager{},
   112  		signer,
   113  		deserializersManager,
   114  		cryptoProvider,
   115  	)
   116  
   117  	err = msgCryptoService.ValidateIdentity([]byte("Alice"))
   118  	assert.NoError(t, err)
   119  
   120  	err = msgCryptoService.ValidateIdentity([]byte("Bob"))
   121  	assert.NoError(t, err)
   122  
   123  	err = msgCryptoService.ValidateIdentity([]byte("Charlie"))
   124  	assert.Error(t, err)
   125  
   126  	err = msgCryptoService.ValidateIdentity(nil)
   127  	assert.Error(t, err)
   128  
   129  	// Now, pretend the identities are not well formed
   130  	deserializersManager.ChannelDeserializers["A"].(*mocks.IdentityDeserializer).On("IsWellFormed", mock.Anything).Return(errors.New("invalid form"))
   131  	err = msgCryptoService.ValidateIdentity([]byte("Bob"))
   132  	assert.Error(t, err)
   133  	assert.Equal(t, "identity is not well formed: invalid form", err.Error())
   134  
   135  	deserializersManager.LocalDeserializer.(*mocks.IdentityDeserializer).On("IsWellFormed", mock.Anything).Return(errors.New("invalid form"))
   136  	err = msgCryptoService.ValidateIdentity([]byte("Alice"))
   137  	assert.Error(t, err)
   138  	assert.Equal(t, "identity is not well formed: invalid form", err.Error())
   139  }
   140  
   141  func TestSign(t *testing.T) {
   142  	signer := &mocks.SignerSerializer{}
   143  	signer.SignReturns([]byte("signature"), nil)
   144  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   145  	assert.NoError(t, err)
   146  
   147  	msgCryptoService := NewMCS(
   148  		&mocks.ChannelPolicyManagerGetter{},
   149  		signer,
   150  		mgmt.NewDeserializersManager(cryptoProvider),
   151  		cryptoProvider,
   152  	)
   153  
   154  	msg := []byte("Hello World!!!")
   155  	sigma, err := msgCryptoService.Sign(msg)
   156  	assert.NoError(t, err, "Failed generating signature")
   157  	assert.NotNil(t, sigma, "Signature must be different from nil")
   158  }
   159  
   160  func TestVerify(t *testing.T) {
   161  	signer := &mocks.SignerSerializer{}
   162  	signer.SerializeReturns([]byte("Alice"), nil)
   163  	signer.SignReturns([]byte("msg1"), nil)
   164  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   165  	assert.NoError(t, err)
   166  	msgCryptoService := NewMCS(
   167  		&mocks.ChannelPolicyManagerGetterWithManager{
   168  			Managers: map[string]policies.Manager{
   169  				"A": &mocks.ChannelPolicyManager{
   170  					Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}}},
   171  				},
   172  				"B": &mocks.ChannelPolicyManager{
   173  					Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Charlie"), Msg: []byte("msg3"), Mock: mock.Mock{}}},
   174  				},
   175  				"C": nil,
   176  			},
   177  		},
   178  		signer,
   179  		&mocks.DeserializersManager{
   180  			LocalDeserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}},
   181  			ChannelDeserializers: map[string]msp.IdentityDeserializer{
   182  				"A": &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}},
   183  				"B": &mocks.IdentityDeserializer{Identity: []byte("Charlie"), Msg: []byte("msg3"), Mock: mock.Mock{}},
   184  				"C": &mocks.IdentityDeserializer{Identity: []byte("Dave"), Msg: []byte("msg4"), Mock: mock.Mock{}},
   185  			},
   186  		},
   187  		cryptoProvider,
   188  	)
   189  
   190  	msg := []byte("msg1")
   191  	sigma, err := msgCryptoService.Sign(msg)
   192  	assert.NoError(t, err, "Failed generating signature")
   193  
   194  	err = msgCryptoService.Verify(api.PeerIdentityType("Alice"), sigma, msg)
   195  	assert.NoError(t, err, "Alice should verify the signature")
   196  
   197  	err = msgCryptoService.Verify(api.PeerIdentityType("Bob"), sigma, msg)
   198  	assert.Error(t, err, "Bob should not verify the signature")
   199  
   200  	err = msgCryptoService.Verify(api.PeerIdentityType("Charlie"), sigma, msg)
   201  	assert.Error(t, err, "Charlie should not verify the signature")
   202  
   203  	sigma, err = msgCryptoService.Sign(msg)
   204  	assert.NoError(t, err)
   205  	err = msgCryptoService.Verify(api.PeerIdentityType("Dave"), sigma, msg)
   206  	assert.Error(t, err)
   207  	assert.Contains(t, err.Error(), "Could not acquire policy manager")
   208  
   209  	// Check invalid args
   210  	assert.Error(t, msgCryptoService.Verify(nil, sigma, msg))
   211  }
   212  
   213  func TestVerifyBlock(t *testing.T) {
   214  	aliceSigner := &mocks.SignerSerializer{}
   215  	aliceSigner.SerializeReturns([]byte("Alice"), nil)
   216  	policyManagerGetter := &mocks.ChannelPolicyManagerGetterWithManager{
   217  		Managers: map[string]policies.Manager{
   218  			"A": &mocks.ChannelPolicyManager{
   219  				Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}}},
   220  			},
   221  			"B": &mocks.ChannelPolicyManager{
   222  				Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Charlie"), Msg: []byte("msg3"), Mock: mock.Mock{}}},
   223  			},
   224  			"C": &mocks.ChannelPolicyManager{
   225  				Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}}},
   226  			},
   227  			"D": &mocks.ChannelPolicyManager{
   228  				Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}}},
   229  			},
   230  		},
   231  	}
   232  
   233  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   234  	assert.NoError(t, err)
   235  	msgCryptoService := NewMCS(
   236  		policyManagerGetter,
   237  		aliceSigner,
   238  		&mocks.DeserializersManager{
   239  			LocalDeserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}},
   240  			ChannelDeserializers: map[string]msp.IdentityDeserializer{
   241  				"A": &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}},
   242  				"B": &mocks.IdentityDeserializer{Identity: []byte("Charlie"), Msg: []byte("msg3"), Mock: mock.Mock{}},
   243  			},
   244  		},
   245  		cryptoProvider,
   246  	)
   247  
   248  	// - Prepare testing valid block, Alice signs it.
   249  	blockRaw, msg := mockBlock(t, "C", 42, aliceSigner, nil)
   250  	policyManagerGetter.Managers["C"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg
   251  	blockRaw2, msg2 := mockBlock(t, "D", 42, aliceSigner, nil)
   252  	policyManagerGetter.Managers["D"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg2
   253  
   254  	// - Verify block
   255  	assert.NoError(t, msgCryptoService.VerifyBlock([]byte("C"), 42, blockRaw))
   256  	// Wrong sequence number claimed
   257  	err = msgCryptoService.VerifyBlock([]byte("C"), 43, blockRaw)
   258  	assert.Error(t, err)
   259  	assert.Contains(t, err.Error(), "but actual seqNum inside block is")
   260  	delete(policyManagerGetter.Managers, "D")
   261  	nilPolMgrErr := msgCryptoService.VerifyBlock([]byte("D"), 42, blockRaw2)
   262  	assert.Contains(t, nilPolMgrErr.Error(), "Could not acquire policy manager")
   263  	assert.Error(t, nilPolMgrErr)
   264  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("A"), 42, blockRaw))
   265  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("B"), 42, blockRaw))
   266  
   267  	// - Prepare testing invalid block (wrong data has), Alice signs it.
   268  	blockRaw, msg = mockBlock(t, "C", 42, aliceSigner, []byte{0})
   269  	policyManagerGetter.Managers["C"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg
   270  
   271  	// - Verify block
   272  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("C"), 42, blockRaw))
   273  
   274  	// Check invalid args
   275  	assert.Error(t, msgCryptoService.VerifyBlock([]byte("C"), 42, &common.Block{}))
   276  }
   277  
   278  func mockBlock(t *testing.T, channel string, seqNum uint64, localSigner *mocks.SignerSerializer, dataHash []byte) (*common.Block, []byte) {
   279  	block := protoutil.NewBlock(seqNum, nil)
   280  
   281  	// Add a fake transaction to the block referring channel "C"
   282  	sProp, _ := protoutil.MockSignedEndorserProposalOrPanic(channel, &protospeer.ChaincodeSpec{}, []byte("transactor"), []byte("transactor's signature"))
   283  	sPropRaw, err := protoutil.Marshal(sProp)
   284  	assert.NoError(t, err, "Failed marshalling signed proposal")
   285  	block.Data.Data = [][]byte{sPropRaw}
   286  
   287  	// Compute hash of block.Data and put into the Header
   288  	if len(dataHash) != 0 {
   289  		block.Header.DataHash = dataHash
   290  	} else {
   291  		block.Header.DataHash = protoutil.BlockDataHash(block.Data)
   292  	}
   293  
   294  	// Add signer's signature to the block
   295  	shdr, err := protoutil.NewSignatureHeader(localSigner)
   296  	assert.NoError(t, err, "Failed generating signature header")
   297  
   298  	blockSignature := &common.MetadataSignature{
   299  		SignatureHeader: protoutil.MarshalOrPanic(shdr),
   300  	}
   301  
   302  	// Note, this value is intentionally nil, as this metadata is only about the signature, there is no additional metadata
   303  	// information required beyond the fact that the metadata item is signed.
   304  	blockSignatureValue := []byte(nil)
   305  
   306  	msg := util.ConcatenateBytes(blockSignatureValue, blockSignature.SignatureHeader, protoutil.BlockHeaderBytes(block.Header))
   307  	localSigner.SignReturns(msg, nil)
   308  	blockSignature.Signature, err = localSigner.Sign(msg)
   309  	assert.NoError(t, err, "Failed signing block")
   310  
   311  	block.Metadata.Metadata[common.BlockMetadataIndex_SIGNATURES] = protoutil.MarshalOrPanic(&common.Metadata{
   312  		Value: blockSignatureValue,
   313  		Signatures: []*common.MetadataSignature{
   314  			blockSignature,
   315  		},
   316  	})
   317  
   318  	return block, msg
   319  }
   320  
   321  func TestExpiration(t *testing.T) {
   322  	expirationDate := time.Now().Add(time.Minute)
   323  	id1 := &pmsp.SerializedIdentity{
   324  		Mspid:   "X509BasedMSP",
   325  		IdBytes: []byte("X509BasedIdentity"),
   326  	}
   327  
   328  	x509IdentityBytes, _ := proto.Marshal(id1)
   329  
   330  	id2 := &pmsp.SerializedIdentity{
   331  		Mspid:   "nonX509BasedMSP",
   332  		IdBytes: []byte("nonX509RawIdentity"),
   333  	}
   334  
   335  	nonX509IdentityBytes, _ := proto.Marshal(id2)
   336  
   337  	deserializersManager := &mocks.DeserializersManager{
   338  		LocalDeserializer: &mocks.IdentityDeserializer{
   339  			Identity: []byte{1, 2, 3},
   340  			Msg:      []byte{1, 2, 3},
   341  		},
   342  		ChannelDeserializers: map[string]msp.IdentityDeserializer{
   343  			"X509BasedMSP": &mocks.IdentityDeserializerWithExpiration{
   344  				Expiration: expirationDate,
   345  				IdentityDeserializer: &mocks.IdentityDeserializer{
   346  					Identity: x509IdentityBytes,
   347  					Msg:      []byte("x509IdentityBytes"),
   348  				},
   349  			},
   350  			"nonX509BasedMSP": &mocks.IdentityDeserializer{
   351  				Identity: nonX509IdentityBytes,
   352  				Msg:      []byte("nonX509IdentityBytes"),
   353  			},
   354  		},
   355  	}
   356  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   357  	assert.NoError(t, err)
   358  	msgCryptoService := NewMCS(
   359  		&mocks.ChannelPolicyManagerGetterWithManager{},
   360  		&mocks.SignerSerializer{},
   361  		deserializersManager,
   362  		cryptoProvider,
   363  	)
   364  
   365  	// Green path I check the expiration date is as expected
   366  	exp, err := msgCryptoService.Expiration(x509IdentityBytes)
   367  	assert.NoError(t, err)
   368  	assert.Equal(t, expirationDate.Second(), exp.Second())
   369  
   370  	// Green path II - a non-x509 identity has a zero expiration time
   371  	exp, err = msgCryptoService.Expiration(nonX509IdentityBytes)
   372  	assert.NoError(t, err)
   373  	assert.Zero(t, exp)
   374  
   375  	// Bad path I - corrupt the x509 identity and make sure error is returned
   376  	x509IdentityBytes = append(x509IdentityBytes, 0, 0, 0, 0, 0, 0)
   377  	exp, err = msgCryptoService.Expiration(x509IdentityBytes)
   378  	assert.Error(t, err)
   379  	assert.Contains(t, err.Error(), "No MSP found able to do that")
   380  	assert.Zero(t, exp)
   381  }