Skip to content

Commit

Permalink
[FAB-7576] Conditional PKCS11 support
Browse files Browse the repository at this point in the history
This patch includes PKCS11 support as an option. This change
enables usage of the SDK when libltdl is not installed.

Change-Id: Id2cbbba5837eb8cdcac6e4f42ad64166e11d8eb4
Signed-off-by: Troy Ronda <troy@troyronda.com>
  • Loading branch information
troyronda committed Jan 2, 2018
1 parent 035e4f9 commit 65c26f4
Show file tree
Hide file tree
Showing 14 changed files with 240 additions and 82 deletions.
17 changes: 11 additions & 6 deletions Makefile
Expand Up @@ -41,6 +41,7 @@ FABRIC_DEVSTABLE_VERSION_MAJOR := 1
GO_LDFLAGS ?= -s
GO_TESTFLAGS ?=
FABRIC_SDK_EXPERIMENTAL ?= true
FABRIC_SDK_PKCS11 ?= false
FABRIC_SDK_EXTRA_GO_TAGS ?=
FABRIC_SDK_POPULATE_VENDOR ?= true

Expand Down Expand Up @@ -127,12 +128,6 @@ GO_DEP_COMMIT := v0.3.1
# The version of mockgen that will be installed by depend-install
GO_MOCKGEN_COMMIT := v1.0.0

# Setup Go Tags
GO_TAGS := $(FABRIC_SDK_EXTRA_GO_TAGS)
ifeq ($(FABRIC_SDK_EXPERIMENTAL),true)
GO_TAGS += experimental
endif

# Detect CI
# TODO introduce nightly and adjust verify
ifdef JENKINS_URL
Expand All @@ -143,6 +138,16 @@ FABRIC_STABLE_PKCS11_INTTEST := true
FABRIC_PREV_INTTEST := true
FABRIC_PRERELEASE_INTTEST := true
FABRIC_DEVSTABLE_INTTEST := true
FABRIC_SDK_PKCS11 := true
endif

# Setup Go Tags
GO_TAGS := $(FABRIC_SDK_EXTRA_GO_TAGS)
ifeq ($(FABRIC_SDK_EXPERIMENTAL),true)
GO_TAGS += experimental
endif
ifeq ($(FABRIC_SDK_PKCS11),true)
GO_TAGS += pkcs11
endif

