github.com/yimialmonte/fabric@v2.1.1+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  }