github.com/lzy4123/fabric@v2.1.1+incompatible/discovery/support/acl/support.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package acl
     8  
     9  import (
    10  	"github.com/hyperledger/fabric-protos-go/msp"
    11  	"github.com/hyperledger/fabric/common/channelconfig"
    12  	"github.com/hyperledger/fabric/common/flogging"
    13  	"github.com/hyperledger/fabric/common/policies"
    14  	"github.com/hyperledger/fabric/protoutil"
    15  	"github.com/pkg/errors"
    16  )
    17  
    18  var (
    19  	logger = flogging.MustGetLogger("discovery.acl")
    20  )
    21  
    22  // ChannelConfigGetter enables to retrieve the channel config resources
    23  type ChannelConfigGetter interface {
    24  	// GetChannelConfig returns the resources of the channel config
    25  	GetChannelConfig(cid string) channelconfig.Resources
    26  }
    27  
    28  // ChannelConfigGetterFunc returns the resources of the channel config
    29  type ChannelConfigGetterFunc func(cid string) channelconfig.Resources
    30  
    31  // GetChannelConfig returns the resources of the channel config
    32  func (f ChannelConfigGetterFunc) GetChannelConfig(cid string) channelconfig.Resources {
    33  	return f(cid)
    34  }
    35  
    36  // Verifier verifies a signature and a message
    37  type Verifier interface {
    38  	// VerifyByChannel checks that signature is a valid signature of message
    39  	// under a peer's verification key, but also in the context of a specific channel.
    40  	// If the verification succeeded, Verify returns nil meaning no error occurred.
    41  	// If peerIdentity is nil, then the verification fails.
    42  	VerifyByChannel(channel string, sd *protoutil.SignedData) error
    43  }
    44  
    45  // Evaluator evaluates signatures.
    46  // It is used to evaluate signatures for the local MSP
    47  type Evaluator interface {
    48  	policies.Policy
    49  }
    50  
    51  // DiscoverySupport implements support that is used for service discovery
    52  // that is related to access control
    53  type DiscoverySupport struct {
    54  	ChannelConfigGetter
    55  	Verifier
    56  	Evaluator
    57  }
    58  
    59  // NewDiscoverySupport creates a new DiscoverySupport
    60  func NewDiscoverySupport(v Verifier, e Evaluator, chanConf ChannelConfigGetter) *DiscoverySupport {
    61  	return &DiscoverySupport{Verifier: v, Evaluator: e, ChannelConfigGetter: chanConf}
    62  }
    63  
    64  // EligibleForService returns whether the given peer is eligible for receiving
    65  // service from the discovery service for a given channel
    66  func (s *DiscoverySupport) EligibleForService(channel string, data protoutil.SignedData) error {
    67  	if channel == "" {
    68  		return s.EvaluateSignedData([]*protoutil.SignedData{&data})
    69  	}
    70  	return s.VerifyByChannel(channel, &data)
    71  }
    72  
    73  // ConfigSequence returns the configuration sequence of the given channel
    74  func (s *DiscoverySupport) ConfigSequence(channel string) uint64 {
    75  	// No sequence if the channel is empty
    76  	if channel == "" {
    77  		return 0
    78  	}
    79  	conf := s.GetChannelConfig(channel)
    80  	if conf == nil {
    81  		logger.Panic("Failed obtaining channel config for channel", channel)
    82  	}
    83  	v := conf.ConfigtxValidator()
    84  	if v == nil {
    85  		logger.Panic("ConfigtxValidator for channel", channel, "is nil")
    86  	}
    87  	return v.Sequence()
    88  }
    89  
    90  func (s *DiscoverySupport) SatisfiesPrincipal(channel string, rawIdentity []byte, principal *msp.MSPPrincipal) error {
    91  	conf := s.GetChannelConfig(channel)
    92  	if conf == nil {
    93  		return errors.Errorf("channel %s doesn't exist", channel)
    94  	}
    95  	mspMgr := conf.MSPManager()
    96  	if mspMgr == nil {
    97  		return errors.Errorf("could not find MSP manager for channel %s", channel)
    98  	}
    99  	identity, err := mspMgr.DeserializeIdentity(rawIdentity)
   100  	if err != nil {
   101  		return errors.Wrap(err, "failed deserializing identity")
   102  	}
   103  	return identity.SatisfiesPrincipal(principal)
   104  }
   105  
   106  // ChannelPolicyManagerGetter is a support interface
   107  // to get access to the policy manager of a given channel
   108  type ChannelPolicyManagerGetter interface {
   109  	// Returns the policy manager associated to the passed channel
   110  	// and true if it was the manager requested, or false if it is the default manager
   111  	Manager(channelID string) policies.Manager
   112  }
   113  
   114  // NewChannelVerifier returns a new channel verifier from the given policy and policy manager getter
   115  func NewChannelVerifier(policy string, polMgr policies.ChannelPolicyManagerGetter) *ChannelVerifier {
   116  	return &ChannelVerifier{
   117  		Policy:                     policy,
   118  		ChannelPolicyManagerGetter: polMgr,
   119  	}
   120  }
   121  
   122  // ChannelVerifier verifies a signature and a message on the context of a channel
   123  type ChannelVerifier struct {
   124  	policies.ChannelPolicyManagerGetter
   125  	Policy string
   126  }
   127  
   128  // VerifyByChannel checks that signature is a valid signature of message
   129  // under a peer's verification key, but also in the context of a specific channel.
   130  // If the verification succeeded, Verify returns nil meaning no error occurred.
   131  // If peerIdentity is nil, then the verification fails.
   132  func (cv *ChannelVerifier) VerifyByChannel(channel string, sd *protoutil.SignedData) error {
   133  	mgr := cv.Manager(channel)
   134  	if mgr == nil {
   135  		return errors.Errorf("policy manager for channel %s doesn't exist", channel)
   136  	}
   137  	pol, _ := mgr.GetPolicy(cv.Policy)
   138  	if pol == nil {
   139  		return errors.New("failed obtaining channel application writers policy")
   140  	}
   141  	return pol.EvaluateSignedData([]*protoutil.SignedData{sd})
   142  }