github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/cauthdsl/cauthdsl_test.go (about)

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