# Detect subtarget execution
Expand Down
5 changes: 5 additions & 0 deletions README.md
Expand Up @@ -66,6 +66,11 @@ make
make clean
```

### Go Tags
The following Go tags can be supplied to enable additional functionality:
- pkcs11: includes support for configuring BCCSP with PKCS11 provider. Note: libltdl must be installed.
- experimental: includes support for experimental features.

## Contributing to the Go SDK

If you want to contribute to the Go SDK, please run the test suite and submit patches to the Gerrit git repostory for review. For general guidelines, please refer to the Fabric project's [contribution page](http://hyperledger-fabric.readthedocs.io/en/latest/CONTRIBUTING.html).
Expand Down
@@ -1,4 +1,4 @@
// +build nopkcs11
// +build !pkcs11

/*
Copyright IBM Corp. 2017 All Rights Reserved.
Expand Down
@@ -1,4 +1,4 @@
// +build !nopkcs11
// +build pkcs11

/*
Copyright IBM Corp. 2017 All Rights Reserved.
Expand Down
@@ -1,4 +1,4 @@
// +build !nopkcs11
// +build pkcs11

/*
Copyright IBM Corp. 2016 All Rights Reserved.
Expand Down
48 changes: 0 additions & 48 deletions pkg/cryptosuite/bccsp/cryptosuiteimpl.go
Expand Up @@ -7,15 +7,12 @@ SPDX-License-Identifier: Apache-2.0
package bccsp

import (
"fmt"

"hash"

"github.com/hyperledger/fabric-sdk-go/api/apiconfig"
"github.com/hyperledger/fabric-sdk-go/api/apicryptosuite"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp"
bccspFactory "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/factory"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/pkcs11"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
)

Expand All @@ -37,51 +34,6 @@ func GetSuiteByConfig(config apiconfig.Config) (apicryptosuite.CryptoSuite, erro
return &cryptoSuite{bccsp}, nil
}

//GetOptsByConfig Returns Factory opts for given SDK config
func GetOptsByConfig(c apiconfig.Config) *bccspFactory.FactoryOpts {
var opts *bccspFactory.FactoryOpts

switch c.SecurityProvider() {
case "SW":
opts = &bccspFactory.FactoryOpts{
ProviderName: "SW",
SwOpts: &bccspFactory.SwOpts{
HashFamily: c.SecurityAlgorithm(),
SecLevel: c.SecurityLevel(),
FileKeystore: &bccspFactory.FileKeystoreOpts{
KeyStorePath: c.KeyStorePath(),
},
Ephemeral: c.Ephemeral(),
},
}
logger.Debug("Initialized SW ")
bccspFactory.InitFactories(opts)
return opts

case "PKCS11":
pkks := pkcs11.FileKeystoreOpts{KeyStorePath: c.KeyStorePath()}
opts = &bccspFactory.FactoryOpts{
ProviderName: "PKCS11",
Pkcs11Opts: &pkcs11.PKCS11Opts{
SecLevel: c.SecurityLevel(),
HashFamily: c.SecurityAlgorithm(),
Ephemeral: c.Ephemeral(),
FileKeystore: &pkks,
Library: c.SecurityProviderLibPath(),
Pin: c.SecurityProviderPin(),
Label: c.SecurityProviderLabel(),
SoftVerify: c.SoftVerify(),
},
}
logger.Debug("Initialized PKCS11 ")
bccspFactory.InitFactories(opts)
return opts
default:
panic(fmt.Sprintf("Unsupported BCCSP Provider: %s", c.SecurityProvider()))

}
}

//GetKey returns implementation of of cryptosuite.Key
func GetKey(newkey bccsp.Key) apicryptosuite.Key {
return &key{newkey}
Expand Down
24 changes: 0 additions & 24 deletions pkg/cryptosuite/bccsp/cryptosuiteimpl_test.go
Expand Up @@ -67,30 +67,6 @@ func TestCryptoSuiteByConfig(t *testing.T) {

}

func TestCryptoSuiteByConfigPKCS11Failure(t *testing.T) {

//Prepare Config
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
//Prepare Config
mockConfig := mock_apiconfig.NewMockConfig(mockCtrl)
mockConfig.EXPECT().SecurityProvider().Return("PKCS11")
mockConfig.EXPECT().SecurityAlgorithm().Return("SHA2")
mockConfig.EXPECT().SecurityLevel().Return(256)
mockConfig.EXPECT().KeyStorePath().Return("/tmp/msp")
mockConfig.EXPECT().Ephemeral().Return(false)
mockConfig.EXPECT().SecurityProviderLibPath().Return("")
mockConfig.EXPECT().SecurityProviderLabel().Return("")
mockConfig.EXPECT().SecurityProviderPin().Return("")
mockConfig.EXPECT().SoftVerify().Return(true)

//Get cryptosuite using config
samplecryptoSuite, err := GetSuiteByConfig(mockConfig)
utils.VerifyNotEmpty(t, err, "Supposed to get error on GetSuiteByConfig call : %s", err)
utils.VerifyEmpty(t, samplecryptoSuite, "Not supposed to get valid cryptosuite")

}

func TestCryptoSuiteByConfigFailures(t *testing.T) {

//Prepare Config
Expand Down
42 changes: 42 additions & 0 deletions pkg/cryptosuite/bccsp/nopkcs11.go
@@ -0,0 +1,42 @@
// +build !pkcs11

/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package bccsp

import (
"fmt"

"github.com/hyperledger/fabric-sdk-go/api/apiconfig"
bccspFactory "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/factory"
)

//GetOptsByConfig Returns Factory opts for given SDK config
func GetOptsByConfig(c apiconfig.Config) *bccspFactory.FactoryOpts {
var opts *bccspFactory.FactoryOpts

switch c.SecurityProvider() {
case "SW":
opts = &bccspFactory.FactoryOpts{
ProviderName: "SW",
SwOpts: &bccspFactory.SwOpts{
HashFamily: c.SecurityAlgorithm(),
SecLevel: c.SecurityLevel(),
FileKeystore: &bccspFactory.FileKeystoreOpts{
KeyStorePath: c.KeyStorePath(),
},
Ephemeral: c.Ephemeral(),
},
}
logger.Debug("Initialized SW ")
bccspFactory.InitFactories(opts)
return opts

default:
panic(fmt.Sprintf("Unsupported BCCSP Provider: %s", c.SecurityProvider()))
}
}
36 changes: 36 additions & 0 deletions pkg/cryptosuite/bccsp/nopkcs11_test.go
@@ -0,0 +1,36 @@
// +build !pkcs11

/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package bccsp

import (
"testing"

"github.com/golang/mock/gomock"
"github.com/hyperledger/fabric-sdk-go/api/apiconfig/mocks"
)

func TestCryptoSuiteByConfigPKCS11Unsupported(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("was supposed to panic")
}
}()

//Prepare Config
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
//Prepare Config
mockConfig := mock_apiconfig.NewMockConfig(mockCtrl)
mockConfig.EXPECT().SecurityProvider().Return("PKCS11")
mockConfig.EXPECT().SecurityProvider().Return("PKCS11")

//Get cryptosuite using config
GetSuiteByConfig(mockConfig)
t.Fatalf("Getting cryptosuite with unsupported pkcs11 security provider supposed to panic")
}
62 changes: 62 additions & 0 deletions pkg/cryptosuite/bccsp/pkcs11.go
@@ -0,0 +1,62 @@
// +build pkcs11

/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package bccsp

import (
"fmt"

"github.com/hyperledger/fabric-sdk-go/api/apiconfig"
bccspFactory "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/factory"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/pkcs11"
)

//GetOptsByConfig Returns Factory opts for given SDK config
func GetOptsByConfig(c apiconfig.Config) *bccspFactory.FactoryOpts {
var opts *bccspFactory.FactoryOpts

switch c.SecurityProvider() {
case "SW":
opts = &bccspFactory.FactoryOpts{
ProviderName: "SW",
SwOpts: &bccspFactory.SwOpts{
HashFamily: c.SecurityAlgorithm(),
SecLevel: c.SecurityLevel(),
FileKeystore: &bccspFactory.FileKeystoreOpts{
KeyStorePath: c.KeyStorePath(),
},
Ephemeral: c.Ephemeral(),
},
}
logger.Debug("Initialized SW ")
bccspFactory.InitFactories(opts)
return opts

case "PKCS11":
pkks := pkcs11.FileKeystoreOpts{KeyStorePath: c.KeyStorePath()}
opts = &bccspFactory.FactoryOpts{
ProviderName: "PKCS11",
Pkcs11Opts: &pkcs11.PKCS11Opts{
SecLevel: c.SecurityLevel(),
HashFamily: c.SecurityAlgorithm(),
Ephemeral: c.Ephemeral(),
FileKeystore: &pkks,
Library: c.SecurityProviderLibPath(),
Pin: c.SecurityProviderPin(),
Label: c.SecurityProviderLabel(),
SoftVerify: c.SoftVerify(),
},
}
logger.Debug("Initialized PKCS11 ")
bccspFactory.InitFactories(opts)
return opts
default:
panic(fmt.Sprintf("Unsupported BCCSP Provider: %s", c.SecurityProvider()))

}
}
40 changes: 40 additions & 0 deletions pkg/cryptosuite/bccsp/pkcs11_test.go
@@ -0,0 +1,40 @@
// +build pkcs11

/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package bccsp

import (
"testing"

"github.com/golang/mock/gomock"
"github.com/hyperledger/fabric-sdk-go/api/apiconfig/mocks"
"github.com/hyperledger/fabric-sdk-go/pkg/logging/utils"
)

func TestCryptoSuiteByConfigPKCS11Failure(t *testing.T) {

//Prepare Config
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
//Prepare Config
mockConfig := mock_apiconfig.NewMockConfig(mockCtrl)
mockConfig.EXPECT().SecurityProvider().Return("PKCS11")
mockConfig.EXPECT().SecurityAlgorithm().Return("SHA2")
mockConfig.EXPECT().SecurityLevel().Return(256)
mockConfig.EXPECT().KeyStorePath().Return("/tmp/msp")
mockConfig.EXPECT().Ephemeral().Return(false)
mockConfig.EXPECT().SecurityProviderLibPath().Return("")
mockConfig.EXPECT().SecurityProviderLabel().Return("")
mockConfig.EXPECT().SecurityProviderPin().Return("")
mockConfig.EXPECT().SoftVerify().Return(true)

//Get cryptosuite using config
samplecryptoSuite, err := GetSuiteByConfig(mockConfig)
utils.VerifyNotEmpty(t, err, "Supposed to get error on GetSuiteByConfig call : %s", err)
utils.VerifyEmpty(t, samplecryptoSuite, "Not supposed to get valid cryptosuite")
}
10 changes: 10 additions & 0 deletions scripts/third_party_pins/fabric/apply_fabric_client_utils.sh
Expand Up @@ -316,6 +316,16 @@ FILTER_FILENAME="msp/mgmt/mgmt.go"
FILTER_FN="GetLocalMSP"
gofilter

# adjust bccsp pkcs11 build tags
FILTER_FILENAME="bccsp/factory/pkcs11factory.go"
sed -i'' -e 's/\+build !nopkcs11/\+build pkcs11/g' "${TMP_PROJECT_PATH}/${FILTER_FILENAME}"

FILTER_FILENAME="bccsp/factory/pkcs11.go"
sed -i'' -e 's/\+build !nopkcs11/\+build pkcs11/g' "${TMP_PROJECT_PATH}/${FILTER_FILENAME}"

FILTER_FILENAME="bccsp/factory/nopkcs11.go"
sed -i'' -e 's/\+build nopkcs11/\+build !pkcs11/g' "${TMP_PROJECT_PATH}/${FILTER_FILENAME}"

echo "Filtering Go sources for allowed declarations ..."
FILTERS_ENABLED="gen,type"
FILTER_TYPE="IMPORT,CONST"
Expand Down

0 comments on commit 65c26f4

Please sign in to comment.