github.com/kaituanwang/hyperledger@v2.0.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 }