github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/bccsp/pkcs11/impl.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  package pkcs11
    17  
    18  import (
    19  	"crypto/ecdsa"
    20  	"crypto/elliptic"
    21  	"crypto/hmac"
    22  	"crypto/rand"
    23  	"crypto/rsa"
    24  	"crypto/sha256"
    25  	"crypto/sha512"
    26  	"crypto/x509"
    27  	"errors"
    28  	"fmt"
    29  	"hash"
    30  	"math/big"
    31  	"os"
    32  
    33  	"github.com/hyperledger/fabric/bccsp"
    34  	"github.com/hyperledger/fabric/bccsp/utils"
    35  	"github.com/hyperledger/fabric/common/flogging"
    36  	"github.com/miekg/pkcs11"
    37  
    38  	"golang.org/x/crypto/sha3"
    39  )
    40  
    41  var (
    42  	logger           = flogging.MustGetLogger("bccsp_p11")
    43  	sessionCacheSize = 10
    44  )
    45  
    46  // New returns a new instance of the software-based BCCSP
    47  // set at the passed security level, hash family and KeyStore.
    48  func New(opts PKCS11Opts, keyStore bccsp.KeyStore) (bccsp.BCCSP, error) {
    49  	// Init config
    50  	conf := &config{}
    51  	err := conf.setSecurityLevel(opts.SecLevel, opts.HashFamily)
    52  	if err != nil {
    53  		return nil, fmt.Errorf("Failed initializing configuration [%s]", err)
    54  	}
    55  
    56  	// Check KeyStore
    57  	if keyStore == nil {
    58  		return nil, errors.New("Invalid bccsp.KeyStore instance. It must be different from nil.")
    59  	}
    60  
    61  	lib := opts.Library
    62  	pin := opts.Pin
    63  	label := opts.Label
    64  	ctx, slot, session, err := loadLib(lib, pin, label)
    65  	if err != nil {
    66  		return nil, fmt.Errorf("Failed initializing PKCS11 library %s %s [%s]",
    67  			lib, label, err)
    68  	}
    69  
    70  	sessions := make(chan pkcs11.SessionHandle, sessionCacheSize)
    71  	csp := &impl{conf, keyStore, ctx, sessions, slot, lib, opts.Sensitive, opts.SoftVerify}
    72  	csp.returnSession(*session)
    73  	return csp, nil
    74  }
    75  
    76  type impl struct {
    77  	conf *config
    78  	ks   bccsp.KeyStore
    79  
    80  	ctx      *pkcs11.Ctx
    81  	sessions chan pkcs11.SessionHandle
    82  	slot     uint
    83  
    84  	lib          string
    85  	noPrivImport bool
    86  	softVerify   bool
    87  }
    88  
    89  // KeyGen generates a key using opts.
    90  func (csp *impl) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
    91  	// Validate arguments
    92  	if opts == nil {
    93  		return nil, errors.New("Invalid Opts parameter. It must not be nil.")
    94  	}
    95  
    96  	pkcs11Stored := false
    97  
    98  	// Parse algorithm
    99  	switch opts.(type) {
   100  	case *bccsp.ECDSAKeyGenOpts:
   101  		ski, pub, err := csp.generateECKey(csp.conf.ellipticCurve, opts.Ephemeral())
   102  		if err != nil {
   103  			return nil, fmt.Errorf("Failed generating ECDSA key [%s]", err)
   104  		}
   105  		k = &ecdsaPrivateKey{ski, ecdsaPublicKey{ski, pub}}
   106  		pkcs11Stored = true
   107  
   108  	case *bccsp.ECDSAP256KeyGenOpts:
   109  		ski, pub, err := csp.generateECKey(oidNamedCurveP256, opts.Ephemeral())
   110  		if err != nil {
   111  			return nil, fmt.Errorf("Failed generating ECDSA P256 key [%s]", err)
   112  		}
   113  
   114  		k = &ecdsaPrivateKey{ski, ecdsaPublicKey{ski, pub}}
   115  		pkcs11Stored = true
   116  
   117  	case *bccsp.ECDSAP384KeyGenOpts:
   118  		ski, pub, err := csp.generateECKey(oidNamedCurveP384, opts.Ephemeral())
   119  		if err != nil {
   120  			return nil, fmt.Errorf("Failed generating ECDSA P384 key [%s]", err)
   121  		}
   122  
   123  		k = &ecdsaPrivateKey{ski, ecdsaPublicKey{ski, pub}}
   124  		pkcs11Stored = true
   125  
   126  	case *bccsp.AESKeyGenOpts:
   127  		lowLevelKey, err := GetRandomBytes(csp.conf.aesBitLength)
   128  
   129  		if err != nil {
   130  			return nil, fmt.Errorf("Failed generating AES key [%s]", err)
   131  		}
   132  
   133  		k = &aesPrivateKey{lowLevelKey, false}
   134  
   135  	case *bccsp.AES256KeyGenOpts:
   136  		lowLevelKey, err := GetRandomBytes(32)
   137  
   138  		if err != nil {
   139  			return nil, fmt.Errorf("Failed generating AES 256 key [%s]", err)
   140  		}
   141  
   142  		k = &aesPrivateKey{lowLevelKey, false}
   143  
   144  	case *bccsp.AES192KeyGenOpts:
   145  		lowLevelKey, err := GetRandomBytes(24)
   146  
   147  		if err != nil {
   148  			return nil, fmt.Errorf("Failed generating AES 192 key [%s]", err)
   149  		}
   150  
   151  		k = &aesPrivateKey{lowLevelKey, false}
   152  
   153  	case *bccsp.AES128KeyGenOpts:
   154  		lowLevelKey, err := GetRandomBytes(16)
   155  
   156  		if err != nil {
   157  			return nil, fmt.Errorf("Failed generating AES 128 key [%s]", err)
   158  		}
   159  
   160  		k = &aesPrivateKey{lowLevelKey, false}
   161  
   162  	case *bccsp.RSAKeyGenOpts:
   163  		lowLevelKey, err := rsa.GenerateKey(rand.Reader, csp.conf.rsaBitLength)
   164  
   165  		if err != nil {
   166  			return nil, fmt.Errorf("Failed generating RSA key [%s]", err)
   167  		}
   168  
   169  		k = &rsaPrivateKey{lowLevelKey}
   170  
   171  	case *bccsp.RSA1024KeyGenOpts:
   172  		lowLevelKey, err := rsa.GenerateKey(rand.Reader, 1024)
   173  
   174  		if err != nil {
   175  			return nil, fmt.Errorf("Failed generating RSA 1024 key [%s]", err)
   176  		}
   177  
   178  		k = &rsaPrivateKey{lowLevelKey}
   179  
   180  	case *bccsp.RSA2048KeyGenOpts:
   181  		lowLevelKey, err := rsa.GenerateKey(rand.Reader, 2048)
   182  
   183  		if err != nil {
   184  			return nil, fmt.Errorf("Failed generating RSA 2048 key [%s]", err)
   185  		}
   186  
   187  		k = &rsaPrivateKey{lowLevelKey}
   188  
   189  	case *bccsp.RSA3072KeyGenOpts:
   190  		lowLevelKey, err := rsa.GenerateKey(rand.Reader, 3072)
   191  
   192  		if err != nil {
   193  			return nil, fmt.Errorf("Failed generating RSA 3072 key [%s]", err)
   194  		}
   195  
   196  		k = &rsaPrivateKey{lowLevelKey}
   197  
   198  	case *bccsp.RSA4096KeyGenOpts:
   199  		lowLevelKey, err := rsa.GenerateKey(rand.Reader, 4096)
   200  
   201  		if err != nil {
   202  			return nil, fmt.Errorf("Failed generating RSA 4096 key [%s]", err)
   203  		}
   204  
   205  		k = &rsaPrivateKey{lowLevelKey}
   206  
   207  	default:
   208  		return nil, fmt.Errorf("Unrecognized KeyGenOpts provided [%s]", opts.Algorithm())
   209  	}
   210  
   211  	// If the key is not Ephemeral, store it. EC Keys now in HSM, no need to store
   212  	if !pkcs11Stored && !opts.Ephemeral() {
   213  		// Store the key
   214  		err = csp.ks.StoreKey(k)
   215  		if err != nil {
   216  			return nil, fmt.Errorf("Failed storing key [%s]. [%s]", opts.Algorithm(), err)
   217  		}
   218  	}
   219  
   220  	return k, nil
   221  }
   222  
   223  // KeyDeriv derives a key from k using opts.
   224  // The opts argument should be appropriate for the primitive used.
   225  func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) {
   226  	// Validate arguments
   227  	if k == nil {
   228  		return nil, errors.New("Invalid Key. It must not be nil.")
   229  	}
   230  
   231  	// Derive key
   232  	switch k.(type) {
   233  	case *ecdsaPublicKey:
   234  		// Validate opts
   235  		if opts == nil {
   236  			return nil, errors.New("Invalid Opts parameter. It must not be nil.")
   237  		}
   238  
   239  		ecdsaK := k.(*ecdsaPublicKey)
   240  
   241  		switch opts.(type) {
   242  
   243  		// Re-randomized an ECDSA public key
   244  		case *bccsp.ECDSAReRandKeyOpts:
   245  			pubKey := ecdsaK.pub
   246  			reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts)
   247  			tempSK := &ecdsa.PublicKey{
   248  				Curve: pubKey.Curve,
   249  				X:     new(big.Int),
   250  				Y:     new(big.Int),
   251  			}
   252  
   253  			var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue())
   254  			var one = new(big.Int).SetInt64(1)
   255  			n := new(big.Int).Sub(pubKey.Params().N, one)
   256  			k.Mod(k, n)
   257  			k.Add(k, one)
   258  
   259  			// Compute temporary public key
   260  			tempX, tempY := pubKey.ScalarBaseMult(k.Bytes())
   261  			tempSK.X, tempSK.Y = tempSK.Add(
   262  				pubKey.X, pubKey.Y,
   263  				tempX, tempY,
   264  			)
   265  
   266  			// Verify temporary public key is a valid point on the reference curve
   267  			isOn := tempSK.Curve.IsOnCurve(tempSK.X, tempSK.Y)
   268  			if !isOn {
   269  				return nil, errors.New("Failed temporary public key IsOnCurve check.")
   270  			}
   271  
   272  			ecPt := elliptic.Marshal(tempSK.Curve, tempSK.X, tempSK.Y)
   273  			oid, ok := oidFromNamedCurve(tempSK.Curve)
   274  			if !ok {
   275  				return nil, errors.New("Do not know OID for this Curve.")
   276  			}
   277  
   278  			ski, err := csp.importECKey(oid, nil, ecPt, opts.Ephemeral(), publicKeyFlag)
   279  			if err != nil {
   280  				return nil, fmt.Errorf("Failed getting importing EC Public Key [%s]", err)
   281  			}
   282  			reRandomizedKey := &ecdsaPublicKey{ski, tempSK}
   283  
   284  			return reRandomizedKey, nil
   285  
   286  		default:
   287  			return nil, fmt.Errorf("Unrecognized KeyDerivOpts provided [%s]", opts.Algorithm())
   288  
   289  		}
   290  	case *ecdsaPrivateKey:
   291  		// Validate opts
   292  		if opts == nil {
   293  			return nil, errors.New("Invalid Opts parameter. It must not be nil.")
   294  		}
   295  
   296  		ecdsaK := k.(*ecdsaPrivateKey)
   297  
   298  		switch opts.(type) {
   299  
   300  		// Re-randomized an ECDSA private key
   301  		case *bccsp.ECDSAReRandKeyOpts:
   302  			reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts)
   303  			pubKey := ecdsaK.pub.pub
   304  			secret := csp.getSecretValue(ecdsaK.ski)
   305  			if secret == nil {
   306  				return nil, errors.New("Could not obtain EC Private Key")
   307  			}
   308  			bigSecret := new(big.Int).SetBytes(secret)
   309  
   310  			tempSK := &ecdsa.PrivateKey{
   311  				PublicKey: ecdsa.PublicKey{
   312  					Curve: pubKey.Curve,
   313  					X:     new(big.Int),
   314  					Y:     new(big.Int),
   315  				},
   316  				D: new(big.Int),
   317  			}
   318  
   319  			var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue())
   320  			var one = new(big.Int).SetInt64(1)
   321  			n := new(big.Int).Sub(pubKey.Params().N, one)
   322  			k.Mod(k, n)
   323  			k.Add(k, one)
   324  
   325  			tempSK.D.Add(bigSecret, k)
   326  			tempSK.D.Mod(tempSK.D, pubKey.Params().N)
   327  
   328  			// Compute temporary public key
   329  			tempSK.PublicKey.X, tempSK.PublicKey.Y = pubKey.ScalarBaseMult(tempSK.D.Bytes())
   330  
   331  			// Verify temporary public key is a valid point on the reference curve
   332  			isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y)
   333  			if !isOn {
   334  				return nil, errors.New("Failed temporary public key IsOnCurve check.")
   335  			}
   336  
   337  			ecPt := elliptic.Marshal(tempSK.Curve, tempSK.X, tempSK.Y)
   338  			oid, ok := oidFromNamedCurve(tempSK.Curve)
   339  			if !ok {
   340  				return nil, errors.New("Do not know OID for this Curve.")
   341  			}
   342  
   343  			ski, err := csp.importECKey(oid, tempSK.D.Bytes(), ecPt, opts.Ephemeral(), privateKeyFlag)
   344  			if err != nil {
   345  				return nil, fmt.Errorf("Failed getting importing EC Public Key [%s]", err)
   346  			}
   347  			reRandomizedKey := &ecdsaPrivateKey{ski, ecdsaPublicKey{ski, &tempSK.PublicKey}}
   348  
   349  			return reRandomizedKey, nil
   350  
   351  		default:
   352  			return nil, fmt.Errorf("Unrecognized KeyDerivOpts provided [%s]", opts.Algorithm())
   353  
   354  		}
   355  	case *aesPrivateKey:
   356  		// Validate opts
   357  		if opts == nil {
   358  			return nil, errors.New("Invalid Opts parameter. It must not be nil.")
   359  		}
   360  
   361  		aesK := k.(*aesPrivateKey)
   362  
   363  		switch opts.(type) {
   364  		case *bccsp.HMACTruncated256AESDeriveKeyOpts:
   365  			hmacOpts := opts.(*bccsp.HMACTruncated256AESDeriveKeyOpts)
   366  
   367  			mac := hmac.New(csp.conf.hashFunction, aesK.privKey)
   368  			mac.Write(hmacOpts.Argument())
   369  			hmacedKey := &aesPrivateKey{mac.Sum(nil)[:csp.conf.aesBitLength], false}
   370  
   371  			// If the key is not Ephemeral, store it.
   372  			if !opts.Ephemeral() {
   373  				// Store the key
   374  				err = csp.ks.StoreKey(hmacedKey)
   375  				if err != nil {
   376  					return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err)
   377  				}
   378  			}
   379  
   380  			return hmacedKey, nil
   381  
   382  		case *bccsp.HMACDeriveKeyOpts:
   383  
   384  			hmacOpts := opts.(*bccsp.HMACDeriveKeyOpts)
   385  
   386  			mac := hmac.New(csp.conf.hashFunction, aesK.privKey)
   387  			mac.Write(hmacOpts.Argument())
   388  			hmacedKey := &aesPrivateKey{mac.Sum(nil), true}
   389  
   390  			// If the key is not Ephemeral, store it.
   391  			if !opts.Ephemeral() {
   392  				// Store the key
   393  				err = csp.ks.StoreKey(hmacedKey)
   394  				if err != nil {
   395  					return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err)
   396  				}
   397  			}
   398  
   399  			return hmacedKey, nil
   400  
   401  		default:
   402  			return nil, fmt.Errorf("Unrecognized KeyDerivOpts provided [%s]", opts.Algorithm())
   403  
   404  		}
   405  
   406  	default:
   407  		return nil, fmt.Errorf("Key type not recognized [%s]", k)
   408  	}
   409  }
   410  
   411  // KeyImport imports a key from its raw representation using opts.
   412  // The opts argument should be appropriate for the primitive used.
   413  func (csp *impl) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
   414  	// Validate arguments
   415  	if raw == nil {
   416  		return nil, errors.New("Invalid raw. Cannot be nil")
   417  	}
   418  
   419  	if opts == nil {
   420  		return nil, errors.New("Invalid Opts parameter. It must not be nil.")
   421  	}
   422  
   423  	switch opts.(type) {
   424  
   425  	case *bccsp.AES256ImportKeyOpts:
   426  		aesRaw, ok := raw.([]byte)
   427  		if !ok {
   428  			return nil, errors.New("[AES256ImportKeyOpts] Invalid raw material. Expected byte array.")
   429  		}
   430  
   431  		if len(aesRaw) != 32 {
   432  			return nil, fmt.Errorf("[AES256ImportKeyOpts] Invalid Key Length [%d]. Must be 32 bytes", len(aesRaw))
   433  		}
   434  
   435  		aesK := &aesPrivateKey{utils.Clone(aesRaw), false}
   436  
   437  		// If the key is not Ephemeral, store it.
   438  		if !opts.Ephemeral() {
   439  			// Store the key
   440  			err = csp.ks.StoreKey(aesK)
   441  			if err != nil {
   442  				return nil, fmt.Errorf("Failed storing AES key [%s]", err)
   443  			}
   444  		}
   445  
   446  		return aesK, nil
   447  
   448  	case *bccsp.HMACImportKeyOpts:
   449  		aesRaw, ok := raw.([]byte)
   450  		if !ok {
   451  			return nil, errors.New("[HMACImportKeyOpts] Invalid raw material. Expected byte array.")
   452  		}
   453  
   454  		if len(aesRaw) == 0 {
   455  			return nil, errors.New("[HMACImportKeyOpts] Invalid raw. It must not be nil.")
   456  		}
   457  
   458  		aesK := &aesPrivateKey{utils.Clone(aesRaw), false}
   459  
   460  		// If the key is not Ephemeral, store it.
   461  		if !opts.Ephemeral() {
   462  			// Store the key
   463  			err = csp.ks.StoreKey(aesK)
   464  			if err != nil {
   465  				return nil, fmt.Errorf("Failed storing AES key [%s]", err)
   466  			}
   467  		}
   468  
   469  		return aesK, nil
   470  
   471  	case *bccsp.ECDSAPKIXPublicKeyImportOpts:
   472  		der, ok := raw.([]byte)
   473  		if !ok {
   474  			return nil, errors.New("[ECDSAPKIXPublicKeyImportOpts] Invalid raw material. Expected byte array.")
   475  		}
   476  
   477  		if len(der) == 0 {
   478  			return nil, errors.New("[ECDSAPKIXPublicKeyImportOpts] Invalid raw. It must not be nil.")
   479  		}
   480  
   481  		lowLevelKey, err := utils.DERToPublicKey(der)
   482  		if err != nil {
   483  			return nil, fmt.Errorf("Failed converting PKIX to ECDSA public key [%s]", err)
   484  		}
   485  
   486  		ecdsaPK, ok := lowLevelKey.(*ecdsa.PublicKey)
   487  		if !ok {
   488  			return nil, errors.New("Failed casting to ECDSA public key. Invalid raw material.")
   489  		}
   490  
   491  		ecPt := elliptic.Marshal(ecdsaPK.Curve, ecdsaPK.X, ecdsaPK.Y)
   492  		oid, ok := oidFromNamedCurve(ecdsaPK.Curve)
   493  		if !ok {
   494  			return nil, errors.New("Do not know OID for this Curve.")
   495  		}
   496  
   497  		var ski []byte
   498  		if csp.noPrivImport {
   499  			// opencryptoki does not support public ec key imports. This is a sufficient
   500  			// workaround for now to use soft verify
   501  			hash := sha256.Sum256(ecPt)
   502  			ski = hash[:]
   503  		} else {
   504  			// Warn about potential future problems
   505  			if !csp.softVerify {
   506  				logger.Debugf("opencryptoki workaround warning: Importing public EC Key does not store out to pkcs11 store,\n" +
   507  					"so verify with this key will fail, unless key is already present in store. Enable 'softwareverify'\n" +
   508  					"in pkcs11 options, if suspect this issue.")
   509  			}
   510  			ski, err = csp.importECKey(oid, nil, ecPt, opts.Ephemeral(), publicKeyFlag)
   511  			if err != nil {
   512  				return nil, fmt.Errorf("Failed getting importing EC Public Key [%s]", err)
   513  			}
   514  		}
   515  
   516  		k = &ecdsaPublicKey{ski, ecdsaPK}
   517  		return k, nil
   518  
   519  	case *bccsp.ECDSAPrivateKeyImportOpts:
   520  		if csp.noPrivImport {
   521  			return nil, errors.New("[ECDSADERPrivateKeyImportOpts] PKCS11 options 'sensitivekeys' is set to true. Cannot import.")
   522  		}
   523  
   524  		der, ok := raw.([]byte)
   525  		if !ok {
   526  			return nil, errors.New("[ECDSADERPrivateKeyImportOpts] Invalid raw material. Expected byte array.")
   527  		}
   528  
   529  		if len(der) == 0 {
   530  			return nil, errors.New("[ECDSADERPrivateKeyImportOpts] Invalid raw. It must not be nil.")
   531  		}
   532  
   533  		lowLevelKey, err := utils.DERToPrivateKey(der)
   534  		if err != nil {
   535  			return nil, fmt.Errorf("Failed converting PKIX to ECDSA public key [%s]", err)
   536  		}
   537  
   538  		ecdsaSK, ok := lowLevelKey.(*ecdsa.PrivateKey)
   539  		if !ok {
   540  			return nil, errors.New("Failed casting to ECDSA public key. Invalid raw material.")
   541  		}
   542  
   543  		ecPt := elliptic.Marshal(ecdsaSK.Curve, ecdsaSK.X, ecdsaSK.Y)
   544  		oid, ok := oidFromNamedCurve(ecdsaSK.Curve)
   545  		if !ok {
   546  			return nil, errors.New("Do not know OID for this Curve.")
   547  		}
   548  
   549  		ski, err := csp.importECKey(oid, ecdsaSK.D.Bytes(), ecPt, opts.Ephemeral(), privateKeyFlag)
   550  		if err != nil {
   551  			return nil, fmt.Errorf("Failed getting importing EC Private Key [%s]", err)
   552  		}
   553  
   554  		k = &ecdsaPrivateKey{ski, ecdsaPublicKey{ski, &ecdsaSK.PublicKey}}
   555  		return k, nil
   556  
   557  	case *bccsp.ECDSAGoPublicKeyImportOpts:
   558  		lowLevelKey, ok := raw.(*ecdsa.PublicKey)
   559  		if !ok {
   560  			return nil, errors.New("[ECDSAGoPublicKeyImportOpts] Invalid raw material. Expected *ecdsa.PublicKey.")
   561  		}
   562  
   563  		ecPt := elliptic.Marshal(lowLevelKey.Curve, lowLevelKey.X, lowLevelKey.Y)
   564  		oid, ok := oidFromNamedCurve(lowLevelKey.Curve)
   565  		if !ok {
   566  			return nil, errors.New("Do not know OID for this Curve.")
   567  		}
   568  
   569  		var ski []byte
   570  		if csp.noPrivImport {
   571  			// opencryptoki does not support public ec key imports. This is a sufficient
   572  			// workaround for now to use soft verify
   573  			hash := sha256.Sum256(ecPt)
   574  			ski = hash[:]
   575  		} else {
   576  			// Warn about potential future problems
   577  			if !csp.softVerify {
   578  				logger.Debugf("opencryptoki workaround warning: Importing public EC Key does not store out to pkcs11 store,\n" +
   579  					"so verify with this key will fail, unless key is already present in store. Enable 'softwareverify'\n" +
   580  					"in pkcs11 options, if suspect this issue.")
   581  			}
   582  			ski, err = csp.importECKey(oid, nil, ecPt, opts.Ephemeral(), publicKeyFlag)
   583  			if err != nil {
   584  				return nil, fmt.Errorf("Failed getting importing EC Public Key [%s]", err)
   585  			}
   586  		}
   587  
   588  		k = &ecdsaPublicKey{ski, lowLevelKey}
   589  		return k, nil
   590  
   591  	case *bccsp.RSAGoPublicKeyImportOpts:
   592  		lowLevelKey, ok := raw.(*rsa.PublicKey)
   593  		if !ok {
   594  			return nil, errors.New("[RSAGoPublicKeyImportOpts] Invalid raw material. Expected *rsa.PublicKey.")
   595  		}
   596  
   597  		k = &rsaPublicKey{lowLevelKey}
   598  
   599  		// If the key is not Ephemeral, store it.
   600  		if !opts.Ephemeral() {
   601  			// Store the key
   602  			err = csp.ks.StoreKey(k)
   603  			if err != nil {
   604  				return nil, fmt.Errorf("Failed storing RSA publi key [%s]", err)
   605  			}
   606  		}
   607  
   608  		return k, nil
   609  
   610  	case *bccsp.X509PublicKeyImportOpts:
   611  		x509Cert, ok := raw.(*x509.Certificate)
   612  		if !ok {
   613  			return nil, errors.New("[X509PublicKeyImportOpts] Invalid raw material. Expected *x509.Certificate.")
   614  		}
   615  
   616  		pk := x509Cert.PublicKey
   617  
   618  		switch pk.(type) {
   619  		case *ecdsa.PublicKey:
   620  			return csp.KeyImport(pk, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()})
   621  		case *rsa.PublicKey:
   622  			return csp.KeyImport(pk, &bccsp.RSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()})
   623  		default:
   624  			return nil, errors.New("Certificate public key type not recognized. Supported keys: [ECDSA, RSA]")
   625  		}
   626  
   627  	default:
   628  		return nil, errors.New("Import Key Options not recognized")
   629  	}
   630  }
   631  
   632  // GetKey returns the key this CSP associates to
   633  // the Subject Key Identifier ski.
   634  func (csp *impl) GetKey(ski []byte) (k bccsp.Key, err error) {
   635  	pubKey, isPriv, err := csp.getECKey(ski)
   636  	if err == nil {
   637  		if isPriv {
   638  			return &ecdsaPrivateKey{ski, ecdsaPublicKey{ski, pubKey}}, nil
   639  		} else {
   640  			return &ecdsaPublicKey{ski, pubKey}, nil
   641  		}
   642  	}
   643  	return csp.ks.GetKey(ski)
   644  }
   645  
   646  // Hash hashes messages msg using options opts.
   647  func (csp *impl) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error) {
   648  	var h hash.Hash
   649  	if opts == nil {
   650  		h = csp.conf.hashFunction()
   651  	} else {
   652  		switch opts.(type) {
   653  		case *bccsp.SHAOpts:
   654  			h = csp.conf.hashFunction()
   655  		case *bccsp.SHA256Opts:
   656  			h = sha256.New()
   657  		case *bccsp.SHA384Opts:
   658  			h = sha512.New384()
   659  		case *bccsp.SHA3_256Opts:
   660  			h = sha3.New256()
   661  		case *bccsp.SHA3_384Opts:
   662  			h = sha3.New384()
   663  		default:
   664  			return nil, fmt.Errorf("Algorithm not recognized [%s]", opts.Algorithm())
   665  		}
   666  	}
   667  
   668  	h.Write(msg)
   669  	return h.Sum(nil), nil
   670  }
   671  
   672  // GetHash returns and instance of hash.Hash using options opts.
   673  // If opts is nil then the default hash function is returned.
   674  func (csp *impl) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) {
   675  	if opts == nil {
   676  		return csp.conf.hashFunction(), nil
   677  	}
   678  
   679  	switch opts.(type) {
   680  	case *bccsp.SHAOpts:
   681  		return csp.conf.hashFunction(), nil
   682  	case *bccsp.SHA256Opts:
   683  		return sha256.New(), nil
   684  	case *bccsp.SHA384Opts:
   685  		return sha512.New384(), nil
   686  	case *bccsp.SHA3_256Opts:
   687  		return sha3.New256(), nil
   688  	case *bccsp.SHA3_384Opts:
   689  		return sha3.New384(), nil
   690  	default:
   691  		return nil, fmt.Errorf("Algorithm not recognized [%s]", opts.Algorithm())
   692  	}
   693  }
   694  
   695  // Sign signs digest using key k.
   696  // The opts argument should be appropriate for the primitive used.
   697  //
   698  // Note that when a signature of a hash of a larger message is needed,
   699  // the caller is responsible for hashing the larger message and passing
   700  // the hash (as digest).
   701  func (csp *impl) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
   702  	// Validate arguments
   703  	if k == nil {
   704  		return nil, errors.New("Invalid Key. It must not be nil.")
   705  	}
   706  	if len(digest) == 0 {
   707  		return nil, errors.New("Invalid digest. Cannot be empty.")
   708  	}
   709  
   710  	// Check key type
   711  	switch k.(type) {
   712  	case *ecdsaPrivateKey:
   713  		return csp.signECDSA(*k.(*ecdsaPrivateKey), digest, opts)
   714  	case *rsaPrivateKey:
   715  		if opts == nil {
   716  			return nil, errors.New("Invalid options. Nil.")
   717  		}
   718  
   719  		return k.(*rsaPrivateKey).privKey.Sign(rand.Reader, digest, opts)
   720  	default:
   721  		//return nil, fmt.Errorf("Key type not recognized [%s]", k)
   722  		panic(fmt.Errorf("Key type not recognized - [%+v] [%#v] [%T] [%T]", k, k, k, k))
   723  	}
   724  }
   725  
   726  // Verify verifies signature against key k and digest
   727  func (csp *impl) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
   728  	// Validate arguments
   729  	if k == nil {
   730  		return false, errors.New("Invalid Key. It must not be nil.")
   731  	}
   732  	if len(signature) == 0 {
   733  		return false, errors.New("Invalid signature. Cannot be empty.")
   734  	}
   735  	if len(digest) == 0 {
   736  		return false, errors.New("Invalid digest. Cannot be empty.")
   737  	}
   738  
   739  	// Check key type
   740  	switch k.(type) {
   741  	case *ecdsaPrivateKey:
   742  		return csp.verifyECDSA(k.(*ecdsaPrivateKey).pub, signature, digest, opts)
   743  	case *ecdsaPublicKey:
   744  		return csp.verifyECDSA(*k.(*ecdsaPublicKey), signature, digest, opts)
   745  	case *rsaPrivateKey:
   746  		if opts == nil {
   747  			return false, errors.New("Invalid options. It must not be nil.")
   748  		}
   749  		switch opts.(type) {
   750  		case *rsa.PSSOptions:
   751  			err := rsa.VerifyPSS(&(k.(*rsaPrivateKey).privKey.PublicKey),
   752  				(opts.(*rsa.PSSOptions)).Hash,
   753  				digest, signature, opts.(*rsa.PSSOptions))
   754  
   755  			return err == nil, err
   756  		default:
   757  			return false, fmt.Errorf("Opts type not recognized [%s]", opts)
   758  		}
   759  	case *rsaPublicKey:
   760  		if opts == nil {
   761  			return false, errors.New("Invalid options. It must not be nil.")
   762  		}
   763  		switch opts.(type) {
   764  		case *rsa.PSSOptions:
   765  			err := rsa.VerifyPSS(k.(*rsaPublicKey).pubKey,
   766  				(opts.(*rsa.PSSOptions)).Hash,
   767  				digest, signature, opts.(*rsa.PSSOptions))
   768  
   769  			return err == nil, err
   770  		default:
   771  			return false, fmt.Errorf("Opts type not recognized [%s]", opts)
   772  		}
   773  	default:
   774  		return false, fmt.Errorf("Key type not recognized [%s]", k)
   775  	}
   776  }
   777  
   778  // Encrypt encrypts plaintext using key k.
   779  // The opts argument should be appropriate for the primitive used.
   780  func (csp *impl) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) (ciphertext []byte, err error) {
   781  	// Validate arguments
   782  	if k == nil {
   783  		return nil, errors.New("Invalid Key. It must not be nil.")
   784  	}
   785  
   786  	// Check key type
   787  	switch k.(type) {
   788  	case *aesPrivateKey:
   789  		// check for mode
   790  		switch opts.(type) {
   791  		case *bccsp.AESCBCPKCS7ModeOpts, bccsp.AESCBCPKCS7ModeOpts:
   792  			// AES in CBC mode with PKCS7 padding
   793  			return AESCBCPKCS7Encrypt(k.(*aesPrivateKey).privKey, plaintext)
   794  		default:
   795  			return nil, fmt.Errorf("Mode not recognized [%s]", opts)
   796  		}
   797  	default:
   798  		return nil, fmt.Errorf("Key type not recognized [%s]", k)
   799  	}
   800  }
   801  
   802  // Decrypt decrypts ciphertext using key k.
   803  // The opts argument should be appropriate for the primitive used.
   804  func (csp *impl) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) (plaintext []byte, err error) {
   805  	// Validate arguments
   806  	if k == nil {
   807  		return nil, errors.New("Invalid Key. It must not be nil.")
   808  	}
   809  
   810  	// Check key type
   811  	switch k.(type) {
   812  	case *aesPrivateKey:
   813  		// check for mode
   814  		switch opts.(type) {
   815  		case *bccsp.AESCBCPKCS7ModeOpts, bccsp.AESCBCPKCS7ModeOpts:
   816  			// AES in CBC mode with PKCS7 padding
   817  			return AESCBCPKCS7Decrypt(k.(*aesPrivateKey).privKey, ciphertext)
   818  		default:
   819  			return nil, fmt.Errorf("Mode not recognized [%s]", opts)
   820  		}
   821  	default:
   822  		return nil, fmt.Errorf("Key type not recognized [%s]", k)
   823  	}
   824  }
   825  
   826  // THIS IS ONLY USED FOR TESTING
   827  // This is a convenience function. Useful to self-configure, for tests where usual configuration is not
   828  // available
   829  func FindPKCS11Lib() (lib, pin, label string) {
   830  	//FIXME: Till we workout the configuration piece, look for the libraries in the familiar places
   831  	lib = os.Getenv("PKCS11_LIB")
   832  	if lib == "" {
   833  		pin = "98765432"
   834  		label = "ForFabric"
   835  		possibilities := []string{
   836  			"/usr/lib/softhsm/libsofthsm2.so",                            //Debian
   837  			"/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so",           //Ubuntu
   838  			"/usr/lib/s390x-linux-gnu/softhsm/libsofthsm2.so",            //Ubuntu
   839  			"/usr/lib/powerpc64le-linux-gnu/softhsm/libsofthsm2.so",      //Power
   840  			"/usr/local/Cellar/softhsm/2.1.0/lib/softhsm/libsofthsm2.so", //MacOS
   841  		}
   842  		for _, path := range possibilities {
   843  			if _, err := os.Stat(path); !os.IsNotExist(err) {
   844  				lib = path
   845  				break
   846  			}
   847  		}
   848  	} else {
   849  		pin = os.Getenv("PKCS11_PIN")
   850  		label = os.Getenv("PKCS11_LABEL")
   851  	}
   852  	return lib, pin, label
   853  }