github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/cauthdsl/policy.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 "fmt" 11 12 "github.com/golang/protobuf/proto" 13 cb "github.com/hyperledger/fabric-protos-go/common" 14 "github.com/hyperledger/fabric/common/policies" 15 "github.com/hyperledger/fabric/msp" 16 "github.com/hyperledger/fabric/protoutil" 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 unmarshaling 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 55 // EnvelopeBasedPolicyProvider allows to create a new policy from SignaturePolicyEnvelope struct instead of []byte 56 type EnvelopeBasedPolicyProvider struct { 57 Deserializer msp.IdentityDeserializer 58 } 59 60 // NewPolicy creates a new policy from the policy envelope 61 func (pp *EnvelopeBasedPolicyProvider) NewPolicy(sigPolicy *cb.SignaturePolicyEnvelope) (policies.Policy, error) { 62 if sigPolicy == nil { 63 return nil, errors.New("invalid arguments") 64 } 65 66 compiled, err := compile(sigPolicy.Rule, sigPolicy.Identities) 67 if err != nil { 68 return nil, err 69 } 70 71 return &policy{ 72 evaluator: compiled, 73 deserializer: pp.Deserializer, 74 signaturePolicyEnvelope: sigPolicy, 75 }, nil 76 } 77 78 type policy struct { 79 signaturePolicyEnvelope *cb.SignaturePolicyEnvelope 80 evaluator func([]msp.Identity, []bool) bool 81 deserializer msp.IdentityDeserializer 82 } 83 84 // EvaluateSignedData takes a set of SignedData and evaluates whether 85 // 1) the signatures are valid over the related message 86 // 2) the signing identities satisfy the policy 87 func (p *policy) EvaluateSignedData(signatureSet []*protoutil.SignedData) error { 88 if p == nil { 89 return errors.New("no such policy") 90 } 91 92 ids := policies.SignatureSetToValidIdentities(signatureSet, p.deserializer) 93 94 return p.EvaluateIdentities(ids) 95 } 96 97 // EvaluateIdentities takes an array of identities and evaluates whether 98 // they satisfy the policy 99 func (p *policy) EvaluateIdentities(identities []msp.Identity) error { 100 if p == nil { 101 return fmt.Errorf("No such policy") 102 } 103 104 ok := p.evaluator(identities, make([]bool, len(identities))) 105 if !ok { 106 return errors.New("signature set did not satisfy policy") 107 } 108 return nil 109 } 110 111 func (p *policy) Convert() (*cb.SignaturePolicyEnvelope, error) { 112 if p.signaturePolicyEnvelope == nil { 113 return nil, errors.New("nil policy field") 114 } 115 116 return p.signaturePolicyEnvelope, nil 117 }