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 }