Skip to content

Commit

Permalink
[FAB-6983] bccsp import refactoring
Browse files Browse the repository at this point in the history
Change highlights:
 - Internal bccsp is not directly referred
 anywhere in SDK including internal fabric-ca.
 - All bccsp call is going through cryptosuitebridge
 - Internal bccsp is still referred in some mocks and
 integration-test for testdata.


Change-Id: I267361869ace224842ebf3ebeffad551aed6c0ef
Signed-off-by: Sudesh Shetty <[email protected]>
  • Loading branch information
sudeshrshetty committed Nov 22, 2017
1 parent e9fa53a commit 26b3d2e
Show file tree
Hide file tree
Showing 29 changed files with 886 additions and 183 deletions.
13 changes: 12 additions & 1 deletion api/apicryptosuite/cryptosuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ CryptoSuite interface defined in this file acts as a wrapper for

package apicryptosuite

import "crypto"
import (
"crypto"
"hash"
)

//CryptoSuite adaptor for all bccsp functionalities used by SDK
type CryptoSuite interface {
Expand All @@ -43,13 +46,21 @@ type CryptoSuite interface {
// If opts is nil, the default hash function will be used.
Hash(msg []byte, opts HashOpts) (hash []byte, err error)

// GetHash returns and instance of hash.Hash using options opts.
// If opts is nil, the default hash function will be returned.
GetHash(opts HashOpts) (h hash.Hash, err error)

// Sign signs digest using key k.
// The opts argument should be appropriate for the algorithm used.
//
// Note that when a signature of a hash of a larger message is needed,
// the caller is responsible for hashing the larger message and passing
// the hash (as digest).
Sign(k Key, digest []byte, opts SignerOpts) (signature []byte, err error)

// Verify verifies signature against key k and digest
// The opts argument should be appropriate for the algorithm used.
Verify(k Key, signature, digest []byte, opts SignerOpts) (valid bool, err error)
}

// Key represents a cryptographic key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ package lib
import (
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/api"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/lib/tls"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/factory"
factory "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/sdkpatch/cryptosuitebridge"
)

// ClientConfig is the fabric-ca client's config
Expand Down
6 changes: 2 additions & 4 deletions internal/github.com/hyperledger/fabric-ca/lib/tls/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@ import (
"time"

"github.com/hyperledger/fabric-sdk-go/api/apicryptosuite"
cryptosuite "github.com/hyperledger/fabric-sdk-go/pkg/cryptosuite/bccsp"

"github.com/hyperledger/fabric-sdk-go/pkg/errors"

factory "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/sdkpatch/cryptosuitebridge"
log "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/sdkpatch/logbridge"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/util"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/factory"
)

// ServerTLSConfig defines key material for a TLS server
Expand Down Expand Up @@ -68,7 +66,7 @@ func GetClientTLSConfig(cfg *ClientTLSConfig, csp apicryptosuite.CryptoSuite) (*
var certs []tls.Certificate

if csp == nil {
csp = cryptosuite.GetSuite(factory.GetDefault())
csp = factory.GetDefault()
}

log.Debugf("CA Files: %+v\n", cfg.CertFiles)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
/*
Notice: This file has been modified for Hyperledger Fabric SDK Go usage.
Please review third_party pinning scripts and patches for more details.
*/

package cryptosuitebridge

import (
"crypto"
"crypto/ecdsa"

"github.com/hyperledger/fabric-sdk-go/api/apicryptosuite"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/factory"
cspsigner "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/signer"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/sw"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/utils"
cryptosuite "github.com/hyperledger/fabric-sdk-go/pkg/cryptosuite/bccsp"
)

const (
ECDSA = bccsp.ECDSA
ECDSAP256 = bccsp.ECDSAP256
ECDSAP384 = bccsp.ECDSAP384
ECDSAReRand = bccsp.ECDSAReRand
RSA = bccsp.RSA
RSA1024 = bccsp.RSA1024
RSA2048 = bccsp.RSA2048
RSA3072 = bccsp.RSA3072
RSA4096 = bccsp.RSA4096
AES = bccsp.AES
AES128 = bccsp.AES128
AES192 = bccsp.AES192
AES256 = bccsp.AES256
HMAC = bccsp.HMAC
HMACTruncated256 = bccsp.HMACTruncated256
SHA = bccsp.SHA
SHA2 = bccsp.SHA2
SHA3 = bccsp.SHA3
SHA256 = bccsp.SHA256
SHA384 = bccsp.SHA384
SHA3_256 = bccsp.SHA3_256
SHA3_384 = bccsp.SHA3_384
X509Certificate = bccsp.X509Certificate
)

// FactoryOpts holds configuration information used to initialize bccsp factory implementations
type FactoryOpts struct {
*factory.FactoryOpts
}

//GetBCCSPFromOpts is a bridge for factory.GetBCCSPFromOpts(config)
func GetBCCSPFromOpts(config *FactoryOpts) (apicryptosuite.CryptoSuite, error) {
bccsp, err := factory.GetBCCSPFromOpts(getFactoryOpts(config))
if err != nil {
return nil, err
}
return cryptosuite.GetSuite(bccsp), nil
}

//InitFactories is a bridge for bccsp factory.InitFactories(config)
func InitFactories(config *FactoryOpts) error {
return factory.InitFactories(getFactoryOpts(config))
}

// PEMtoPrivateKey is a bridge for bccsp utils.PEMtoPrivateKey()
func PEMtoPrivateKey(raw []byte, pwd []byte) (interface{}, error) {
return utils.PEMtoPrivateKey(raw, pwd)
}

// PrivateKeyToDER marshals is bridge for utils.PrivateKeyToDER
func PrivateKeyToDER(privateKey *ecdsa.PrivateKey) ([]byte, error) {
return utils.PrivateKeyToDER(privateKey)
}

// NewCspsigner is a bridge for bccsp signer.New call
func NewCspsigner(csp apicryptosuite.CryptoSuite, key apicryptosuite.Key) (crypto.Signer, error) {
return cspsigner.New(csp, key)
}

//NewEmptySwOpts creates new empty bccsp factory.SwOpts
func NewSwOpts() *factory.SwOpts {
return &factory.SwOpts{}
}

//NewEmptyFileKeystoreOpts creates new empty bccsp factory.FileKeystoreOpts
func NewFileKeystoreOpts() *factory.FileKeystoreOpts {
return &factory.FileKeystoreOpts{}
}

//GetFactoryDefaultCryptoSuite creates new cryptosuite from bccsp factory default
func GetDefault() apicryptosuite.CryptoSuite {
return cryptosuite.GetSuite(factory.GetDefault())
}

//SignatureToLowS is a bridge for bccsp sw.SignatureToLowS()
func SignatureToLowS(k *ecdsa.PublicKey, signature []byte) ([]byte, error) {
return sw.SignatureToLowS(k, signature)
}

//GetHashOpt is a bridge for bccsp util GetHashOpt
func GetHashOpt(hashFunction string) (apicryptosuite.HashOpts, error) {
return bccsp.GetHashOpt(hashFunction)
}

func getFactoryOpts(config *FactoryOpts) *factory.FactoryOpts {
if config == nil {
return nil
}
return &factory.FactoryOpts{
SwOpts: config.SwOpts,
ProviderName: config.ProviderName,
Pkcs11Opts: config.Pkcs11Opts,
PluginOpts: config.PluginOpts,
}
}

//GetSHAOpts returns options for computing SHA.
func GetSHAOpts() apicryptosuite.HashOpts {
return &bccsp.SHAOpts{}
}

//GetSHA256Opts returns options relating to SHA-256.
func GetSHA256Opts() apicryptosuite.HashOpts {
return &bccsp.SHA256Opts{}
}

//GetRSA2048KeyGenOpts returns options for RSA key generation at 2048 security.
func GetRSA2048KeyGenOpts(ephemeral bool) apicryptosuite.KeyGenOpts {
return &bccsp.RSA2048KeyGenOpts{Temporary: ephemeral}
}

//GetRSA3072KeyGenOpts returns options for RSA key generation at 3072 security.
func GetRSA3072KeyGenOpts(ephemeral bool) apicryptosuite.KeyGenOpts {
return &bccsp.RSA3072KeyGenOpts{Temporary: ephemeral}
}

//GetRSA4096KeyGenOpts returns options for RSA key generation at 4096 security.
func GetRSA4096KeyGenOpts(ephemeral bool) apicryptosuite.KeyGenOpts {
return &bccsp.RSA4096KeyGenOpts{Temporary: ephemeral}
}

// GetECDSAKeyGenOpts returns options for ECDSA key generation.
func GetECDSAKeyGenOpts(ephemeral bool) apicryptosuite.KeyGenOpts {
return &bccsp.ECDSAKeyGenOpts{Temporary: ephemeral}
}

//GetECDSAP256KeyGenOpts returns options for ECDSA key generation with curve P-256.
func GetECDSAP256KeyGenOpts(ephemeral bool) apicryptosuite.KeyGenOpts {
return &bccsp.ECDSAP256KeyGenOpts{Temporary: ephemeral}
}

//GetECDSAP384KeyGenOpts options for ECDSA key generation with curve P-384.
func GetECDSAP384KeyGenOpts(ephemeral bool) apicryptosuite.KeyGenOpts {
return &bccsp.ECDSAP384KeyGenOpts{Temporary: ephemeral}
}

//GetX509PublicKeyImportOpts options for importing public keys from an x509 certificate
func GetX509PublicKeyImportOpts(ephemeral bool) apicryptosuite.KeyImportOpts {
return &bccsp.X509PublicKeyImportOpts{Temporary: ephemeral}
}

//GetECDSAPrivateKeyImportOpts options for ECDSA secret key importation in DER format
// or PKCS#8 format.
func GetECDSAPrivateKeyImportOpts(ephemeral bool) apicryptosuite.KeyImportOpts {
return &bccsp.ECDSAPrivateKeyImportOpts{Temporary: ephemeral}
}
36 changes: 16 additions & 20 deletions internal/github.com/hyperledger/fabric-ca/util/csp.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,8 @@ import (

"github.com/cloudflare/cfssl/csr"
"github.com/cloudflare/cfssl/helpers"
factory "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/sdkpatch/cryptosuitebridge"
log "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/sdkpatch/logbridge"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/factory"
cspsigner "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/signer"
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/utils"
cryptosuite "github.com/hyperledger/fabric-sdk-go/pkg/cryptosuite/bccsp"
)

// InitBCCSP initializes BCCSP
Expand Down Expand Up @@ -73,7 +69,7 @@ func ConfigureBCCSP(optsPtr **factory.FactoryOpts, mspDir, homeDir string) error
}
if strings.ToUpper(opts.ProviderName) == "SW" {
if opts.SwOpts == nil {
opts.SwOpts = &factory.SwOpts{}
opts.SwOpts = factory.NewSwOpts()
}
if opts.SwOpts.HashFamily == "" {
opts.SwOpts.HashFamily = "SHA2"
Expand All @@ -82,7 +78,7 @@ func ConfigureBCCSP(optsPtr **factory.FactoryOpts, mspDir, homeDir string) error
opts.SwOpts.SecLevel = 256
}
if opts.SwOpts.FileKeystore == nil {
opts.SwOpts.FileKeystore = &factory.FileKeystoreOpts{}
opts.SwOpts.FileKeystore = factory.NewFileKeystoreOpts()
}
// The mspDir overrides the KeyStorePath; otherwise, if not set, set default
if mspDir != "" {
Expand Down Expand Up @@ -119,7 +115,7 @@ func GetBCCSP(opts *factory.FactoryOpts, homeDir string) (apicryptosuite.CryptoS
if err != nil {
return nil, errors.WithMessage(err, "Failed to get BCCSP with opts")
}
return cryptosuite.GetSuite(csp), nil
return csp, nil
}

// makeFileNamesAbsolute makes all relative file names associated with CSP absolute,
Expand All @@ -137,28 +133,28 @@ func makeFileNamesAbsolute(opts *factory.FactoryOpts, homeDir string) error {
// This supports ECDSA and RSA.
func getBCCSPKeyOpts(kr csr.KeyRequest, ephemeral bool) (opts apicryptosuite.KeyGenOpts, err error) {
if kr == nil {
return &bccsp.ECDSAKeyGenOpts{Temporary: ephemeral}, nil
return factory.GetECDSAKeyGenOpts(ephemeral), nil
}
log.Debugf("generate key from request: algo=%s, size=%d", kr.Algo(), kr.Size())
switch kr.Algo() {
case "rsa":
switch kr.Size() {
case 2048:
return &bccsp.RSA2048KeyGenOpts{Temporary: ephemeral}, nil
return factory.GetRSA2048KeyGenOpts(ephemeral), nil
case 3072:
return &bccsp.RSA3072KeyGenOpts{Temporary: ephemeral}, nil
return factory.GetRSA3072KeyGenOpts(ephemeral), nil
case 4096:
return &bccsp.RSA4096KeyGenOpts{Temporary: ephemeral}, nil
return factory.GetRSA4096KeyGenOpts(ephemeral), nil
default:
// Need to add a way to specify arbitrary RSA key size to bccsp
return nil, errors.Errorf("Invalid RSA key size: %d", kr.Size())
}
case "ecdsa":
switch kr.Size() {
case 256:
return &bccsp.ECDSAP256KeyGenOpts{Temporary: ephemeral}, nil
return factory.GetECDSAP256KeyGenOpts(ephemeral), nil
case 384:
return &bccsp.ECDSAP384KeyGenOpts{Temporary: ephemeral}, nil
return factory.GetECDSAP384KeyGenOpts(ephemeral), nil
case 521:
// Need to add curve P521 to bccsp
// return &bccsp.ECDSAP512KeyGenOpts{Temporary: false}, nil
Expand All @@ -177,7 +173,7 @@ func GetSignerFromCert(cert *x509.Certificate, csp apicryptosuite.CryptoSuite) (
return nil, nil, errors.New("CSP was not initialized")
}
// get the public key in the right format
certPubK, err := csp.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: true})
certPubK, err := csp.KeyImport(cert, factory.GetX509PublicKeyImportOpts(true))
if err != nil {
return nil, nil, errors.WithMessage(err, "Failed to import certificate's public key")
}
Expand All @@ -187,7 +183,7 @@ func GetSignerFromCert(cert *x509.Certificate, csp apicryptosuite.CryptoSuite) (
return nil, nil, errors.WithMessage(err, "Could not find matching private key for SKI")
}
// Construct and initialize the signer
signer, err := cspsigner.New(csp, privateKey)
signer, err := factory.NewCspsigner(csp, privateKey)
if err != nil {
return nil, nil, errors.WithMessage(err, "Failed to load ski from bccsp")
}
Expand Down Expand Up @@ -224,7 +220,7 @@ func BCCSPKeyRequestGenerate(req *csr.CertificateRequest, myCSP apicryptosuite.C
return nil, nil, err
}

cspSigner, err := cspsigner.New(myCSP, key)
cspSigner, err := factory.NewCspsigner(myCSP, key)
if err != nil {
return nil, nil, errors.WithMessage(err, "Failed initializing CryptoSigner")
}
Expand All @@ -237,17 +233,17 @@ func ImportBCCSPKeyFromPEM(keyFile string, myCSP apicryptosuite.CryptoSuite, tem
if err != nil {
return nil, err
}
key, err := utils.PEMtoPrivateKey(keyBuff, nil)
key, err := factory.PEMtoPrivateKey(keyBuff, nil)
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("Failed parsing private key from %s", keyFile))
}
switch key.(type) {
case *ecdsa.PrivateKey:
priv, err := utils.PrivateKeyToDER(key.(*ecdsa.PrivateKey))
priv, err := factory.PrivateKeyToDER(key.(*ecdsa.PrivateKey))
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("Failed to convert ECDSA private key for '%s'", keyFile))
}
sk, err := myCSP.KeyImport(priv, &bccsp.ECDSAPrivateKeyImportOpts{Temporary: temporary})
sk, err := myCSP.KeyImport(priv, factory.GetECDSAPrivateKeyImportOpts(temporary))
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("Failed to import ECDSA private key for '%s'", keyFile))
}
Expand Down
8 changes: 5 additions & 3 deletions internal/github.com/hyperledger/fabric-ca/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ import (
"io/ioutil"
"math/big"
mrand "math/rand"

"github.com/hyperledger/fabric-sdk-go/api/apicryptosuite"
factory "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/sdkpatch/cryptosuitebridge"

"net/http"
"path/filepath"
"reflect"
"regexp"
"strings"
"time"

"github.com/hyperledger/fabric-sdk-go/api/apicryptosuite"
"github.com/hyperledger/fabric-sdk-go/pkg/errors"

"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp"
"golang.org/x/crypto/ocsp"
)

Expand Down Expand Up @@ -168,7 +170,7 @@ func GenECDSAToken(csp apicryptosuite.CryptoSuite, cert []byte, key apicryptosui
b64cert := B64Encode(cert)
bodyAndcert := b64body + "." + b64cert

digest, digestError := csp.Hash([]byte(bodyAndcert), &bccsp.SHAOpts{})
digest, digestError := csp.Hash([]byte(bodyAndcert), factory.GetSHAOpts())
if digestError != nil {
return "", errors.WithMessage(digestError, fmt.Sprintf("Hash failed on '%s'", bodyAndcert))
}
Expand Down
Loading

0 comments on commit 26b3d2e

Please sign in to comment.