Skip to content

Commit

Permalink
Revert "Allow BCCSP config to be set using env var (hyperledger#1900)"
Browse files Browse the repository at this point in the history
This reverts commit f2e9e6e.
which pushed the pkcs11 code outside of the pkcs11 build tag.
This prevents cross-compilation of Fabric due to the fact the
miekg/pkcs11 package contains CGO which requires a cross-compiler
for each platform you are cross compiling for.

We need to find a better approach to solving this problem
that doesn't pull the code out of the build tag.

Signed-off-by: Danny Cao <dcao@us.ibm.com>
  • Loading branch information
caod123 committed Nov 10, 2020
1 parent d1b4524 commit ef10053
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 263 deletions.
6 changes: 6 additions & 0 deletions bccsp/factory/nopkcs11.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import (

const pkcs11Enabled = false

// FactoryOpts holds configuration information used to initialize factory implementations
type FactoryOpts struct {
ProviderName string `mapstructure:"default" json:"default" yaml:"Default"`
SwOpts *SwOpts `mapstructure:"SW,omitempty" json:"SW,omitempty" yaml:"SW,omitempty"`
}

// InitFactories must be called before using factory interfaces
// It is acceptable to call with config = nil, in which case
// some defaults will get used
Expand Down
27 changes: 12 additions & 15 deletions bccsp/factory/opts.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
/*
Copyright IBM Corp. All Rights Reserved.
Copyright IBM Corp. 2016 All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
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
package factory
http://www.apache.org/licenses/LICENSE-2.0
import "github.com/hyperledger/fabric/bccsp/pkcs11"
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.
*/

// FactoryOpts holds configuration information used to initialize factory implementations
type FactoryOpts struct {
ProviderName string `mapstructure:"default" json:"default" yaml:"Default"`
SwOpts *SwOpts `mapstructure:"SW,omitempty" json:"SW,omitempty" yaml:"SW,omitempty"`
Pkcs11Opts *pkcs11.PKCS11Opts `mapstructure:"PKCS11,omitempty" json:"PKCS11,omitempty" yaml:"PKCS11"`
}
package factory

// GetDefaultOpts offers a default implementation for Opts
// returns a new instance every time
Expand All @@ -25,10 +26,6 @@ func GetDefaultOpts() *FactoryOpts {
SecLevel: 256,
Ephemeral: true,
},
Pkcs11Opts: &pkcs11.PKCS11Opts{
HashFamily: "SHA2",
SecLevel: 256,
},
}
}

Expand Down
8 changes: 8 additions & 0 deletions bccsp/factory/pkcs11.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,19 @@ package factory

import (
"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/bccsp/pkcs11"
"github.com/pkg/errors"
)

const pkcs11Enabled = false

// FactoryOpts holds configuration information used to initialize factory implementations
type FactoryOpts struct {
ProviderName string `mapstructure:"default" json:"default" yaml:"Default"`
SwOpts *SwOpts `mapstructure:"SW,omitempty" json:"SW,omitempty" yaml:"SW,omitempty"`
Pkcs11Opts *pkcs11.PKCS11Opts `mapstructure:"PKCS11,omitempty" json:"PKCS11,omitempty" yaml:"PKCS11"`
}

