github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/cauthdsl/cauthdsl.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 "time" 12 13 cb "github.com/hyperledger/fabric-protos-go/common" 14 mb "github.com/hyperledger/fabric-protos-go/msp" 15 "github.com/hyperledger/fabric/common/flogging" 16 "github.com/hyperledger/fabric/msp" 17 "go.uber.org/zap/zapcore" 18 ) 19 20 var cauthdslLogger = flogging.MustGetLogger("cauthdsl") 21 22 // compile recursively builds a go evaluatable function corresponding to the policy specified, remember to call deduplicate on identities before 23 // passing them to this function for evaluation 24 func compile(policy *cb.SignaturePolicy, identities []*mb.MSPPrincipal) (func([]msp.Identity, []bool) bool, error) { 25 if policy == nil { 26 return nil, fmt.Errorf("Empty policy element") 27 } 28 29 switch t := policy.Type.(type) { 30 case *cb.SignaturePolicy_NOutOf_: 31 policies := make([]func([]msp.Identity, []bool) bool, len(t.NOutOf.Rules)) 32 for i, policy := range t.NOutOf.Rules { 33 compiledPolicy, err := compile(policy, identities) 34 if err != nil { 35 return nil, err 36 } 37 policies[i] = compiledPolicy 38 39 } 40 return func(signedData []msp.Identity, used []bool) bool { 41 grepKey := time.Now().UnixNano() 42 cauthdslLogger.Debugf("%p gate %d evaluation starts", signedData, grepKey) 43 verified := int32(0) 44 _used := make([]bool, len(used)) 45 for _, policy := range policies { 46 copy(_used, used) 47 if policy(signedData, _used) { 48 verified++ 49 copy(used, _used) 50 } 51 } 52 53 if verified >= t.NOutOf.N { 54 cauthdslLogger.Debugf("%p gate %d evaluation succeeds", signedData, grepKey) 55 } else { 56 cauthdslLogger.Debugf("%p gate %d evaluation fails", signedData, grepKey) 57 } 58 59 return verified >= t.NOutOf.N 60 }, nil 61 case *cb.SignaturePolicy_SignedBy: 62 if t.SignedBy < 0 || t.SignedBy >= int32(len(identities)) { 63 return nil, fmt.Errorf("identity index out of range, requested %v, but identities length is %d", t.SignedBy, len(identities)) 64 } 65 signedByID := identities[t.SignedBy] 66 return func(signedData []msp.Identity, used []bool) bool { 67 cauthdslLogger.Debugf("%p signed by %d principal evaluation starts (used %v)", signedData, t.SignedBy, used) 68 for i, sd := range signedData { 69 if used[i] { 70 cauthdslLogger.Debugf("%p skipping identity %d because it has already been used", signedData, i) 71 continue 72 } 73 if cauthdslLogger.IsEnabledFor(zapcore.DebugLevel) { 74 // Unlike most places, this is a huge print statement, and worth checking log level before create garbage 75 cauthdslLogger.Debugf("%p processing identity %d - %v", signedData, i, sd.GetIdentifier()) 76 } 77 err := sd.SatisfiesPrincipal(signedByID) 78 if err != nil { 79 cauthdslLogger.Debugf("%p identity %d does not satisfy principal: %s", signedData, i, err) 80 continue 81 } 82 cauthdslLogger.Debugf("%p principal evaluation succeeds for identity %d", signedData, i) 83 used[i] = true 84 return true 85 } 86 cauthdslLogger.Debugf("%p principal evaluation fails", signedData) 87 return false 88 }, nil 89 default: 90 return nil, fmt.Errorf("Unknown type: %T:%v", t, t) 91 } 92 }