github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/cauthdsl/cauthdsl_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package cauthdsl 8 9 import ( 10 "bytes" 11 "errors" 12 "testing" 13 "time" 14 15 "github.com/golang/protobuf/proto" 16 "github.com/hechain20/hechain/common/policydsl" 17 "github.com/hechain20/hechain/msp" 18 cb "github.com/hyperledger/fabric-protos-go/common" 19 mb "github.com/hyperledger/fabric-protos-go/msp" 20 "github.com/stretchr/testify/require" 21 ) 22 23 var invalidSignature = []byte("badsigned") 24 25 type mockIdentity struct { 26 idBytes []byte 27 } 28 29 func (id *mockIdentity) Anonymous() bool { 30 panic("implement me") 31 } 32 33 func (id *mockIdentity) ExpiresAt() time.Time { 34 return time.Time{} 35 } 36 37 func (id *mockIdentity) SatisfiesPrincipal(p *mb.MSPPrincipal) error { 38 if !bytes.Equal(id.idBytes, p.Principal) { 39 return errors.New("Principals do not match") 40 } 41 return nil 42 } 43 44 func (id *mockIdentity) GetIdentifier() *msp.IdentityIdentifier { 45 return &msp.IdentityIdentifier{Mspid: "Mock", Id: string(id.idBytes)} 46 } 47 48 func (id *mockIdentity) GetMSPIdentifier() string { 49 return "Mock" 50 } 51 52 func (id *mockIdentity) Validate() error { 53 return nil 54 } 55 56 func (id *mockIdentity) GetOrganizationalUnits() []*msp.OUIdentifier { 57 return nil 58 } 59 60 func (id *mockIdentity) Verify(msg []byte, sig []byte) error { 61 if bytes.Equal(sig, invalidSignature) { 62 return errors.New("Invalid signature") 63 } 64 return nil 65 } 66 67 func (id *mockIdentity) Serialize() ([]byte, error) { 68 return id.idBytes, nil 69 } 70 71 func toIdentities(idBytesSlice [][]byte, deserializer msp.IdentityDeserializer) ([]msp.Identity, []bool) { 72 identities := make([]msp.Identity, len(idBytesSlice)) 73 for i, idBytes := range idBytesSlice { 74 id, _ := deserializer.DeserializeIdentity(idBytes) 75 identities[i] = id 76 } 77 78 return identities, make([]bool, len(idBytesSlice)) 79 } 80 81 type mockDeserializer struct { 82 fail error 83 } 84 85 func (md *mockDeserializer) IsWellFormed(_ *mb.SerializedIdentity) error { 86 return nil 87 } 88 89 func (md *mockDeserializer) DeserializeIdentity(serializedIdentity []byte) (msp.Identity, error) { 90 if md.fail != nil { 91 return nil, md.fail 92 } 93 return &mockIdentity{idBytes: serializedIdentity}, nil 94 } 95 96 var signers = [][]byte{[]byte("signer0"), []byte("signer1")} 97 98 func TestSimpleSignature(t *testing.T) { 99 policy := policydsl.Envelope(policydsl.SignedBy(0), signers) 100 101 spe, err := compile(policy.Rule, policy.Identities) 102 if err != nil { 103 t.Fatalf("Could not create a new SignaturePolicyEvaluator using the given policy, crypto-helper: %s", err) 104 } 105 106 if !spe(toIdentities([][]byte{signers[0]}, &mockDeserializer{})) { 107 t.Errorf("Expected authentication to succeed with valid signatures") 108 } 109 if spe(toIdentities([][]byte{signers[1]}, &mockDeserializer{})) { 110 t.Errorf("Expected authentication to fail because signers[1] is not authorized in the policy, despite his valid signature") 111 } 112 } 113 114 func TestMultipleSignature(t *testing.T) { 115 policy := policydsl.Envelope(policydsl.And(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers) 116 117 spe, err := compile(policy.Rule, policy.Identities) 118 if err != nil { 119 t.Fatalf("Could not create a new SignaturePolicyEvaluator using the given policy, crypto-helper: %s", err) 120 } 121 122 if !spe(toIdentities(signers, &mockDeserializer{})) { 123 t.Errorf("Expected authentication to succeed with valid signatures") 124 } 125 if spe(toIdentities([][]byte{signers[0], signers[0]}, &mockDeserializer{})) { 126 t.Errorf("Expected authentication to fail because although there were two valid signatures, one was duplicated") 127 } 128 } 129 130 func TestComplexNestedSignature(t *testing.T) { 131 policy := policydsl.Envelope(policydsl.And(policydsl.Or(policydsl.And(policydsl.SignedBy(0), policydsl.SignedBy(1)), policydsl.And(policydsl.SignedBy(0), policydsl.SignedBy(0))), policydsl.SignedBy(0)), signers) 132 133 spe, err := compile(policy.Rule, policy.Identities) 134 if err != nil { 135 t.Fatalf("Could not create a new SignaturePolicyEvaluator using the given policy, crypto-helper: %s", err) 136 } 137 138 if !spe(toIdentities(append(signers, [][]byte{[]byte("signer0")}...), &mockDeserializer{})) { 139 t.Errorf("Expected authentication to succeed with valid signatures") 140 } 141 if !spe(toIdentities([][]byte{[]byte("signer0"), []byte("signer0"), []byte("signer0")}, &mockDeserializer{})) { 142 t.Errorf("Expected authentication to succeed with valid signatures") 143 } 144 if spe(toIdentities(signers, &mockDeserializer{})) { 145 t.Errorf("Expected authentication to fail with too few signatures") 146 } 147 if spe(toIdentities(append(signers, [][]byte{[]byte("signer1")}...), &mockDeserializer{})) { 148 t.Errorf("Expected authentication failure as there was a signature from signer[0] missing") 149 } 150 } 151 152 func TestNegatively(t *testing.T) { 153 rpolicy := policydsl.Envelope(policydsl.And(policydsl.SignedBy(0), policydsl.SignedBy(1)), signers) 154 rpolicy.Rule.Type = nil 155 b, _ := proto.Marshal(rpolicy) 156 policy := &cb.SignaturePolicyEnvelope{} 157 _ = proto.Unmarshal(b, policy) 158 _, err := compile(policy.Rule, policy.Identities) 159 if err == nil { 160 t.Fatal("Should have errored compiling because the Type field was nil") 161 } 162 } 163 164 func TestNilSignaturePolicyEnvelope(t *testing.T) { 165 _, err := compile(nil, nil) 166 require.Error(t, err, "Fail to compile") 167 } 168 169 func TestSignedByMspClient(t *testing.T) { 170 e := policydsl.SignedByMspClient("A") 171 require.Equal(t, 1, len(e.Identities)) 172 173 role := &mb.MSPRole{} 174 err := proto.Unmarshal(e.Identities[0].Principal, role) 175 require.NoError(t, err) 176 177 require.Equal(t, role.MspIdentifier, "A") 178 require.Equal(t, role.Role, mb.MSPRole_CLIENT) 179 180 e = policydsl.SignedByAnyClient([]string{"A"}) 181 require.Equal(t, 1, len(e.Identities)) 182 183 role = &mb.MSPRole{} 184 err = proto.Unmarshal(e.Identities[0].Principal, role) 185 require.NoError(t, err) 186 187 require.Equal(t, role.MspIdentifier, "A") 188 require.Equal(t, role.Role, mb.MSPRole_CLIENT) 189 } 190 191 func TestSignedByMspPeer(t *testing.T) { 192 e := policydsl.SignedByMspPeer("A") 193 require.Equal(t, 1, len(e.Identities)) 194 195 role := &mb.MSPRole{} 196 err := proto.Unmarshal(e.Identities[0].Principal, role) 197 require.NoError(t, err) 198 199 require.Equal(t, role.MspIdentifier, "A") 200 require.Equal(t, role.Role, mb.MSPRole_PEER) 201 202 e = policydsl.SignedByAnyPeer([]string{"A"}) 203 require.Equal(t, 1, len(e.Identities)) 204 205 role = &mb.MSPRole{} 206 err = proto.Unmarshal(e.Identities[0].Principal, role) 207 require.NoError(t, err) 208 209 require.Equal(t, role.MspIdentifier, "A") 210 require.Equal(t, role.Role, mb.MSPRole_PEER) 211 } 212 213 func TestReturnNil(t *testing.T) { 214 policy := policydsl.Envelope(policydsl.And(policydsl.SignedBy(-1), policydsl.SignedBy(-2)), signers) 215 216 spe, err := compile(policy.Rule, policy.Identities) 217 require.Nil(t, spe) 218 require.EqualError(t, err, "identity index out of range, requested -1, but identities length is 2") 219 }