From 16e209bf11e0e50920bf086d1a27c72c01bed058 Mon Sep 17 00:00:00 2001 From: Gari Singh Date: Sun, 4 Feb 2018 07:26:47 -0500 Subject: [PATCH] [FAB-6986] cryptogen support for NodeOUs Since cryptogen is used to generate MSPs used in many of the samples as well as by clients to bootstrap their test networks, it makes sense to add support for testing the NodeOU support added in FAB-5664. In order to keep things simple, crypotgen now provides an option to enable NodeOU support and uses a fixed set of OUs to avoid unnecessary confusion and complexity. Change-Id: I40745caa1761113c1358efc4c6ff05dda64e3ee9 Signed-off-by: Gari Singh --- common/tools/cryptogen/ca/ca_test.go | 33 ++++---- common/tools/cryptogen/ca/generator.go | 18 ++-- common/tools/cryptogen/csp/csp.go | 14 +--- common/tools/cryptogen/csp/csp_test.go | 14 +--- common/tools/cryptogen/main.go | 51 +++++------- common/tools/cryptogen/msp/generator.go | 83 +++++++++++++++---- .../tools/cryptogen/msp/msp_internal_test.go | 9 ++ common/tools/cryptogen/msp/msp_test.go | 67 ++++++++++----- 8 files changed, 166 insertions(+), 123 deletions(-) create mode 100644 common/tools/cryptogen/msp/msp_internal_test.go diff --git a/common/tools/cryptogen/ca/ca_test.go b/common/tools/cryptogen/ca/ca_test.go index 591fac20b35..95fc39baa28 100644 --- a/common/tools/cryptogen/ca/ca_test.go +++ b/common/tools/cryptogen/ca/ca_test.go @@ -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 ca_test @@ -62,7 +52,7 @@ func TestLoadCertificateECDSA(t *testing.T) { rootCA, err := ca.NewCA(caDir, testCA3Name, testCA3Name, testCountry, testProvince, testLocality, testOrganizationalUnit, testStreetAddress, testPostalCode) assert.NoError(t, err, "Error generating CA") - cert, err := rootCA.SignCertificate(certDir, testName3, nil, ecPubKey, + cert, err := rootCA.SignCertificate(certDir, testName3, nil, nil, ecPubKey, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}) assert.NoError(t, err, "Failed to generate signed certificate") @@ -128,7 +118,7 @@ func TestGenerateSignCertificate(t *testing.T) { rootCA, err := ca.NewCA(caDir, testCA2Name, testCA2Name, testCountry, testProvince, testLocality, testOrganizationalUnit, testStreetAddress, testPostalCode) assert.NoError(t, err, "Error generating CA") - cert, err := rootCA.SignCertificate(certDir, testName, nil, ecPubKey, + cert, err := rootCA.SignCertificate(certDir, testName, nil, nil, ecPubKey, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}) assert.NoError(t, err, "Failed to generate signed certificate") @@ -137,14 +127,21 @@ func TestGenerateSignCertificate(t *testing.T) { cert.KeyUsage) assert.Contains(t, cert.ExtKeyUsage, x509.ExtKeyUsageAny) - cert, err = rootCA.SignCertificate(certDir, testName, nil, ecPubKey, + cert, err = rootCA.SignCertificate(certDir, testName, nil, nil, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) assert.NoError(t, err, "Failed to generate signed certificate") assert.Equal(t, 0, len(cert.ExtKeyUsage)) + // make sure ous are correctly set + ous := []string{"TestOU", "PeerOU"} + cert, err = rootCA.SignCertificate(certDir, testName, ous, nil, ecPubKey, + x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) + assert.Contains(t, cert.Subject.OrganizationalUnit, ous[0]) + assert.Contains(t, cert.Subject.OrganizationalUnit, ous[1]) + // make sure sans are correctly set sans := []string{testName2, testIP} - cert, err = rootCA.SignCertificate(certDir, testName, sans, ecPubKey, + cert, err = rootCA.SignCertificate(certDir, testName, nil, sans, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) assert.Contains(t, cert.DNSNames, testName2) assert.Contains(t, cert.IPAddresses, net.ParseIP(testIP).To4()) @@ -154,7 +151,7 @@ func TestGenerateSignCertificate(t *testing.T) { assert.Equal(t, true, checkForFile(pemFile), "Expected to find file "+pemFile) - _, err = rootCA.SignCertificate(certDir, "empty/CA", nil, ecPubKey, + _, err = rootCA.SignCertificate(certDir, "empty/CA", nil, nil, ecPubKey, x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}) assert.Error(t, err, "Bad name should fail") @@ -163,7 +160,7 @@ func TestGenerateSignCertificate(t *testing.T) { Name: "badCA", SignCert: &x509.Certificate{}, } - _, err = badCA.SignCertificate(certDir, testName, nil, &ecdsa.PublicKey{}, + _, err = badCA.SignCertificate(certDir, testName, nil, nil, &ecdsa.PublicKey{}, x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}) assert.Error(t, err, "Empty CA should not be able to sign") cleanup(testDir) diff --git a/common/tools/cryptogen/ca/generator.go b/common/tools/cryptogen/ca/generator.go index a371d9ba5cc..67b2910b176 100644 --- a/common/tools/cryptogen/ca/generator.go +++ b/common/tools/cryptogen/ca/generator.go @@ -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 ca @@ -103,7 +93,7 @@ func NewCA(baseDir, org, name, country, province, locality, orgUnit, streetAddre // SignCertificate creates a signed certificate based on a built-in template // and saves it in baseDir/name -func (ca *CA) SignCertificate(baseDir, name string, sans []string, pub *ecdsa.PublicKey, +func (ca *CA) SignCertificate(baseDir, name string, ous, sans []string, pub *ecdsa.PublicKey, ku x509.KeyUsage, eku []x509.ExtKeyUsage) (*x509.Certificate, error) { template := x509Template() @@ -114,6 +104,8 @@ func (ca *CA) SignCertificate(baseDir, name string, sans []string, pub *ecdsa.Pu subject := subjectTemplateAdditional(ca.Country, ca.Province, ca.Locality, ca.OrganizationalUnit, ca.StreetAddress, ca.PostalCode) subject.CommonName = name + subject.OrganizationalUnit = append(subject.OrganizationalUnit, ous...) + template.Subject = subject for _, san := range sans { // try to parse as an IP address first diff --git a/common/tools/cryptogen/csp/csp.go b/common/tools/cryptogen/csp/csp.go index 9bb61468401..3d7d76bb028 100644 --- a/common/tools/cryptogen/csp/csp.go +++ b/common/tools/cryptogen/csp/csp.go @@ -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 csp diff --git a/common/tools/cryptogen/csp/csp_test.go b/common/tools/cryptogen/csp/csp_test.go index 1515a5d927b..690154a97dd 100644 --- a/common/tools/cryptogen/csp/csp_test.go +++ b/common/tools/cryptogen/csp/csp_test.go @@ -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 csp_test diff --git a/common/tools/cryptogen/main.go b/common/tools/cryptogen/main.go index fa6aea349b2..4360754965a 100644 --- a/common/tools/cryptogen/main.go +++ b/common/tools/cryptogen/main.go @@ -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 main @@ -75,12 +65,13 @@ type UsersSpec struct { } type OrgSpec struct { - Name string `yaml:"Name"` - Domain string `yaml:"Domain"` - CA NodeSpec `yaml:"CA"` - Template NodeTemplate `yaml:"Template"` - Specs []NodeSpec `yaml:"Specs"` - Users UsersSpec `yaml:"Users"` + Name string `yaml:"Name"` + Domain string `yaml:"Domain"` + EnableNodeOUs bool `yaml:"EnableNodeOUs"` + CA NodeSpec `yaml:"CA"` + Template NodeTemplate `yaml:"Template"` + Specs []NodeSpec `yaml:"Specs"` + Users UsersSpec `yaml:"Users"` } type Config struct { @@ -114,6 +105,7 @@ PeerOrgs: # --------------------------------------------------------------------------- - Name: Org1 Domain: org1.example.com + EnableNodeOUs: false # --------------------------------------------------------------------------- # "CA" @@ -197,6 +189,7 @@ PeerOrgs: # --------------------------------------------------------------------------- - Name: Org2 Domain: org2.example.com + EnableNodeOUs: false Template: Count: 1 Users: @@ -315,7 +308,7 @@ func extendPeerOrg(orgSpec OrgSpec) { signCA := getCA(caDir, orgSpec, orgSpec.CA.CommonName) tlsCA := getCA(tlscaDir, orgSpec, "tls"+orgSpec.CA.CommonName) - generateNodes(peersDir, orgSpec.Specs, signCA, tlsCA, msp.PEER) + generateNodes(peersDir, orgSpec.Specs, signCA, tlsCA, msp.PEER, orgSpec.EnableNodeOUs) adminUser := NodeSpec{ CommonName: fmt.Sprintf("%s@%s", adminBaseName, orgName), @@ -341,7 +334,7 @@ func extendPeerOrg(orgSpec OrgSpec) { users = append(users, user) } - generateNodes(usersDir, users, signCA, tlsCA, msp.CLIENT) + generateNodes(usersDir, users, signCA, tlsCA, msp.CLIENT, orgSpec.EnableNodeOUs) } func extendOrdererOrg(orgSpec OrgSpec) { @@ -360,7 +353,7 @@ func extendOrdererOrg(orgSpec OrgSpec) { signCA := getCA(caDir, orgSpec, orgSpec.CA.CommonName) tlsCA := getCA(tlscaDir, orgSpec, "tls"+orgSpec.CA.CommonName) - generateNodes(orderersDir, orgSpec.Specs, signCA, tlsCA, msp.ORDERER) + generateNodes(orderersDir, orgSpec.Specs, signCA, tlsCA, msp.ORDERER, false) adminUser := NodeSpec{ CommonName: fmt.Sprintf("%s@%s", adminBaseName, orgName), @@ -533,13 +526,13 @@ func generatePeerOrg(baseDir string, orgSpec OrgSpec) { os.Exit(1) } - err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA) + err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA, orgSpec.EnableNodeOUs) if err != nil { fmt.Printf("Error generating MSP for org %s:\n%v\n", orgName, err) os.Exit(1) } - generateNodes(peersDir, orgSpec.Specs, signCA, tlsCA, msp.PEER) + generateNodes(peersDir, orgSpec.Specs, signCA, tlsCA, msp.PEER, orgSpec.EnableNodeOUs) // TODO: add ability to specify usernames users := []NodeSpec{} @@ -556,7 +549,7 @@ func generatePeerOrg(baseDir string, orgSpec OrgSpec) { } users = append(users, adminUser) - generateNodes(usersDir, users, signCA, tlsCA, msp.CLIENT) + generateNodes(usersDir, users, signCA, tlsCA, msp.CLIENT, orgSpec.EnableNodeOUs) // copy the admin cert to the org's MSP admincerts err = copyAdminCert(usersDir, adminCertsDir, adminUser.CommonName) @@ -603,12 +596,12 @@ func copyAdminCert(usersDir, adminCertsDir, adminUserName string) error { } -func generateNodes(baseDir string, nodes []NodeSpec, signCA *ca.CA, tlsCA *ca.CA, nodeType int) { +func generateNodes(baseDir string, nodes []NodeSpec, signCA *ca.CA, tlsCA *ca.CA, nodeType int, nodeOUs bool) { 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) + err := msp.GenerateLocalMSP(nodeDir, node.CommonName, node.SANS, signCA, tlsCA, nodeType, nodeOUs) if err != nil { fmt.Printf("Error generating local MSP for %s:\n%v\n", node, err) os.Exit(1) @@ -642,13 +635,13 @@ func generateOrdererOrg(baseDir string, orgSpec OrgSpec) { os.Exit(1) } - err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA) + err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA, false) if err != nil { fmt.Printf("Error generating MSP for org %s:\n%v\n", orgName, err) os.Exit(1) } - generateNodes(orderersDir, orgSpec.Specs, signCA, tlsCA, msp.ORDERER) + generateNodes(orderersDir, orgSpec.Specs, signCA, tlsCA, msp.ORDERER, false) adminUser := NodeSpec{ CommonName: fmt.Sprintf("%s@%s", adminBaseName, orgName), @@ -658,7 +651,7 @@ func generateOrdererOrg(baseDir string, orgSpec OrgSpec) { users := []NodeSpec{} // add an admin user users = append(users, adminUser) - generateNodes(usersDir, users, signCA, tlsCA, msp.CLIENT) + generateNodes(usersDir, users, signCA, tlsCA, msp.CLIENT, false) // copy the admin cert to the org's MSP admincerts err = copyAdminCert(usersDir, adminCertsDir, adminUser.CommonName) diff --git a/common/tools/cryptogen/msp/generator.go b/common/tools/cryptogen/msp/generator.go index 0af213ea33b..fccb165eeaa 100644 --- a/common/tools/cryptogen/msp/generator.go +++ b/common/tools/cryptogen/msp/generator.go @@ -1,32 +1,24 @@ /* -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 import ( "crypto/x509" + "encoding/hex" "encoding/pem" "os" "path/filepath" - "encoding/hex" + "gopkg.in/yaml.v2" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/factory" "github.com/hyperledger/fabric/common/tools/cryptogen/ca" "github.com/hyperledger/fabric/common/tools/cryptogen/csp" + fabricmsp "github.com/hyperledger/fabric/msp" ) const ( @@ -35,8 +27,18 @@ const ( PEER ) +const ( + CLIENTOU = "FabricClient" + PEEROU = "FabricPeer" +) + +var nodeOUMap = map[int]string{ + CLIENT: CLIENTOU, + PEER: PEEROU, +} + func GenerateLocalMSP(baseDir, name string, sans []string, signCA *ca.CA, - tlsCA *ca.CA, nodeType int) error { + tlsCA *ca.CA, nodeType int, nodeOUs bool) error { // create folder structure mspDir := filepath.Join(baseDir, "msp") @@ -70,8 +72,12 @@ func GenerateLocalMSP(baseDir, name string, sans []string, signCA *ca.CA, return err } // generate X509 certificate using signing CA + var ous []string + if nodeOUs { + ous = []string{nodeOUMap[nodeType]} + } cert, err := signCA.SignCertificate(filepath.Join(mspDir, "signcerts"), - name, []string{}, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) + name, ous, nil, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) if err != nil { return err } @@ -89,6 +95,11 @@ func GenerateLocalMSP(baseDir, name string, sans []string, signCA *ca.CA, return err } + // generate config.yaml if required + if nodeOUs && nodeType == PEER { + exportConfig(mspDir, "cacerts/"+x509Filename(signCA.Name), true) + } + // the signing identity goes into admincerts. // This means that the signing identity // of this MSP is also an admin of this MSP @@ -117,7 +128,7 @@ func GenerateLocalMSP(baseDir, name string, sans []string, signCA *ca.CA, } // generate X509 certificate using TLS CA _, err = tlsCA.SignCertificate(filepath.Join(tlsDir), - name, sans, tlsPubKey, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, + name, nil, sans, tlsPubKey, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}) if err != nil { return err @@ -146,7 +157,7 @@ func GenerateLocalMSP(baseDir, name string, sans []string, signCA *ca.CA, return nil } -func GenerateVerifyingMSP(baseDir string, signCA *ca.CA, tlsCA *ca.CA) error { +func GenerateVerifyingMSP(baseDir string, signCA *ca.CA, tlsCA *ca.CA, nodeOUs bool) error { // create folder structure and write artifacts to proper locations err := createFolderStructure(baseDir, false) @@ -163,6 +174,11 @@ func GenerateVerifyingMSP(baseDir string, signCA *ca.CA, tlsCA *ca.CA) error { } } + // generate config.yaml if required + if nodeOUs { + exportConfig(baseDir, "cacerts/"+x509Filename(signCA.Name), true) + } + // create a throwaway cert to act as an admin cert // NOTE: the admincerts folder is going to be // cleared up anyway by copyAdminCert, but @@ -176,7 +192,7 @@ func GenerateVerifyingMSP(baseDir string, signCA *ca.CA, tlsCA *ca.CA) error { return err } _, err = signCA.SignCertificate(filepath.Join(baseDir, "admincerts"), signCA.Name, - []string{""}, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) + nil, nil, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) if err != nil { return err } @@ -232,3 +248,34 @@ func pemExport(path, pemType string, bytes []byte) error { return pem.Encode(file, &pem.Block{Type: pemType, Bytes: bytes}) } + +func exportConfig(mspDir, caFile string, enable bool) error { + var config = &fabricmsp.Configuration{ + NodeOUs: &fabricmsp.NodeOUs{ + Enable: enable, + ClientOUIdentifier: &fabricmsp.OrganizationalUnitIdentifiersConfiguration{ + Certificate: caFile, + OrganizationalUnitIdentifier: CLIENTOU, + }, + PeerOUIdentifier: &fabricmsp.OrganizationalUnitIdentifiersConfiguration{ + Certificate: caFile, + OrganizationalUnitIdentifier: PEEROU, + }, + }, + } + + configBytes, err := yaml.Marshal(config) + if err != nil { + return err + } + + file, err := os.Create(filepath.Join(mspDir, "config.yaml")) + if err != nil { + return err + } + + defer file.Close() + _, err = file.WriteString(string(configBytes)) + + return err +} diff --git a/common/tools/cryptogen/msp/msp_internal_test.go b/common/tools/cryptogen/msp/msp_internal_test.go new file mode 100644 index 00000000000..03baa452fac --- /dev/null +++ b/common/tools/cryptogen/msp/msp_internal_test.go @@ -0,0 +1,9 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package msp + +var ExportConfig = exportConfig diff --git a/common/tools/cryptogen/msp/msp_test.go b/common/tools/cryptogen/msp/msp_test.go index 6e1f9ed2aec..1e479a8312b 100644 --- a/common/tools/cryptogen/msp/msp_test.go +++ b/common/tools/cryptogen/msp/msp_test.go @@ -1,29 +1,22 @@ /* -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_test import ( + "io/ioutil" "os" "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v2" + "github.com/hyperledger/fabric/common/tools/cryptogen/ca" "github.com/hyperledger/fabric/common/tools/cryptogen/msp" fabricmsp "github.com/hyperledger/fabric/msp" - "github.com/stretchr/testify/assert" ) const ( @@ -44,7 +37,7 @@ func TestGenerateLocalMSP(t *testing.T) { cleanup(testDir) - err := msp.GenerateLocalMSP(testDir, testName, nil, &ca.CA{}, &ca.CA{}, msp.PEER) + err := msp.GenerateLocalMSP(testDir, testName, nil, &ca.CA{}, &ca.CA{}, msp.PEER, true) assert.Error(t, err, "Empty CA should have failed") caDir := filepath.Join(testDir, "ca") @@ -73,7 +66,7 @@ func TestGenerateLocalMSP(t *testing.T) { assert.Equal(t, testPostalCode, signCA.SignCert.Subject.PostalCode[0], "Failed to match postalCode") // generate local MSP for nodeType=PEER - err = msp.GenerateLocalMSP(testDir, testName, nil, signCA, tlsCA, msp.PEER) + err = msp.GenerateLocalMSP(testDir, testName, nil, signCA, tlsCA, msp.PEER, true) assert.NoError(t, err, "Failed to generate local MSP") // check to see that the right files were generated/saved @@ -83,6 +76,7 @@ func TestGenerateLocalMSP(t *testing.T) { filepath.Join(mspDir, "tlscacerts", testCAName+"-cert.pem"), filepath.Join(mspDir, "keystore"), filepath.Join(mspDir, "signcerts", testName+"-cert.pem"), + filepath.Join(mspDir, "config.yaml"), } tlsFiles := []string{ filepath.Join(tlsDir, "ca.crt"), @@ -100,7 +94,7 @@ func TestGenerateLocalMSP(t *testing.T) { } // generate local MSP for nodeType=CLIENT - err = msp.GenerateLocalMSP(testDir, testName, nil, signCA, tlsCA, msp.CLIENT) + err = msp.GenerateLocalMSP(testDir, testName, nil, signCA, tlsCA, msp.CLIENT, true) assert.NoError(t, err, "Failed to generate local MSP") //only need to check for the TLS certs tlsFiles = []string{ @@ -123,10 +117,10 @@ func TestGenerateLocalMSP(t *testing.T) { assert.NoError(t, err, "Error setting up local MSP") tlsCA.Name = "test/fail" - err = msp.GenerateLocalMSP(testDir, testName, nil, signCA, tlsCA, msp.CLIENT) + err = msp.GenerateLocalMSP(testDir, testName, nil, signCA, tlsCA, msp.CLIENT, true) assert.Error(t, err, "Should have failed with CA name 'test/fail'") signCA.Name = "test/fail" - err = msp.GenerateLocalMSP(testDir, testName, nil, signCA, tlsCA, msp.ORDERER) + err = msp.GenerateLocalMSP(testDir, testName, nil, signCA, tlsCA, msp.ORDERER, true) assert.Error(t, err, "Should have failed with CA name 'test/fail'") t.Log(err) cleanup(testDir) @@ -145,7 +139,7 @@ func TestGenerateVerifyingMSP(t *testing.T) { tlsCA, err := ca.NewCA(tlsCADir, testCAOrg, testCAName, testCountry, testProvince, testLocality, testOrganizationalUnit, testStreetAddress, testPostalCode) assert.NoError(t, err, "Error generating CA") - err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA) + err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA, true) assert.NoError(t, err, "Failed to generate verifying MSP") // check to see that the right files were generated/saved @@ -153,6 +147,7 @@ func TestGenerateVerifyingMSP(t *testing.T) { filepath.Join(mspDir, "admincerts", testCAName+"-cert.pem"), filepath.Join(mspDir, "cacerts", testCAName+"-cert.pem"), filepath.Join(mspDir, "tlscacerts", testCAName+"-cert.pem"), + filepath.Join(mspDir, "config.yaml"), } for _, file := range files { @@ -168,15 +163,45 @@ func TestGenerateVerifyingMSP(t *testing.T) { assert.NoError(t, err, "Error setting up verifying MSP") tlsCA.Name = "test/fail" - err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA) + err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA, true) assert.Error(t, err, "Should have failed with CA name 'test/fail'") signCA.Name = "test/fail" - err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA) + err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA, true) assert.Error(t, err, "Should have failed with CA name 'test/fail'") t.Log(err) cleanup(testDir) } +func TestExportConfig(t *testing.T) { + path := filepath.Join(testDir, "export-test") + configFile := filepath.Join(path, "config.yaml") + caFile := "ca.pem" + t.Log(path) + err := os.MkdirAll(path, 0755) + if err != nil { + t.Fatalf("failed to create test directory: [%s]", err) + } + + err = msp.ExportConfig(path, caFile, true) + assert.NoError(t, err) + + configBytes, err := ioutil.ReadFile(configFile) + if err != nil { + t.Fatalf("failed to read config file: [%s]", err) + } + + config := &fabricmsp.Configuration{} + err = yaml.Unmarshal(configBytes, config) + if err != nil { + t.Fatalf("failed to unmarshal config: [%s]", err) + } + assert.True(t, config.NodeOUs.Enable) + assert.Equal(t, caFile, config.NodeOUs.ClientOUIdentifier.Certificate) + assert.Equal(t, msp.CLIENTOU, config.NodeOUs.ClientOUIdentifier.OrganizationalUnitIdentifier) + assert.Equal(t, caFile, config.NodeOUs.PeerOUIdentifier.Certificate) + assert.Equal(t, msp.PEEROU, config.NodeOUs.PeerOUIdentifier.OrganizationalUnitIdentifier) +} + func cleanup(dir string) { os.RemoveAll(dir) }