// InitFactories must be called before using factory interfaces
// It is acceptable to call with config = nil, in which case
// some defaults will get used
Expand Down
2 changes: 1 addition & 1 deletion common/viperutil/config_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ func bccspHook(f reflect.Type, t reflect.Type, data interface{}) (interface{}, e

err := mapstructure.WeakDecode(data, config)
if err != nil {
return nil, errors.Wrap(err, "could not decode bccsp type")
return nil, errors.Wrap(err, "could not decode bcssp type")
}

return config, nil
Expand Down
6 changes: 0 additions & 6 deletions integration/nwo/core_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,6 @@ peer:
Security: 256
FileKeyStore:
KeyStore:
PKCS11:
Hash: SHA2
Security: 256
Library:
Label:
Pin:
mspConfigPath: {{ .PeerLocalMSPDir Peer }}
localMspId: {{ (.Organization Peer.Organization).MSPID }}
deliveryclient:
Expand Down
6 changes: 0 additions & 6 deletions integration/nwo/orderer_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,6 @@ General:
Security: 256
FileKeyStore:
KeyStore:
PKCS11:
Hash: SHA2
Security: 256
Library:
Label:
Pin:
Authentication:
TimeWindow: 15m
FileLedger:
Expand Down
62 changes: 0 additions & 62 deletions integration/pkcs11/pkcs11_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"github.com/hyperledger/fabric/integration"
"github.com/hyperledger/fabric/integration/nwo"
"github.com/hyperledger/fabric/integration/nwo/commands"
"github.com/hyperledger/fabric/integration/nwo/fabricconfig"
"github.com/miekg/pkcs11"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
Expand All @@ -34,9 +32,6 @@ func TestPKCS11(t *testing.T) {
var (
buildServer *nwo.BuildServer
components *nwo.Components
ctx *pkcs11.Ctx
sess pkcs11.SessionHandle
bccspConfig *fabricconfig.BCCSP
)

var _ = SynchronizedBeforeSuite(func() []byte {
Expand All @@ -46,9 +41,6 @@ var _ = SynchronizedBeforeSuite(func() []byte {
components = buildServer.Components()
payload, err := json.Marshal(components)
Expect(err).NotTo(HaveOccurred())

setupPKCS11()

return payload
}, func(payload []byte) {
err := json.Unmarshal(payload, &components)
Expand All @@ -58,66 +50,12 @@ var _ = SynchronizedBeforeSuite(func() []byte {
var _ = SynchronizedAfterSuite(func() {
}, func() {
buildServer.Shutdown()
ctx.Destroy()
ctx.CloseSession(sess)
})

func StartPort() int {
return integration.PKCS11Port.StartPortForNode()
}

func setupPKCS11() {
lib, pin, label := bpkcs11.FindPKCS11Lib()
ctx, sess = setupPKCS11Ctx(lib, label, pin)
bccspConfig = &fabricconfig.BCCSP{
Default: "PKCS11",
PKCS11: &fabricconfig.PKCS11{
Security: 256,
Hash: "SHA2",
Pin: pin,
Label: label,
Library: lib,
},
}
}

// Creates pkcs11 context and session
func setupPKCS11Ctx(lib, label, pin string) (*pkcs11.Ctx, pkcs11.SessionHandle) {
ctx := pkcs11.New(lib)

err := ctx.Initialize()
Expect(err).NotTo(HaveOccurred())

slot := findPKCS11Slot(ctx, label)
Expect(slot).Should(BeNumerically(">", 0), "Could not find slot with label %s", label)

sess, err := ctx.OpenSession(slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
Expect(err).NotTo(HaveOccurred())

// Login
err = ctx.Login(sess, pkcs11.CKU_USER, pin)
Expect(err).NotTo(HaveOccurred())

return ctx, sess
}

// Identifies pkcs11 slot using specified label
func findPKCS11Slot(ctx *pkcs11.Ctx, label string) uint {
slots, err := ctx.GetSlotList(true)
Expect(err).NotTo(HaveOccurred())

for _, s := range slots {
tokInfo, err := ctx.GetTokenInfo(s)
Expect(err).NotTo(HaveOccurred())

if tokInfo.Label == label {
return s
}
}

return 0
}

func runQueryInvokeQuery(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, channel string) {
By("querying the chaincode")
sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
Expand Down
138 changes: 63 additions & 75 deletions integration/pkcs11/pkcs11_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import (
"math/big"
"os"
"path/filepath"
"strconv"
"syscall"
"time"

bpkcs11 "github.com/hyperledger/fabric/bccsp/pkcs11"
"github.com/hyperledger/fabric/integration/nwo"
"github.com/hyperledger/fabric/integration/nwo/fabricconfig"
"github.com/miekg/pkcs11"
Expand All @@ -50,7 +50,12 @@ var _ = Describe("PKCS11 enabled network", func() {
network.Bootstrap()

By("configuring PKCS11 artifacts")
configurePKCS11(network)
setupPKCS11(network)

By("starting fabric processes")
networkRunner := network.NetworkGroupRunner()
process = ifrit.Invoke(networkRunner)
Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
})

AfterEach(func() {
Expand All @@ -62,14 +67,7 @@ var _ = Describe("PKCS11 enabled network", func() {
os.RemoveAll(tempDir)
})

It("executes transactions against a basic solo network using yaml config", func() {
setPKCS11Config(network, bccspConfig)

By("starting fabric processes")
networkRunner := network.NetworkGroupRunner()
process = ifrit.Invoke(networkRunner)
Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())

It("executes transactions against a basic solo network", func() {
chaincode := nwo.Chaincode{
Name: "mycc",
Version: "0.0",
Expand All @@ -90,44 +88,30 @@ var _ = Describe("PKCS11 enabled network", func() {
nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
runQueryInvokeQuery(network, orderer, network.Peer("Org1", "peer0"), "testchannel")
})
})

It("executes transactions against a basic solo network using environment variable config", func() {
envCleanup := setPKCS11ConfigWithEnvVariables(network, bccspConfig)
defer envCleanup()

By("starting fabric processes")
networkRunner := network.NetworkGroupRunner()
process = ifrit.Invoke(networkRunner)
Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())

chaincode := nwo.Chaincode{
Name: "mycc",
Version: "0.0",
Path: components.Build("github.com/hyperledger/fabric/integration/chaincode/simple/cmd"),
Lang: "binary",
PackageFile: filepath.Join(tempDir, "simplecc.tar.gz"),
Ctor: `{"Args":["init","a","100","b","200"]}`,
SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`,
Sequence: "1",
InitRequired: true,
Label: "my_prebuilt_chaincode",
}

orderer := network.Orderer("orderer")
network.CreateAndJoinChannels(orderer)
func setupPKCS11(network *nwo.Network) {
lib, pin, label := bpkcs11.FindPKCS11Lib()

nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.PeersWithChannel("testchannel")...)
nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
runQueryInvokeQuery(network, orderer, network.Peer("Org1", "peer0"), "testchannel")
})
})
By("establishing a PKCS11 session")
ctx, sess := setupPKCS11Ctx(lib, label, pin)
defer ctx.Destroy()
defer ctx.CloseSession(sess)

func configurePKCS11(network *nwo.Network) {
configurePeerPKCS11(ctx, sess, network)
configureOrdererPKCS11(ctx, sess, network)
}

func setPKCS11Config(network *nwo.Network, bccspConfig *fabricconfig.BCCSP) {
bccspConfig := &fabricconfig.BCCSP{
Default: "PKCS11",
PKCS11: &fabricconfig.PKCS11{
Security: 256,
Hash: "SHA2",
Pin: pin,
Label: label,
Library: lib,
},
}

By("updating bccsp peer config")
for _, peer := range network.Peers {
peerConfig := network.ReadPeerConfig(peer)
Expand All @@ -142,39 +126,6 @@ func setPKCS11Config(network *nwo.Network, bccspConfig *fabricconfig.BCCSP) {
network.WriteOrdererConfig(orderer, ordererConfig)
}

func setPKCS11ConfigWithEnvVariables(network *nwo.Network, bccspConfig *fabricconfig.BCCSP) (cleanup func()) {
By("setting bccsp peer config via environment variables")
os.Setenv("CORE_PEER_BCCSP_DEFAULT", bccspConfig.Default)
os.Setenv("CORE_PEER_BCCSP_PKCS11_SECURITY", strconv.Itoa(bccspConfig.PKCS11.Security))
os.Setenv("CORE_PEER_BCCSP_PKCS11_HASH", bccspConfig.PKCS11.Hash)
os.Setenv("CORE_PEER_BCCSP_PKCS11_PIN", bccspConfig.PKCS11.Pin)
os.Setenv("CORE_PEER_BCCSP_PKCS11_LABEL", bccspConfig.PKCS11.Label)
os.Setenv("CORE_PEER_BCCSP_PKCS11_LIBRARY", bccspConfig.PKCS11.Library)

By("setting bccsp orderer config via environment variables")
os.Setenv("ORDERER_GENERAL_BCCSP_DEFAULT", bccspConfig.Default)
os.Setenv("ORDERER_GENERAL_BCCSP_PKCS11_SECURITY", strconv.Itoa(bccspConfig.PKCS11.Security))
os.Setenv("ORDERER_GENERAL_BCCSP_PKCS11_HASH", bccspConfig.PKCS11.Hash)
os.Setenv("ORDERER_GENERAL_BCCSP_PKCS11_PIN", bccspConfig.PKCS11.Pin)
os.Setenv("ORDERER_GENERAL_BCCSP_PKCS11_LABEL", bccspConfig.PKCS11.Label)
os.Setenv("ORDERER_GENERAL_BCCSP_PKCS11_LIBRARY", bccspConfig.PKCS11.Library)

return func() {
os.Unsetenv("CORE_PEER_BCCSP_DEFAULT")
os.Unsetenv("CORE_PEER_BCCSP_PKCS11_SECURITY")
os.Unsetenv("CORE_PEER_BCCSP_PKCS11_HASH")
os.Unsetenv("CORE_PEER_BCCSP_PKCS11_PIN")
os.Unsetenv("CORE_PEER_BCCSP_PKCS11_LABEL")
os.Unsetenv("CORE_PEER_BCCSP_PKCS11_LIBRARY")
os.Unsetenv("ORDERER_GENERAL_BCCSP_DEFAULT")
os.Unsetenv("ORDERER_GENERAL_BCCSP_PKCS11_SECURITY")
os.Unsetenv("ORDERER_GENERAL_BCCSP_PKCS11_HASH")
os.Unsetenv("ORDERER_GENERAL_BCCSP_PKCS11_PIN")
os.Unsetenv("ORDERER_GENERAL_BCCSP_PKCS11_LABEL")
os.Unsetenv("ORDERER_GENERAL_BCCSP_PKCS11_LIBRARY")
}
}

func configurePeerPKCS11(ctx *pkcs11.Ctx, sess pkcs11.SessionHandle, network *nwo.Network) {
for _, peer := range network.Peers {
orgName := peer.Organization
Expand Down Expand Up @@ -229,6 +180,43 @@ func configureOrdererPKCS11(ctx *pkcs11.Ctx, sess pkcs11.SessionHandle, network
updateMSPFolder(orgAdminMSPPath, fmt.Sprintf("Admin@%s-cert.pem", domain), newAdminPemCert)
}

// Creates pkcs11 context and session
func setupPKCS11Ctx(lib, label, pin string) (*pkcs11.Ctx, pkcs11.SessionHandle) {
ctx := pkcs11.New(lib)

err := ctx.Initialize()
Expect(err).NotTo(HaveOccurred())

slot := findPKCS11Slot(ctx, label)
Expect(slot).Should(BeNumerically(">", 0), "Could not find slot with label %s", label)

sess, err := ctx.OpenSession(slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
Expect(err).NotTo(HaveOccurred())

// Login
err = ctx.Login(sess, pkcs11.CKU_USER, pin)
Expect(err).NotTo(HaveOccurred())

return ctx, sess
}

// Identifies pkcs11 slot using specified label
func findPKCS11Slot(ctx *pkcs11.Ctx, label string) uint {
slots, err := ctx.GetSlotList(true)
Expect(err).NotTo(HaveOccurred())

for _, s := range slots {
tokInfo, err := ctx.GetTokenInfo(s)
Expect(err).NotTo(HaveOccurred())

if tokInfo.Label == label {
return s
}
}

return 0
}

// Creates CSR for provided organization and organizational unit
func createCSR(ctx *pkcs11.Ctx, sess pkcs11.SessionHandle, org, ou string) (*ecdsa.PublicKey, *x509.CertificateRequest, *big.Int) {
pubKey, pkcs11Key := generateKeyPair(ctx, sess)
Expand Down
Loading

0 comments on commit ef10053

Please sign in to comment.