diff --git a/common/cauthdsl/cauthdsl_builder.go b/common/cauthdsl/cauthdsl_builder.go index 8a766103867..83bf3f6ef25 100644 --- a/common/cauthdsl/cauthdsl_builder.go +++ b/common/cauthdsl/cauthdsl_builder.go @@ -92,6 +92,24 @@ func SignedByMspMember(mspId string) *cb.SignaturePolicyEnvelope { return p } +// SignedByMspAdmin creates a SignaturePolicyEnvelope +// requiring 1 signature from any admin of the specified MSP +func SignedByMspAdmin(mspId string) *cb.SignaturePolicyEnvelope { + // specify the principal: it's a member of the msp we just found + principal := &cb.MSPPrincipal{ + PrincipalClassification: cb.MSPPrincipal_ROLE, + Principal: utils.MarshalOrPanic(&cb.MSPRole{Role: cb.MSPRole_ADMIN, MspIdentifier: mspId})} + + // create the policy: it requires exactly 1 signature from the first (and only) principal + p := &cb.SignaturePolicyEnvelope{ + Version: 0, + Policy: NOutOf(1, []*cb.SignaturePolicy{SignedBy(0)}), + Identities: []*cb.MSPPrincipal{principal}, + } + + return p +} + // And is a convenience method which utilizes NOutOf to produce And equivalent behavior func And(lhs, rhs *cb.SignaturePolicy) *cb.SignaturePolicy { return NOutOf(2, []*cb.SignaturePolicy{lhs, rhs}) diff --git a/common/configtx/tool/provisional/provisional.go b/common/configtx/tool/provisional/provisional.go index 2a5ee2b55e9..08b59faf4b5 100644 --- a/common/configtx/tool/provisional/provisional.go +++ b/common/configtx/tool/provisional/provisional.go @@ -25,6 +25,7 @@ import ( configtxchannel "github.com/hyperledger/fabric/common/configvalues/channel" configtxapplication "github.com/hyperledger/fabric/common/configvalues/channel/application" configtxorderer "github.com/hyperledger/fabric/common/configvalues/channel/orderer" + configvaluesmsp "github.com/hyperledger/fabric/common/configvalues/msp" "github.com/hyperledger/fabric/common/genesis" "github.com/hyperledger/fabric/common/policies" "github.com/hyperledger/fabric/orderer/common/bootstrap" @@ -56,15 +57,6 @@ const ( // AcceptAllPolicyKey is the key of the AcceptAllPolicy. AcceptAllPolicyKey = "AcceptAllPolicy" - - // ReadersPolicyKey is the key used for the read policy - ReadersPolicyKey = "Readers" - - // WritersPolicyKey is the key used for the read policy - WritersPolicyKey = "Writers" - - // AdminsPolicyKey is the key used for the read policy - AdminsPolicyKey = "Admins" ) // DefaultChainCreationPolicyNames is the default value of ChainCreatorsKey. @@ -99,19 +91,19 @@ func New(conf *genesisconfig.TopLevel) Generator { cauthdsl.TemplatePolicy(AcceptAllPolicyKey, cauthdsl.AcceptAllPolicy), // Initialize the default Reader/Writer/Admins channel policies - policies.TemplateImplicitMetaAnyPolicy([]string{}, ReadersPolicyKey), - policies.TemplateImplicitMetaAnyPolicy([]string{}, WritersPolicyKey), - policies.TemplateImplicitMetaMajorityPolicy([]string{}, AdminsPolicyKey), + policies.TemplateImplicitMetaAnyPolicy([]string{}, configvaluesmsp.ReadersPolicyKey), + policies.TemplateImplicitMetaAnyPolicy([]string{}, configvaluesmsp.WritersPolicyKey), + policies.TemplateImplicitMetaMajorityPolicy([]string{}, configvaluesmsp.AdminsPolicyKey), // Initialize the default Reader/Writer/Admins orderer policies - policies.TemplateImplicitMetaAnyPolicy([]string{configtxorderer.GroupKey}, ReadersPolicyKey), - policies.TemplateImplicitMetaAnyPolicy([]string{configtxorderer.GroupKey}, WritersPolicyKey), - policies.TemplateImplicitMetaMajorityPolicy([]string{configtxorderer.GroupKey}, AdminsPolicyKey), + policies.TemplateImplicitMetaAnyPolicy([]string{configtxorderer.GroupKey}, configvaluesmsp.ReadersPolicyKey), + policies.TemplateImplicitMetaAnyPolicy([]string{configtxorderer.GroupKey}, configvaluesmsp.WritersPolicyKey), + policies.TemplateImplicitMetaMajorityPolicy([]string{configtxorderer.GroupKey}, configvaluesmsp.AdminsPolicyKey), // Initialize the default Reader/Writer/Admins application policies - policies.TemplateImplicitMetaAnyPolicy([]string{configtxapplication.GroupKey}, ReadersPolicyKey), - policies.TemplateImplicitMetaAnyPolicy([]string{configtxapplication.GroupKey}, WritersPolicyKey), - policies.TemplateImplicitMetaMajorityPolicy([]string{configtxapplication.GroupKey}, AdminsPolicyKey), + policies.TemplateImplicitMetaAnyPolicy([]string{configtxapplication.GroupKey}, configvaluesmsp.ReadersPolicyKey), + policies.TemplateImplicitMetaAnyPolicy([]string{configtxapplication.GroupKey}, configvaluesmsp.WritersPolicyKey), + policies.TemplateImplicitMetaMajorityPolicy([]string{configtxapplication.GroupKey}, configvaluesmsp.AdminsPolicyKey), }, systemChainGroups: []*cb.ConfigGroup{ diff --git a/common/configvalues/msp/config_util.go b/common/configvalues/msp/config_util.go index fff5b0a457c..94bce99213f 100644 --- a/common/configvalues/msp/config_util.go +++ b/common/configvalues/msp/config_util.go @@ -17,25 +17,82 @@ limitations under the License. package msp import ( + "github.com/hyperledger/fabric/common/cauthdsl" + "github.com/hyperledger/fabric/msp" cb "github.com/hyperledger/fabric/protos/common" - "github.com/hyperledger/fabric/protos/msp" + mspprotos "github.com/hyperledger/fabric/protos/msp" "github.com/hyperledger/fabric/protos/utils" + + logging "github.com/op/go-logging" ) +var logger = logging.MustGetLogger("configvalues/msp") + const ( + // ReadersPolicyKey is the key used for the read policy + ReadersPolicyKey = "Readers" + + // WritersPolicyKey is the key used for the read policy + WritersPolicyKey = "Writers" + + // AdminsPolicyKey is the key used for the read policy + AdminsPolicyKey = "Admins" + + // MSPKey is the org key used for MSP configuration MSPKey = "MSP" ) // TemplateGroupMSP creates an MSP ConfigValue at the given configPath -func TemplateGroupMSP(configPath []string, mspConf *msp.MSPConfig) *cb.ConfigGroup { +func TemplateGroupMSP(configPath []string, mspConfig *mspprotos.MSPConfig) *cb.ConfigGroup { + // check that the type for that MSP is supported + if mspConfig.Type != int32(msp.FABRIC) { + logger.Panicf("Setup error: unsupported msp type %d", mspConfig.Type) + } + + // create the msp instance + mspInst, err := msp.NewBccspMsp() + if err != nil { + logger.Panicf("Creating the MSP manager failed, err %s", err) + } + + // set it up + err = mspInst.Setup(mspConfig) + if err != nil { + logger.Panicf("Setting up the MSP manager failed, err %s", err) + } + + // add the MSP to the map of pending MSPs + mspID, err := mspInst.GetIdentifier() + if err != nil { + logger.Panicf("Could not extract msp identifier, err %s", err) + } + + memberPolicy := &cb.ConfigPolicy{ + Policy: &cb.Policy{ + Type: int32(cb.Policy_SIGNATURE), + Policy: utils.MarshalOrPanic(cauthdsl.SignedByMspMember(mspID)), + }, + } + + adminPolicy := &cb.ConfigPolicy{ + Policy: &cb.Policy{ + Type: int32(cb.Policy_SIGNATURE), + Policy: utils.MarshalOrPanic(cauthdsl.SignedByMspAdmin(mspID)), + }, + } + result := cb.NewConfigGroup() + intermediate := result for _, group := range configPath { intermediate.Groups[group] = cb.NewConfigGroup() intermediate = intermediate.Groups[group] } intermediate.Values[MSPKey] = &cb.ConfigValue{ - Value: utils.MarshalOrPanic(mspConf), + Value: utils.MarshalOrPanic(mspConfig), } + intermediate.Policies[AdminsPolicyKey] = adminPolicy + intermediate.Policies[ReadersPolicyKey] = memberPolicy + intermediate.Policies[WritersPolicyKey] = memberPolicy return result }