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 }