github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/cauthdsl/policy.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 "fmt" 11 12 "github.com/golang/protobuf/proto" 13 "github.com/hechain20/hechain/common/policies" 14 "github.com/hechain20/hechain/msp" 15 "github.com/hechain20/hechain/protoutil" 16 cb "github.com/hyperledger/fabric-protos-go/common" 17 "github.com/pkg/errors" 18 ) 19 20 type provider struct { 21 deserializer msp.IdentityDeserializer 22 } 23 24 // NewPolicyProvider provides a policy generator for cauthdsl type policies 25 func NewPolicyProvider(deserializer msp.IdentityDeserializer) policies.Provider { 26 return &provider{ 27 deserializer: deserializer, 28 } 29 } 30 31 // NewPolicy creates a new policy based on the policy bytes 32 func (pr *provider) NewPolicy(data []byte) (policies.Policy, proto.Message, error) { 33 sigPolicy := &cb.SignaturePolicyEnvelope{} 34 if err := proto.Unmarshal(data, sigPolicy); err != nil { 35 return nil, nil, fmt.Errorf("Error unmarshalling to SignaturePolicy: %s", err) 36 } 37 38 if sigPolicy.Version != 0 { 39 return nil, nil, fmt.Errorf("This evaluator only understands messages of version 0, but version was %d", sigPolicy.Version) 40 } 41 42 compiled, err := compile(sigPolicy.Rule, sigPolicy.Identities) 43 if err != nil { 44 return nil, nil, err 45 } 46 47 return &policy{ 48 evaluator: compiled, 49 deserializer: pr.deserializer, 50 signaturePolicyEnvelope: sigPolicy, 51 }, sigPolicy, nil 52 } 53 54 // EnvelopeBasedPolicyProvider allows to create a new policy from SignaturePolicyEnvelope struct instead of []byte 55 type EnvelopeBasedPolicyProvider struct { 56 Deserializer msp.IdentityDeserializer 57 } 58 59 // NewPolicy creates a new policy from the policy envelope 60 func (pp *EnvelopeBasedPolicyProvider) NewPolicy(sigPolicy *cb.SignaturePolicyEnvelope) (policies.Policy, error) { 61 if sigPolicy == nil { 62 return nil, errors.New("invalid arguments") 63 } 64 65 compiled, err := compile(sigPolicy.Rule, sigPolicy.Identities) 66 if err != nil { 67 return nil, err 68 } 69 70 return &policy{ 71 evaluator: compiled, 72 deserializer: pp.Deserializer, 73 signaturePolicyEnvelope: sigPolicy, 74 }, nil 75 } 76 77 type policy struct { 78 signaturePolicyEnvelope *cb.SignaturePolicyEnvelope 79 evaluator func([]msp.Identity, []bool) bool 80 deserializer msp.IdentityDeserializer 81 } 82 83 // EvaluateSignedData takes a set of SignedData and evaluates whether 84 // 1) the signatures are valid over the related message 85 // 2) the signing identities satisfy the policy 86 func (p *policy) EvaluateSignedData(signatureSet []*protoutil.SignedData) error { 87 if p == nil { 88 return errors.New("no such policy") 89 } 90 91 ids := policies.SignatureSetToValidIdentities(signatureSet, p.deserializer) 92 93 return p.EvaluateIdentities(ids) 94 } 95 96 // EvaluateIdentities takes an array of identities and evaluates whether 97 // they satisfy the policy 98 func (p *policy) EvaluateIdentities(identities []msp.Identity) error { 99 if p == nil { 100 return fmt.Errorf("No such policy") 101 } 102 103 ok := p.evaluator(identities, make([]bool, len(identities))) 104 if !ok { 105 return errors.New("signature set did not satisfy policy") 106 } 107 return nil 108 } 109 110 func (p *policy) Convert() (*cb.SignaturePolicyEnvelope, error) { 111 if p.signaturePolicyEnvelope == nil { 112 return nil, errors.New("nil policy field") 113 } 114 115 return p.signaturePolicyEnvelope, nil 116 }