github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/peer/gossip/mcs_test.go (about) 1 /* 2 Copyright hechain. 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/hechain20/hechain/bccsp/sw" 19 "github.com/hechain20/hechain/common/policies" 20 "github.com/hechain20/hechain/common/util" 21 "github.com/hechain20/hechain/gossip/api" 22 "github.com/hechain20/hechain/internal/peer/gossip/mocks" 23 "github.com/hechain20/hechain/internal/pkg/identity" 24 "github.com/hechain20/hechain/msp" 25 "github.com/hechain20/hechain/msp/mgmt" 26 "github.com/hechain20/hechain/protoutil" 27 "github.com/hyperledger/fabric-protos-go/common" 28 pmsp "github.com/hyperledger/fabric-protos-go/msp" 29 protospeer "github.com/hyperledger/fabric-protos-go/peer" 30 "github.com/stretchr/testify/mock" 31 "github.com/stretchr/testify/require" 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 require.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 require.NotNil(t, pkid, "PKID must be different from nil") 66 // Check that pkid is correctly computed 67 id, err := deserializersManager.Deserialize(peerIdentity) 68 require.NoError(t, err, "Failed getting validated identity from [% x]", []byte(peerIdentity)) 69 idRaw := append([]byte(id.Mspid), id.IdBytes...) 70 require.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 require.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 require.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 require.NoError(t, err) 92 localMSP := mgmt.GetLocalMSP(cryptoProvider) 93 msgCryptoService := NewMCS( 94 &mocks.ChannelPolicyManagerGetter{}, 95 signer, 96 NewDeserializersManager(localMSP), 97 cryptoProvider, 98 ) 99 100 pkid := msgCryptoService.GetPKIidOfCert(nil) 101 // Check pkid is not nil 102 require.Nil(t, pkid, "PKID must be nil") 103 } 104 105 func TestValidateIdentity(t *testing.T) { 106 deserializersManager := &mocks.DeserializersManager{ 107 LocalDeserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}}, 108 ChannelDeserializers: map[string]msp.IdentityDeserializer{ 109 "A": &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}}, 110 }, 111 } 112 signer := &mocks.SignerSerializer{} 113 signer.SerializeReturns([]byte("Charlie"), nil) 114 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 115 require.NoError(t, err) 116 msgCryptoService := NewMCS( 117 &mocks.ChannelPolicyManagerGetterWithManager{}, 118 signer, 119 deserializersManager, 120 cryptoProvider, 121 ) 122 123 err = msgCryptoService.ValidateIdentity([]byte("Alice")) 124 require.NoError(t, err) 125 126 err = msgCryptoService.ValidateIdentity([]byte("Bob")) 127 require.NoError(t, err) 128 129 err = msgCryptoService.ValidateIdentity([]byte("Charlie")) 130 require.Error(t, err) 131 132 err = msgCryptoService.ValidateIdentity(nil) 133 require.Error(t, err) 134 135 // Now, pretend the identities are not well formed 136 deserializersManager.ChannelDeserializers["A"].(*mocks.IdentityDeserializer).On("IsWellFormed", mock.Anything).Return(errors.New("invalid form")) 137 err = msgCryptoService.ValidateIdentity([]byte("Bob")) 138 require.Error(t, err) 139 require.Equal(t, "identity is not well formed: invalid form", err.Error()) 140 141 deserializersManager.LocalDeserializer.(*mocks.IdentityDeserializer).On("IsWellFormed", mock.Anything).Return(errors.New("invalid form")) 142 err = msgCryptoService.ValidateIdentity([]byte("Alice")) 143 require.Error(t, err) 144 require.Equal(t, "identity is not well formed: invalid form", err.Error()) 145 } 146 147 func TestSign(t *testing.T) { 148 signer := &mocks.SignerSerializer{} 149 signer.SignReturns([]byte("signature"), nil) 150 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 151 require.NoError(t, err) 152 153 localMSP := mgmt.GetLocalMSP(cryptoProvider) 154 msgCryptoService := NewMCS( 155 &mocks.ChannelPolicyManagerGetter{}, 156 signer, 157 NewDeserializersManager(localMSP), 158 cryptoProvider, 159 ) 160 161 msg := []byte("Hello World!!!") 162 sigma, err := msgCryptoService.Sign(msg) 163 require.NoError(t, err, "Failed generating signature") 164 require.NotNil(t, sigma, "Signature must be different from nil") 165 } 166 167 func TestVerify(t *testing.T) { 168 signer := &mocks.SignerSerializer{} 169 signer.SerializeReturns([]byte("Alice"), nil) 170 signer.SignReturns([]byte("msg1"), nil) 171 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 172 require.NoError(t, err) 173 msgCryptoService := NewMCS( 174 &mocks.ChannelPolicyManagerGetterWithManager{ 175 Managers: map[string]policies.Manager{ 176 "A": &mocks.ChannelPolicyManager{ 177 Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}}}, 178 }, 179 "B": &mocks.ChannelPolicyManager{ 180 Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Charlie"), Msg: []byte("msg3"), Mock: mock.Mock{}}}, 181 }, 182 "C": nil, 183 }, 184 }, 185 signer, 186 &mocks.DeserializersManager{ 187 LocalDeserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}}, 188 ChannelDeserializers: map[string]msp.IdentityDeserializer{ 189 "A": &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}}, 190 "B": &mocks.IdentityDeserializer{Identity: []byte("Charlie"), Msg: []byte("msg3"), Mock: mock.Mock{}}, 191 "C": &mocks.IdentityDeserializer{Identity: []byte("Dave"), Msg: []byte("msg4"), Mock: mock.Mock{}}, 192 }, 193 }, 194 cryptoProvider, 195 ) 196 197 msg := []byte("msg1") 198 sigma, err := msgCryptoService.Sign(msg) 199 require.NoError(t, err, "Failed generating signature") 200 201 err = msgCryptoService.Verify(api.PeerIdentityType("Alice"), sigma, msg) 202 require.NoError(t, err, "Alice should verify the signature") 203 204 err = msgCryptoService.Verify(api.PeerIdentityType("Bob"), sigma, msg) 205 require.Error(t, err, "Bob should not verify the signature") 206 207 err = msgCryptoService.Verify(api.PeerIdentityType("Charlie"), sigma, msg) 208 require.Error(t, err, "Charlie should not verify the signature") 209 210 sigma, err = msgCryptoService.Sign(msg) 211 require.NoError(t, err) 212 err = msgCryptoService.Verify(api.PeerIdentityType("Dave"), sigma, msg) 213 require.Error(t, err) 214 require.Contains(t, err.Error(), "Could not acquire policy manager") 215 216 // Check invalid args 217 require.Error(t, msgCryptoService.Verify(nil, sigma, msg)) 218 } 219 220 func TestVerifyBlock(t *testing.T) { 221 aliceSigner := &mocks.SignerSerializer{} 222 aliceSigner.SerializeReturns([]byte("Alice"), nil) 223 policyManagerGetter := &mocks.ChannelPolicyManagerGetterWithManager{ 224 Managers: map[string]policies.Manager{ 225 "A": &mocks.ChannelPolicyManager{ 226 Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}}}, 227 }, 228 "B": &mocks.ChannelPolicyManager{ 229 Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Charlie"), Msg: []byte("msg3"), Mock: mock.Mock{}}}, 230 }, 231 "C": &mocks.ChannelPolicyManager{ 232 Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}}}, 233 }, 234 "D": &mocks.ChannelPolicyManager{ 235 Policy: &mocks.Policy{Deserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}}}, 236 }, 237 }, 238 } 239 240 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 241 require.NoError(t, err) 242 msgCryptoService := NewMCS( 243 policyManagerGetter, 244 aliceSigner, 245 &mocks.DeserializersManager{ 246 LocalDeserializer: &mocks.IdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1"), Mock: mock.Mock{}}, 247 ChannelDeserializers: map[string]msp.IdentityDeserializer{ 248 "A": &mocks.IdentityDeserializer{Identity: []byte("Bob"), Msg: []byte("msg2"), Mock: mock.Mock{}}, 249 "B": &mocks.IdentityDeserializer{Identity: []byte("Charlie"), Msg: []byte("msg3"), Mock: mock.Mock{}}, 250 }, 251 }, 252 cryptoProvider, 253 ) 254 255 // - Prepare testing valid block, Alice signs it. 256 blockRaw, msg := mockBlock(t, "C", 42, aliceSigner, nil) 257 policyManagerGetter.Managers["C"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg 258 blockRaw2, msg2 := mockBlock(t, "D", 42, aliceSigner, nil) 259 policyManagerGetter.Managers["D"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg2 260 261 // - Verify block 262 require.NoError(t, msgCryptoService.VerifyBlock([]byte("C"), 42, blockRaw)) 263 // Wrong sequence number claimed 264 err = msgCryptoService.VerifyBlock([]byte("C"), 43, blockRaw) 265 require.Error(t, err) 266 require.Contains(t, err.Error(), "but actual seqNum inside block is") 267 delete(policyManagerGetter.Managers, "D") 268 nilPolMgrErr := msgCryptoService.VerifyBlock([]byte("D"), 42, blockRaw2) 269 require.Contains(t, nilPolMgrErr.Error(), "Could not acquire policy manager") 270 require.Error(t, nilPolMgrErr) 271 require.Error(t, msgCryptoService.VerifyBlock([]byte("A"), 42, blockRaw)) 272 require.Error(t, msgCryptoService.VerifyBlock([]byte("B"), 42, blockRaw)) 273 274 // - Prepare testing invalid block (wrong data has), Alice signs it. 275 blockRaw, msg = mockBlock(t, "C", 42, aliceSigner, []byte{0}) 276 policyManagerGetter.Managers["C"].(*mocks.ChannelPolicyManager).Policy.(*mocks.Policy).Deserializer.(*mocks.IdentityDeserializer).Msg = msg 277 278 // - Verify block 279 require.Error(t, msgCryptoService.VerifyBlock([]byte("C"), 42, blockRaw)) 280 281 // Check invalid args 282 require.Error(t, msgCryptoService.VerifyBlock([]byte("C"), 42, &common.Block{})) 283 } 284 285 func mockBlock(t *testing.T, channel string, seqNum uint64, localSigner *mocks.SignerSerializer, dataHash []byte) (*common.Block, []byte) { 286 block := protoutil.NewBlock(seqNum, nil) 287 288 // Add a fake transaction to the block referring channel "C" 289 sProp, _ := protoutil.MockSignedEndorserProposalOrPanic(channel, &protospeer.ChaincodeSpec{}, []byte("transactor"), []byte("transactor's signature")) 290 sPropRaw, err := protoutil.Marshal(sProp) 291 require.NoError(t, err, "Failed marshalling signed proposal") 292 block.Data.Data = [][]byte{sPropRaw} 293 294 // Compute hash of block.Data and put into the Header 295 if len(dataHash) != 0 { 296 block.Header.DataHash = dataHash 297 } else { 298 block.Header.DataHash = protoutil.BlockDataHash(block.Data) 299 } 300 301 // Add signer's signature to the block 302 shdr, err := protoutil.NewSignatureHeader(localSigner) 303 require.NoError(t, err, "Failed generating signature header") 304 305 blockSignature := &common.MetadataSignature{ 306 SignatureHeader: protoutil.MarshalOrPanic(shdr), 307 } 308 309 // Note, this value is intentionally nil, as this metadata is only about the signature, there is no additional metadata 310 // information required beyond the fact that the metadata item is signed. 311 blockSignatureValue := []byte(nil) 312 313 msg := util.ConcatenateBytes(blockSignatureValue, blockSignature.SignatureHeader, protoutil.BlockHeaderBytes(block.Header)) 314 localSigner.SignReturns(msg, nil) 315 blockSignature.Signature, err = localSigner.Sign(msg) 316 require.NoError(t, err, "Failed signing block") 317 318 block.Metadata.Metadata[common.BlockMetadataIndex_SIGNATURES] = protoutil.MarshalOrPanic(&common.Metadata{ 319 Value: blockSignatureValue, 320 Signatures: []*common.MetadataSignature{ 321 blockSignature, 322 }, 323 }) 324 325 return block, msg 326 } 327 328 func TestExpiration(t *testing.T) { 329 expirationDate := time.Now().Add(time.Minute) 330 id1 := &pmsp.SerializedIdentity{ 331 Mspid: "X509BasedMSP", 332 IdBytes: []byte("X509BasedIdentity"), 333 } 334 335 x509IdentityBytes, _ := proto.Marshal(id1) 336 337 id2 := &pmsp.SerializedIdentity{ 338 Mspid: "nonX509BasedMSP", 339 IdBytes: []byte("nonX509RawIdentity"), 340 } 341 342 nonX509IdentityBytes, _ := proto.Marshal(id2) 343 344 deserializersManager := &mocks.DeserializersManager{ 345 LocalDeserializer: &mocks.IdentityDeserializer{ 346 Identity: []byte{1, 2, 3}, 347 Msg: []byte{1, 2, 3}, 348 }, 349 ChannelDeserializers: map[string]msp.IdentityDeserializer{ 350 "X509BasedMSP": &mocks.IdentityDeserializerWithExpiration{ 351 Expiration: expirationDate, 352 IdentityDeserializer: &mocks.IdentityDeserializer{ 353 Identity: x509IdentityBytes, 354 Msg: []byte("x509IdentityBytes"), 355 }, 356 }, 357 "nonX509BasedMSP": &mocks.IdentityDeserializer{ 358 Identity: nonX509IdentityBytes, 359 Msg: []byte("nonX509IdentityBytes"), 360 }, 361 }, 362 } 363 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 364 require.NoError(t, err) 365 msgCryptoService := NewMCS( 366 &mocks.ChannelPolicyManagerGetterWithManager{}, 367 &mocks.SignerSerializer{}, 368 deserializersManager, 369 cryptoProvider, 370 ) 371 372 // Green path I check the expiration date is as expected 373 exp, err := msgCryptoService.Expiration(x509IdentityBytes) 374 require.NoError(t, err) 375 require.Equal(t, expirationDate.Second(), exp.Second()) 376 377 // Green path II - a non-x509 identity has a zero expiration time 378 exp, err = msgCryptoService.Expiration(nonX509IdentityBytes) 379 require.NoError(t, err) 380 require.Zero(t, exp) 381 382 // Bad path I - corrupt the x509 identity and make sure error is returned 383 x509IdentityBytes = append(x509IdentityBytes, 0, 0, 0, 0, 0, 0) 384 exp, err = msgCryptoService.Expiration(x509IdentityBytes) 385 require.Error(t, err) 386 require.Contains(t, err.Error(), "No MSP found able to do that") 387 require.Zero(t, exp) 388 }