Skip to content

Commit

Permalink
Merge "[FAB-15933] Optional NodeOU Classification" into release-1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
denyeart authored and Gerrit Code Review committed Aug 16, 2019
2 parents 3091941 + 7078648 commit 719e892
Show file tree
Hide file tree
Showing 19 changed files with 290 additions and 61 deletions.
10 changes: 8 additions & 2 deletions common/tools/cryptogen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type NodeTemplate struct {
}

type NodeSpec struct {
isAdmin bool
Hostname string `yaml:"Hostname"`
CommonName string `yaml:"CommonName"`
Country string `yaml:"Country"`
Expand Down Expand Up @@ -546,6 +547,7 @@ func generatePeerOrg(baseDir string, orgSpec OrgSpec) {
}
// add an admin user
adminUser := NodeSpec{
isAdmin: true,
CommonName: fmt.Sprintf("%s@%s", adminBaseName, orgName),
}

Expand Down Expand Up @@ -602,9 +604,13 @@ func generateNodes(baseDir string, nodes []NodeSpec, signCA *ca.CA, tlsCA *ca.CA
for _, node := range nodes {
nodeDir := filepath.Join(baseDir, node.CommonName)
if _, err := os.Stat(nodeDir); os.IsNotExist(err) {
err := msp.GenerateLocalMSP(nodeDir, node.CommonName, node.SANS, signCA, tlsCA, nodeType, nodeOUs)
currentNodeType := nodeType
if node.isAdmin && nodeOUs {
currentNodeType = msp.ADMIN
}
err := msp.GenerateLocalMSP(nodeDir, node.CommonName, node.SANS, signCA, tlsCA, currentNodeType, nodeOUs)
if err != nil {
fmt.Printf("Error generating local MSP for %s:\n%v\n", node, err)
fmt.Printf("Error generating local MSP for %v:\n%v\n", node, err)
os.Exit(1)
}
}
Expand Down
2 changes: 1 addition & 1 deletion integration/nwo/configtx_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Organizations:{{ range .PeerOrgs }}
Channel: &ChannelDefaults
Capabilities:
V1_4_2: true
V1_4_3: true
Policies:
Readers:
Type: ImplicitMeta
Expand Down
23 changes: 12 additions & 11 deletions msp/configbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,17 +296,14 @@ func getMspConfig(dir string, ID string, sigid *msp.SigningIdentityInfo) (*msp.M
// Prepare NodeOUs
if configuration.NodeOUs != nil && configuration.NodeOUs.Enable {
mspLogger.Debug("Loading NodeOUs")
if configuration.NodeOUs.ClientOUIdentifier == nil || len(configuration.NodeOUs.ClientOUIdentifier.OrganizationalUnitIdentifier) == 0 {
return nil, errors.New("Failed loading NodeOUs. ClientOU must be different from nil.")
nodeOUs = &msp.FabricNodeOUs{
Enable: true,
}
if configuration.NodeOUs.PeerOUIdentifier == nil || len(configuration.NodeOUs.PeerOUIdentifier.OrganizationalUnitIdentifier) == 0 {
return nil, errors.New("Failed loading NodeOUs. PeerOU must be different from nil.")
if configuration.NodeOUs.ClientOUIdentifier != nil && len(configuration.NodeOUs.ClientOUIdentifier.OrganizationalUnitIdentifier) != 0 {
nodeOUs.ClientOuIdentifier = &msp.FabricOUIdentifier{OrganizationalUnitIdentifier: configuration.NodeOUs.ClientOUIdentifier.OrganizationalUnitIdentifier}
}

nodeOUs = &msp.FabricNodeOUs{
Enable: configuration.NodeOUs.Enable,
ClientOuIdentifier: &msp.FabricOUIdentifier{OrganizationalUnitIdentifier: configuration.NodeOUs.ClientOUIdentifier.OrganizationalUnitIdentifier},
PeerOuIdentifier: &msp.FabricOUIdentifier{OrganizationalUnitIdentifier: configuration.NodeOUs.PeerOUIdentifier.OrganizationalUnitIdentifier},
if configuration.NodeOUs.PeerOUIdentifier != nil && len(configuration.NodeOUs.PeerOUIdentifier.OrganizationalUnitIdentifier) != 0 {
nodeOUs.PeerOuIdentifier = &msp.FabricOUIdentifier{OrganizationalUnitIdentifier: configuration.NodeOUs.PeerOUIdentifier.OrganizationalUnitIdentifier}
}
if configuration.NodeOUs.AdminOUIdentifier != nil && len(configuration.NodeOUs.AdminOUIdentifier.OrganizationalUnitIdentifier) != 0 {
nodeOUs.AdminOuIdentifier = &msp.FabricOUIdentifier{OrganizationalUnitIdentifier: configuration.NodeOUs.AdminOUIdentifier.OrganizationalUnitIdentifier}
Expand All @@ -318,9 +315,13 @@ func getMspConfig(dir string, ID string, sigid *msp.SigningIdentityInfo) (*msp.M
// Read certificates, if defined

// ClientOU
nodeOUs.ClientOuIdentifier.Certificate = loadCertificateAt(dir, configuration.NodeOUs.ClientOUIdentifier.Certificate, "ClientOU")
if nodeOUs.ClientOuIdentifier != nil {
nodeOUs.ClientOuIdentifier.Certificate = loadCertificateAt(dir, configuration.NodeOUs.ClientOUIdentifier.Certificate, "ClientOU")
}
// PeerOU
nodeOUs.PeerOuIdentifier.Certificate = loadCertificateAt(dir, configuration.NodeOUs.PeerOUIdentifier.Certificate, "PeerOU")
if nodeOUs.PeerOuIdentifier != nil {
nodeOUs.PeerOuIdentifier.Certificate = loadCertificateAt(dir, configuration.NodeOUs.PeerOUIdentifier.Certificate, "PeerOU")
}
// AdminOU
if nodeOUs.AdminOuIdentifier != nil {
nodeOUs.AdminOuIdentifier.Certificate = loadCertificateAt(dir, configuration.NodeOUs.AdminOUIdentifier.Certificate, "AdminOU")
Expand Down
22 changes: 13 additions & 9 deletions msp/mspimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,25 +326,29 @@ func (msp *bccspmsp) hasOURole(id Identity, mspRole m.MSPRole_MSPRoleType) error
}

func (msp *bccspmsp) hasOURoleInternal(id *identity, mspRole m.MSPRole_MSPRoleType) error {
var nodeOUValue string
var nodeOU *OUIdentifier
switch mspRole {
case m.MSPRole_CLIENT:
nodeOUValue = msp.clientOU.OrganizationalUnitIdentifier
nodeOU = msp.clientOU
case m.MSPRole_PEER:
nodeOUValue = msp.peerOU.OrganizationalUnitIdentifier
nodeOU = msp.peerOU
case m.MSPRole_ADMIN:
nodeOUValue = msp.adminOU.OrganizationalUnitIdentifier
nodeOU = msp.adminOU
case m.MSPRole_ORDERER:
if msp.ordererOU == nil {
return errors.New("cannot test for orderer ou classification, node ou for orderers not defined")
}
nodeOUValue = msp.ordererOU.OrganizationalUnitIdentifier
nodeOU = msp.ordererOU
default:
return errors.New("Invalid MSPRoleType. It must be CLIENT, PEER, ADMIN or ORDERER")
}

// Notice that, for versions prior to v1.4.3, hasOURoleInternal is invoked
// only to check that an identity is a client or a peer. The relative nodeOU are supposed to be different from nil.
// For version >= v1.4.3, any classification is optional.
if nodeOU == nil {
return errors.Errorf("cannot test for classification, node ou for type [%s], not defined, msp: [%s]", mspRole, msp.name)
}

for _, OU := range id.GetOrganizationalUnits() {
if OU.OrganizationalUnitIdentifier == nodeOUValue {
if OU.OrganizationalUnitIdentifier == nodeOU.OrganizationalUnitIdentifier {
return nil
}
}
Expand Down
81 changes: 64 additions & 17 deletions msp/mspimplsetup.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ func (msp *bccspmsp) setupAdminsV143(conf *m.FabricMSPConfig) error {
return err
}

if len(msp.admins) == 0 && !msp.ouEnforcement {
return errors.New("administrators must be declared when no ou enforcement is set")
if len(msp.admins) == 0 && (!msp.ouEnforcement || msp.adminOU == nil) {
return errors.New("administrators must be declared when no admin ou classification is set")
}

return nil
Expand Down Expand Up @@ -252,6 +252,14 @@ func (msp *bccspmsp) setupNodeOUs(config *m.FabricMSPConfig) error {

msp.ouEnforcement = config.FabricNodeOus.Enable

if config.FabricNodeOus.ClientOuIdentifier == nil || len(config.FabricNodeOus.ClientOuIdentifier.OrganizationalUnitIdentifier) == 0 {
return errors.New("Failed setting up NodeOUs. ClientOU must be different from nil.")
}

if config.FabricNodeOus.PeerOuIdentifier == nil || len(config.FabricNodeOus.PeerOuIdentifier.OrganizationalUnitIdentifier) == 0 {
return errors.New("Failed setting up NodeOUs. PeerOU must be different from nil.")
}

// ClientOU
msp.clientOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.ClientOuIdentifier.OrganizationalUnitIdentifier}
if len(config.FabricNodeOus.ClientOuIdentifier.Certificate) != 0 {
Expand Down Expand Up @@ -280,26 +288,57 @@ func (msp *bccspmsp) setupNodeOUs(config *m.FabricMSPConfig) error {
}

func (msp *bccspmsp) setupNodeOUsV143(config *m.FabricMSPConfig) error {
if err := msp.setupNodeOUs(config); err != nil {
return err
}

if config.FabricNodeOus == nil {
msp.ouEnforcement = false
return nil
}

// AdminOU
if config.FabricNodeOus.AdminOuIdentifier == nil {
return errors.New("invalid admin ou configuration, nil.")
msp.ouEnforcement = config.FabricNodeOus.Enable

counter := 0
// ClientOU
if config.FabricNodeOus.ClientOuIdentifier != nil {
msp.clientOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.ClientOuIdentifier.OrganizationalUnitIdentifier}
if len(config.FabricNodeOus.ClientOuIdentifier.Certificate) != 0 {
certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.ClientOuIdentifier.Certificate)
if err != nil {
return err
}
msp.clientOU.CertifiersIdentifier = certifiersIdentifier
}
counter++
} else {
msp.clientOU = nil
}

msp.adminOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.AdminOuIdentifier.OrganizationalUnitIdentifier}
if len(config.FabricNodeOus.AdminOuIdentifier.Certificate) != 0 {
certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.AdminOuIdentifier.Certificate)
if err != nil {
return err
// PeerOU
if config.FabricNodeOus.PeerOuIdentifier != nil {
msp.peerOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.PeerOuIdentifier.OrganizationalUnitIdentifier}
if len(config.FabricNodeOus.PeerOuIdentifier.Certificate) != 0 {
certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.PeerOuIdentifier.Certificate)
if err != nil {
return err
}
msp.peerOU.CertifiersIdentifier = certifiersIdentifier
}
counter++
} else {
msp.peerOU = nil
}

// AdminOU
if config.FabricNodeOus.AdminOuIdentifier != nil {
msp.adminOU = &OUIdentifier{OrganizationalUnitIdentifier: config.FabricNodeOus.AdminOuIdentifier.OrganizationalUnitIdentifier}
if len(config.FabricNodeOus.AdminOuIdentifier.Certificate) != 0 {
certifiersIdentifier, err := msp.getCertifiersIdentifier(config.FabricNodeOus.AdminOuIdentifier.Certificate)
if err != nil {
return err
}
msp.adminOU.CertifiersIdentifier = certifiersIdentifier
}
msp.adminOU.CertifiersIdentifier = certifiersIdentifier
counter++
} else {
msp.adminOU = nil
}

// OrdererOU
Expand All @@ -312,10 +351,16 @@ func (msp *bccspmsp) setupNodeOUsV143(config *m.FabricMSPConfig) error {
}
msp.ordererOU.CertifiersIdentifier = certifiersIdentifier
}
counter++
} else {
msp.ordererOU = nil
}

if counter == 0 {
// Disable NodeOU
msp.ouEnforcement = false
}

return nil
}

Expand Down Expand Up @@ -614,8 +659,10 @@ func (msp *bccspmsp) postSetupV143(conf *m.FabricMSPConfig) error {

// Check that admins are clients or admins
for i, admin := range msp.admins {
if msp.hasOURole(admin, m.MSPRole_CLIENT) != nil && msp.hasOURole(admin, m.MSPRole_ADMIN) != nil {
return errors.Errorf("admin %d is invalid", i)
err1 := msp.hasOURole(admin, m.MSPRole_CLIENT)
err2 := msp.hasOURole(admin, m.MSPRole_ADMIN)
if err1 != nil && err2 != nil {
return errors.Errorf("admin %d is invalid [%s,%s]", i, err1, err2)
}
}

Expand Down
12 changes: 9 additions & 3 deletions msp/mspimplvalidate.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,15 @@ func (msp *bccspmsp) validateIdentityOUsV143(id *identity) error {
// used to tell apart clients, peers and admins.
counter := 0
validOUs := make(map[string]*OUIdentifier)
validOUs[msp.clientOU.OrganizationalUnitIdentifier] = msp.clientOU
validOUs[msp.peerOU.OrganizationalUnitIdentifier] = msp.peerOU
validOUs[msp.adminOU.OrganizationalUnitIdentifier] = msp.adminOU
if msp.clientOU != nil {
validOUs[msp.clientOU.OrganizationalUnitIdentifier] = msp.clientOU
}
if msp.peerOU != nil {
validOUs[msp.peerOU.OrganizationalUnitIdentifier] = msp.peerOU
}
if msp.adminOU != nil {
validOUs[msp.adminOU.OrganizationalUnitIdentifier] = msp.adminOU
}
if msp.ordererOU != nil {
validOUs[msp.ordererOU.OrganizationalUnitIdentifier] = msp.ordererOU
}
Expand Down
47 changes: 29 additions & 18 deletions msp/nodeous_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
Copyright IBM Corp. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/

package msp
Expand Down Expand Up @@ -259,14 +249,14 @@ func TestSatisfiesPrincipalAdmin(t *testing.T) {
assert.NoError(t, err)
}

func TestLoad142MSPWithInvalidAdminConfiguration(t *testing.T) {
func TestLoad143MSPWithInvalidAdminConfiguration(t *testing.T) {
// testdata/nodeouadmin2:
// the configuration enables NodeOUs (with adminOU) but no valid identifier for the AdminOU
getLocalMSPWithVersionErr(t, "testdata/nodeouadmin2", MSPv1_4_3, "invalid admin ou configuration, nil.")
getLocalMSPWithVersionErr(t, "testdata/nodeouadmin2", MSPv1_4_3, "administrators must be declared when no admin ou classification is set")

// testdata/nodeouadmin3:
// the configuration enables NodeOUs (with adminOU) but no valid identifier for the AdminOU
getLocalMSPWithVersionErr(t, "testdata/nodeouadmin3", MSPv1_4_3, "invalid admin ou configuration, nil.")
getLocalMSPWithVersionErr(t, "testdata/nodeouadmin3", MSPv1_4_3, "administrators must be declared when no admin ou classification is set")
}

func TestSatisfiesPrincipalOrderer(t *testing.T) {
Expand All @@ -287,7 +277,7 @@ func TestSatisfiesPrincipalOrderer(t *testing.T) {
assert.NoError(t, err)
}

func TestLoad142MSPWithInvalidOrdererConfiguration(t *testing.T) {
func TestLoad143MSPWithInvalidOrdererConfiguration(t *testing.T) {
// testdata/nodeouorderer2:
// the configuration enables NodeOUs (with orderOU) but no valid identifier for the OrdererOU
thisMSP := getLocalMSPWithVersion(t, "testdata/nodeouorderer2", MSPv1_4_3)
Expand All @@ -304,7 +294,7 @@ func TestLoad142MSPWithInvalidOrdererConfiguration(t *testing.T) {
Principal: principalBytes}
err = id.SatisfiesPrincipal(principal)
assert.Error(t, err)
assert.Equal(t, "The identity is not a [ORDERER] under this MSP [SampleOrg]: cannot test for orderer ou classification, node ou for orderers not defined", err.Error())
assert.Equal(t, "The identity is not a [ORDERER] under this MSP [SampleOrg]: cannot test for classification, node ou for type [ORDERER], not defined, msp: [SampleOrg]", err.Error())

// testdata/nodeouorderer3:
// the configuration enables NodeOUs (with orderOU) but no valid identifier for the OrdererOU
Expand All @@ -322,5 +312,26 @@ func TestLoad142MSPWithInvalidOrdererConfiguration(t *testing.T) {
Principal: principalBytes}
err = id.SatisfiesPrincipal(principal)
assert.Error(t, err)
assert.Equal(t, "The identity is not a [ORDERER] under this MSP [SampleOrg]: cannot test for orderer ou classification, node ou for orderers not defined", err.Error())
assert.Equal(t, "The identity is not a [ORDERER] under this MSP [SampleOrg]: cannot test for classification, node ou for type [ORDERER], not defined, msp: [SampleOrg]", err.Error())
}

func TestValidMSPWithNodeOUMissingClassification(t *testing.T) {
// testdata/nodeousbadconf1:
// the configuration enables NodeOUs but client ou identifier is missing
_, err := getLocalMSPWithVersionAndError(t, "testdata/nodeousbadconf1", MSPv1_3)
assert.Error(t, err)
assert.Equal(t, "Failed setting up NodeOUs. ClientOU must be different from nil.", err.Error())

_, err = getLocalMSPWithVersionAndError(t, "testdata/nodeousbadconf1", MSPv1_4_3)
assert.Error(t, err)
assert.Equal(t, "admin 0 is invalid [cannot test for classification, node ou for type [CLIENT], not defined, msp: [SampleOrg],The identity does not contain OU [ADMIN], MSP: [SampleOrg]]", err.Error())

// testdata/nodeousbadconf2:
// the configuration enables NodeOUs but peer ou identifier is missing
_, err = getLocalMSPWithVersionAndError(t, "testdata/nodeousbadconf2", MSPv1_3)
assert.Error(t, err)
assert.Equal(t, "Failed setting up NodeOUs. PeerOU must be different from nil.", err.Error())

_, err = getLocalMSPWithVersionAndError(t, "testdata/nodeousbadconf2", MSPv1_4_3)
assert.NoError(t, err)
}
14 changes: 14 additions & 0 deletions msp/testdata/nodeousbadconf1/admincerts/Admin@example.com-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICGzCCAcKgAwIBAgIRAN5DkOBs583C+swyjC7nHS0wCgYIKoZIzj0EAwIwaTEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFt
cGxlLmNvbTAeFw0xOTA3MDQxNjI3MDBaFw0yOTA3MDExNjI3MDBaMGcxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
c2NvMQ8wDQYDVQQLEwZjbGllbnQxGjAYBgNVBAMMEUFkbWluQGV4YW1wbGUuY29t
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3H+SsKIPqOTCn2YBHDYTkgsvYtr0
6Kz3mEp4jfNmRt0Mz/Sjyg+E3AUjBah/Qj6WBqVYhmJeFsMoNvk8OhdHg6NNMEsw
DgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAg3+GALQue
CGamN/C2yq8S+ET/YsjAltoJS2hjlwUXxZ8wCgYIKoZIzj0EAwIDRwAwRAIgXvE1
Dsw0Vd2Tz+mxCfyf62lzQ8IN2BE4qsEQNgcsL94CIH26gcvFF7u0j+FVkjA4Awuq
10yaq8RzytoLpOz4SDkw
-----END CERTIFICATE-----
15 changes: 15 additions & 0 deletions msp/testdata/nodeousbadconf1/cacerts/ca.example.com-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICPzCCAeSgAwIBAgIRAONi5v8ImyejqCrCatbAW1QwCgYIKoZIzj0EAwIwaTEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFt
cGxlLmNvbTAeFw0xOTA3MDQxNjI3MDBaFw0yOTA3MDExNjI3MDBaMGkxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
c2NvMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEXMBUGA1UEAxMOY2EuZXhhbXBsZS5j
b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQAfjOlLCdB/6SsdPlbDHUsdK+b
gRuEN38QOFZ0Ws3aFAsER8ImqV3UIlsbKi5JnDs+OQnzrr3hrKA8downRRy/o20w
azAOBgNVHQ8BAf8EBAMCAaYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB
MA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEIN/hgC0LnghmpjfwtsqvEvhE/2LI
wJbaCUtoY5cFF8WfMAoGCCqGSM49BAMCA0kAMEYCIQDhhgAHx0l7V5uAG2hATgCs
bvsbHiJpHUtiK7f1Qfxf2AIhANeukSgRU+AeGSzyVmAOKhIUS+grsPyspksUwVvB
ehXv
-----END CERTIFICATE-----
14 changes: 14 additions & 0 deletions msp/testdata/nodeousbadconf1/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
NodeOUs:
Enable: true
ClientOUIdentifier:
Certificate: cacerts/ca.example.com-cert.pem
OrganizationalUnitIdentifier:
PeerOUIdentifier:
Certificate: cacerts/ca.example.com-cert.pem
OrganizationalUnitIdentifier: peer
AdminOUIdentifier:
Certificate: cacerts/ca.example.com-cert.pem
OrganizationalUnitIdentifier: admin
OrdererOUIdentifier:
Certificate: cacerts/ca.example.com-cert.pem
OrganizationalUnitIdentifier: orderer
Loading

0 comments on commit 719e892

Please sign in to comment.