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  }