/
policy.go
132 lines (106 loc) · 3.4 KB
/
policy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//<developer>
// <name>linapex 曹一峰</name>
// <email>linapex@163.com</email>
// <wx>superexc</wx>
// <qqgroup>128148617</qqgroup>
// <url>https://jsq.ink</url>
// <role>pku engineer</role>
// <date>2019-03-16 19:39:53</date>
//</624455943102402560>
/*
版权所有IBM公司。保留所有权利。
SPDX许可证标识符:Apache-2.0
**/
package cauthdsl
import (
"errors"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/msp"
cb "github.com/hyperledger/fabric/protos/common"
mspp "github.com/hyperledger/fabric/protos/msp"
)
type Identity interface {
//satisfiesprincipal检查此实例是否匹配
//mspprincipal中提供的说明。支票可以
//涉及逐字节比较(如果主体是
//或可能需要MSP验证
SatisfiesPrincipal(principal *mspp.MSPPrincipal) error
//GetIdentifier返回该标识的标识符
GetIdentifier() *msp.IdentityIdentifier
}
type IdentityAndSignature interface {
//标识返回与此实例关联的标识
Identity() (Identity, error)
//verify返回此标识在消息上的签名的有效性状态
Verify() error
}
type deserializeAndVerify struct {
signedData *cb.SignedData
deserializer msp.IdentityDeserializer
deserializedIdentity msp.Identity
}
func (d *deserializeAndVerify) Identity() (Identity, error) {
deserializedIdentity, err := d.deserializer.DeserializeIdentity(d.signedData.Identity)
if err != nil {
return nil, err
}
d.deserializedIdentity = deserializedIdentity
return deserializedIdentity, nil
}
func (d *deserializeAndVerify) Verify() error {
if d.deserializedIdentity == nil {
cauthdslLogger.Panicf("programming error, Identity must be called prior to Verify")
}
return d.deserializedIdentity.Verify(d.signedData.Data, d.signedData.Signature)
}
type provider struct {
deserializer msp.IdentityDeserializer
}
//NewProviderImpl为cauthDSL类型策略提供策略生成器
func NewPolicyProvider(deserializer msp.IdentityDeserializer) policies.Provider {
return &provider{
deserializer: deserializer,
}
}
//new policy基于策略字节创建新策略
func (pr *provider) NewPolicy(data []byte) (policies.Policy, proto.Message, error) {
sigPolicy := &cb.SignaturePolicyEnvelope{}
if err := proto.Unmarshal(data, sigPolicy); err != nil {
return nil, nil, fmt.Errorf("Error unmarshaling to SignaturePolicy: %s", err)
}
if sigPolicy.Version != 0 {
return nil, nil, fmt.Errorf("This evaluator only understands messages of version 0, but version was %d", sigPolicy.Version)
}
compiled, err := compile(sigPolicy.Rule, sigPolicy.Identities, pr.deserializer)
if err != nil {
return nil, nil, err
}
return &policy{
evaluator: compiled,
deserializer: pr.deserializer,
}, sigPolicy, nil
}
type policy struct {
evaluator func([]IdentityAndSignature, []bool) bool
deserializer msp.IdentityDeserializer
}
//Evaluate获取一组SignedData并评估该组签名是否满足策略
func (p *policy) Evaluate(signatureSet []*cb.SignedData) error {
if p == nil {
return fmt.Errorf("No such policy")
}
idAndS := make([]IdentityAndSignature, len(signatureSet))
for i, sd := range signatureSet {
idAndS[i] = &deserializeAndVerify{
signedData: sd,
deserializer: p.deserializer,
}
}
ok := p.evaluator(deduplicate(idAndS), make([]bool, len(signatureSet)))
if !ok {
return errors.New("signature set did not satisfy policy")
}
return nil
}