github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/discovery/support/acl/support.go (about)

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