From 1109d6369beb407924826bcc688d19498a44de54 Mon Sep 17 00:00:00 2001 From: Angelo De Caro Date: Fri, 5 May 2017 11:31:47 +0200 Subject: [PATCH] [FAB-3441] bccsp/sw KeyDeriv test coverage Using the approach discussed in FAB-3465, this change-sets refactors the way key derivation is done at bccsp/sw. Essentially, the switch has been replaced by a map. The approach decouples the testing of the bccsp interface implementation from the cryptographic algorithms. Test-coverage of the entire bccsp/sw is now at more than 85% Change-Id: I29f460830ac9531755c5b818b222b75339a75f8b Signed-off-by: Angelo De Caro --- bccsp/mocks/mocks.go | 12 +++ bccsp/sw/impl.go | 198 ++++++-------------------------------- bccsp/sw/internals.go | 8 ++ bccsp/sw/keyderiv.go | 157 ++++++++++++++++++++++++++++++ bccsp/sw/keyderiv_test.go | 94 ++++++++++++++++++ bccsp/sw/mocks/mocks.go | 19 ++++ bccsp/sw/sw_test.go | 70 +++++++++----- 7 files changed, 361 insertions(+), 197 deletions(-) create mode 100644 bccsp/sw/keyderiv.go create mode 100644 bccsp/sw/keyderiv_test.go diff --git a/bccsp/mocks/mocks.go b/bccsp/mocks/mocks.go index 661e3c2a7a1..9ca79c23d0b 100644 --- a/bccsp/mocks/mocks.go +++ b/bccsp/mocks/mocks.go @@ -170,3 +170,15 @@ type HashOpts struct{} func (HashOpts) Algorithm() string { return "Mock HashOpts" } + +type KeyDerivOpts struct { + EphemeralValue bool +} + +func (*KeyDerivOpts) Algorithm() string { + return "Mock KeyDerivOpts" +} + +func (o *KeyDerivOpts) Ephemeral() bool { + return o.EphemeralValue +} diff --git a/bccsp/sw/impl.go b/bccsp/sw/impl.go index 3d2785a984b..e8888dcf79a 100644 --- a/bccsp/sw/impl.go +++ b/bccsp/sw/impl.go @@ -18,13 +18,11 @@ package sw import ( "crypto/ecdsa" "crypto/elliptic" - "crypto/hmac" "crypto/rsa" "crypto/x509" "errors" "fmt" "hash" - "math/big" "reflect" "crypto/sha256" @@ -125,6 +123,13 @@ func New(securityLevel int, hashFamily string, keyStore bccsp.KeyStore) (bccsp.B keyGenerators[reflect.TypeOf(&bccsp.RSA4096KeyGenOpts{})] = &rsaKeyGenerator{length: 4096} impl.keyGenerators = keyGenerators + // Set the key generators + keyDerivers := make(map[reflect.Type]KeyDeriver) + keyDerivers[reflect.TypeOf(&ecdsaPrivateKey{})] = &ecdsaPrivateKeyKeyDeriver{} + keyDerivers[reflect.TypeOf(&ecdsaPublicKey{})] = &ecdsaPublicKeyKeyDeriver{} + keyDerivers[reflect.TypeOf(&aesPrivateKey{})] = &aesPrivateKeyKeyDeriver{bccsp: impl} + impl.keyDerivers = keyDerivers + return impl, nil } @@ -134,6 +139,7 @@ type impl struct { ks bccsp.KeyStore keyGenerators map[reflect.Type]KeyGenerator + keyDerivers map[reflect.Type]KeyDeriver encryptors map[reflect.Type]Encryptor decryptors map[reflect.Type]Decryptor signers map[reflect.Type]Signer @@ -177,180 +183,30 @@ func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, e if k == nil { return nil, errors.New("Invalid Key. It must not be nil.") } + if opts == nil { + return nil, errors.New("Invalid opts. It must not be nil.") + } - // Derive key - switch k.(type) { - case *ecdsaPublicKey: - // Validate opts - if opts == nil { - return nil, errors.New("Invalid Opts parameter. It must not be nil.") - } - - ecdsaK := k.(*ecdsaPublicKey) - - switch opts.(type) { - - // Re-randomized an ECDSA private key - case *bccsp.ECDSAReRandKeyOpts: - reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts) - tempSK := &ecdsa.PublicKey{ - Curve: ecdsaK.pubKey.Curve, - X: new(big.Int), - Y: new(big.Int), - } - - var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue()) - var one = new(big.Int).SetInt64(1) - n := new(big.Int).Sub(ecdsaK.pubKey.Params().N, one) - k.Mod(k, n) - k.Add(k, one) - - // Compute temporary public key - tempX, tempY := ecdsaK.pubKey.ScalarBaseMult(k.Bytes()) - tempSK.X, tempSK.Y = tempSK.Add( - ecdsaK.pubKey.X, ecdsaK.pubKey.Y, - tempX, tempY, - ) - - // Verify temporary public key is a valid point on the reference curve - isOn := tempSK.Curve.IsOnCurve(tempSK.X, tempSK.Y) - if !isOn { - return nil, errors.New("Failed temporary public key IsOnCurve check.") - } - - reRandomizedKey := &ecdsaPublicKey{tempSK} - - // If the key is not Ephemeral, store it. - if !opts.Ephemeral() { - // Store the key - err = csp.ks.StoreKey(reRandomizedKey) - if err != nil { - return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err) - } - } - - return reRandomizedKey, nil - - default: - return nil, fmt.Errorf("Unrecognized KeyDerivOpts provided [%s]", opts.Algorithm()) - - } - case *ecdsaPrivateKey: - // Validate opts - if opts == nil { - return nil, errors.New("Invalid Opts parameter. It must not be nil.") - } - - ecdsaK := k.(*ecdsaPrivateKey) - - switch opts.(type) { - - // Re-randomized an ECDSA private key - case *bccsp.ECDSAReRandKeyOpts: - reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts) - tempSK := &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: ecdsaK.privKey.Curve, - X: new(big.Int), - Y: new(big.Int), - }, - D: new(big.Int), - } - - var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue()) - var one = new(big.Int).SetInt64(1) - n := new(big.Int).Sub(ecdsaK.privKey.Params().N, one) - k.Mod(k, n) - k.Add(k, one) - - tempSK.D.Add(ecdsaK.privKey.D, k) - tempSK.D.Mod(tempSK.D, ecdsaK.privKey.PublicKey.Params().N) - - // Compute temporary public key - tempX, tempY := ecdsaK.privKey.PublicKey.ScalarBaseMult(k.Bytes()) - tempSK.PublicKey.X, tempSK.PublicKey.Y = - tempSK.PublicKey.Add( - ecdsaK.privKey.PublicKey.X, ecdsaK.privKey.PublicKey.Y, - tempX, tempY, - ) - - // Verify temporary public key is a valid point on the reference curve - isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y) - if !isOn { - return nil, errors.New("Failed temporary public key IsOnCurve check.") - } - - reRandomizedKey := &ecdsaPrivateKey{tempSK} - - // If the key is not Ephemeral, store it. - if !opts.Ephemeral() { - // Store the key - err = csp.ks.StoreKey(reRandomizedKey) - if err != nil { - return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err) - } - } - - return reRandomizedKey, nil - - default: - return nil, fmt.Errorf("Unrecognized KeyDerivOpts provided [%s]", opts.Algorithm()) - - } - case *aesPrivateKey: - // Validate opts - if opts == nil { - return nil, errors.New("Invalid Opts parameter. It must not be nil.") - } - - aesK := k.(*aesPrivateKey) - - switch opts.(type) { - case *bccsp.HMACTruncated256AESDeriveKeyOpts: - hmacOpts := opts.(*bccsp.HMACTruncated256AESDeriveKeyOpts) - - mac := hmac.New(csp.conf.hashFunction, aesK.privKey) - mac.Write(hmacOpts.Argument()) - hmacedKey := &aesPrivateKey{mac.Sum(nil)[:csp.conf.aesBitLength], false} - - // If the key is not Ephemeral, store it. - if !opts.Ephemeral() { - // Store the key - err = csp.ks.StoreKey(hmacedKey) - if err != nil { - return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err) - } - } - - return hmacedKey, nil - - case *bccsp.HMACDeriveKeyOpts: - - hmacOpts := opts.(*bccsp.HMACDeriveKeyOpts) - - mac := hmac.New(csp.conf.hashFunction, aesK.privKey) - mac.Write(hmacOpts.Argument()) - hmacedKey := &aesPrivateKey{mac.Sum(nil), true} - - // If the key is not Ephemeral, store it. - if !opts.Ephemeral() { - // Store the key - err = csp.ks.StoreKey(hmacedKey) - if err != nil { - return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err) - } - } - - return hmacedKey, nil + keyDeriver, found := csp.keyDerivers[reflect.TypeOf(k)] + if !found { + return nil, fmt.Errorf("Unsupported 'Key' provided [%v]", k) + } - default: - return nil, fmt.Errorf("Unrecognized KeyDerivOpts provided [%s]", opts.Algorithm()) + k, err = keyDeriver.KeyDeriv(k, opts) + if err != nil { + return nil, err + } + // If the key is not Ephemeral, store it. + if !opts.Ephemeral() { + // Store the key + err = csp.ks.StoreKey(k) + if err != nil { + return nil, fmt.Errorf("Failed storing key [%s]. [%s]", opts.Algorithm(), err) } - - default: - return nil, fmt.Errorf("Key type not recognized [%s]", k) } + + return k, nil } // KeyImport imports a key from its raw representation using opts. diff --git a/bccsp/sw/internals.go b/bccsp/sw/internals.go index 09fed6b59e9..cfca22fa4c7 100644 --- a/bccsp/sw/internals.go +++ b/bccsp/sw/internals.go @@ -29,6 +29,14 @@ type KeyGenerator interface { KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) } +// KeyDeriver is a BCCSP-like interface that provides key derivation algorithms +type KeyDeriver interface { + + // KeyDeriv derives a key from k using opts. + // The opts argument should be appropriate for the primitive used. + KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) +} + // Encryptor is a BCCSP-like interface that provides encryption algorithms type Encryptor interface { diff --git a/bccsp/sw/keyderiv.go b/bccsp/sw/keyderiv.go new file mode 100644 index 00000000000..31bb3702355 --- /dev/null +++ b/bccsp/sw/keyderiv.go @@ -0,0 +1,157 @@ +/* +Copyright IBM Corp. 2017 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. +*/ + +package sw + +import ( + "crypto/ecdsa" + "fmt" + + "errors" + "math/big" + + "crypto/hmac" + + "github.com/hyperledger/fabric/bccsp" +) + +type ecdsaPublicKeyKeyDeriver struct{} + +func (kd *ecdsaPublicKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) { + // Validate opts + if opts == nil { + return nil, errors.New("Invalid opts parameter. It must not be nil.") + } + + ecdsaK := k.(*ecdsaPublicKey) + + switch opts.(type) { + // Re-randomized an ECDSA private key + case *bccsp.ECDSAReRandKeyOpts: + reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts) + tempSK := &ecdsa.PublicKey{ + Curve: ecdsaK.pubKey.Curve, + X: new(big.Int), + Y: new(big.Int), + } + + var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue()) + var one = new(big.Int).SetInt64(1) + n := new(big.Int).Sub(ecdsaK.pubKey.Params().N, one) + k.Mod(k, n) + k.Add(k, one) + + // Compute temporary public key + tempX, tempY := ecdsaK.pubKey.ScalarBaseMult(k.Bytes()) + tempSK.X, tempSK.Y = tempSK.Add( + ecdsaK.pubKey.X, ecdsaK.pubKey.Y, + tempX, tempY, + ) + + // Verify temporary public key is a valid point on the reference curve + isOn := tempSK.Curve.IsOnCurve(tempSK.X, tempSK.Y) + if !isOn { + return nil, errors.New("Failed temporary public key IsOnCurve check.") + } + + return &ecdsaPublicKey{tempSK}, nil + default: + return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts) + } +} + +type ecdsaPrivateKeyKeyDeriver struct{} + +func (kd *ecdsaPrivateKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) { + // Validate opts + if opts == nil { + return nil, errors.New("Invalid opts parameter. It must not be nil.") + } + + ecdsaK := k.(*ecdsaPrivateKey) + + switch opts.(type) { + // Re-randomized an ECDSA private key + case *bccsp.ECDSAReRandKeyOpts: + reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts) + tempSK := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: ecdsaK.privKey.Curve, + X: new(big.Int), + Y: new(big.Int), + }, + D: new(big.Int), + } + + var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue()) + var one = new(big.Int).SetInt64(1) + n := new(big.Int).Sub(ecdsaK.privKey.Params().N, one) + k.Mod(k, n) + k.Add(k, one) + + tempSK.D.Add(ecdsaK.privKey.D, k) + tempSK.D.Mod(tempSK.D, ecdsaK.privKey.PublicKey.Params().N) + + // Compute temporary public key + tempX, tempY := ecdsaK.privKey.PublicKey.ScalarBaseMult(k.Bytes()) + tempSK.PublicKey.X, tempSK.PublicKey.Y = + tempSK.PublicKey.Add( + ecdsaK.privKey.PublicKey.X, ecdsaK.privKey.PublicKey.Y, + tempX, tempY, + ) + + // Verify temporary public key is a valid point on the reference curve + isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y) + if !isOn { + return nil, errors.New("Failed temporary public key IsOnCurve check.") + } + + return &ecdsaPrivateKey{tempSK}, nil + default: + return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts) + } +} + +type aesPrivateKeyKeyDeriver struct { + bccsp *impl +} + +func (kd *aesPrivateKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) { + // Validate opts + if opts == nil { + return nil, errors.New("Invalid opts parameter. It must not be nil.") + } + + aesK := k.(*aesPrivateKey) + + switch opts.(type) { + case *bccsp.HMACTruncated256AESDeriveKeyOpts: + hmacOpts := opts.(*bccsp.HMACTruncated256AESDeriveKeyOpts) + + mac := hmac.New(kd.bccsp.conf.hashFunction, aesK.privKey) + mac.Write(hmacOpts.Argument()) + return &aesPrivateKey{mac.Sum(nil)[:kd.bccsp.conf.aesBitLength], false}, nil + + case *bccsp.HMACDeriveKeyOpts: + hmacOpts := opts.(*bccsp.HMACDeriveKeyOpts) + + mac := hmac.New(kd.bccsp.conf.hashFunction, aesK.privKey) + mac.Write(hmacOpts.Argument()) + return &aesPrivateKey{mac.Sum(nil), true}, nil + default: + return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts) + } +} diff --git a/bccsp/sw/keyderiv_test.go b/bccsp/sw/keyderiv_test.go new file mode 100644 index 00000000000..4e5916ab4f7 --- /dev/null +++ b/bccsp/sw/keyderiv_test.go @@ -0,0 +1,94 @@ +/* +Copyright IBM Corp. 2017 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. +*/ + +package sw + +import ( + "errors" + "reflect" + "testing" + + mocks2 "github.com/hyperledger/fabric/bccsp/mocks" + "github.com/hyperledger/fabric/bccsp/sw/mocks" + "github.com/stretchr/testify/assert" +) + +func TestKeyDeriv(t *testing.T) { + expectedKey := &mocks2.MockKey{BytesValue: []byte{1, 2, 3}} + expectedOpts := &mocks2.KeyDerivOpts{EphemeralValue: true} + expectetValue := &mocks2.MockKey{BytesValue: []byte{1, 2, 3, 4, 5}} + expectedErr := errors.New("no error") + + keyDerivers := make(map[reflect.Type]KeyDeriver) + keyDerivers[reflect.TypeOf(&mocks2.MockKey{})] = &mocks.KeyDeriver{ + KeyArg: expectedKey, + OptsArg: expectedOpts, + Value: expectetValue, + Err: expectedErr, + } + csp := impl{keyDerivers: keyDerivers} + value, err := csp.KeyDeriv(expectedKey, expectedOpts) + assert.Equal(t, nil, value) + assert.Equal(t, expectedErr, err) + + keyDerivers = make(map[reflect.Type]KeyDeriver) + keyDerivers[reflect.TypeOf(&mocks2.MockKey{})] = &mocks.KeyDeriver{ + KeyArg: expectedKey, + OptsArg: expectedOpts, + Value: expectetValue, + Err: nil, + } + csp = impl{keyDerivers: keyDerivers} + value, err = csp.KeyDeriv(expectedKey, expectedOpts) + assert.Equal(t, expectetValue, value) + assert.Equal(t, nil, err) +} + +func TestECDSAPublicKeyKeyDeriver(t *testing.T) { + kd := ecdsaPublicKeyKeyDeriver{} + + _, err := kd.KeyDeriv(&mocks2.MockKey{}, nil) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Invalid opts parameter. It must not be nil.") + + _, err = kd.KeyDeriv(&ecdsaPublicKey{}, &mocks2.KeyDerivOpts{}) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Unsupported 'KeyDerivOpts' provided [") +} + +func TestECDSAPrivateKeyKeyDeriver(t *testing.T) { + kd := ecdsaPrivateKeyKeyDeriver{} + + _, err := kd.KeyDeriv(&mocks2.MockKey{}, nil) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Invalid opts parameter. It must not be nil.") + + _, err = kd.KeyDeriv(&ecdsaPrivateKey{}, &mocks2.KeyDerivOpts{}) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Unsupported 'KeyDerivOpts' provided [") +} + +func TestAESPrivateKeyKeyDeriver(t *testing.T) { + kd := aesPrivateKeyKeyDeriver{} + + _, err := kd.KeyDeriv(&mocks2.MockKey{}, nil) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Invalid opts parameter. It must not be nil.") + + _, err = kd.KeyDeriv(&aesPrivateKey{}, &mocks2.KeyDerivOpts{}) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Unsupported 'KeyDerivOpts' provided [") +} diff --git a/bccsp/sw/mocks/mocks.go b/bccsp/sw/mocks/mocks.go index 947a5f93771..c146a2090f0 100644 --- a/bccsp/sw/mocks/mocks.go +++ b/bccsp/sw/mocks/mocks.go @@ -139,3 +139,22 @@ func (kg *KeyGenerator) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) { return kg.Value, kg.Err } + +type KeyDeriver struct { + KeyArg bccsp.Key + OptsArg bccsp.KeyDerivOpts + + Value bccsp.Key + Err error +} + +func (kd *KeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) { + if !reflect.DeepEqual(kd.KeyArg, k) { + return nil, errors.New("invalid key") + } + if !reflect.DeepEqual(kd.OptsArg, opts) { + return nil, errors.New("invalid opts") + } + + return kd.Value, kd.Err +} diff --git a/bccsp/sw/sw_test.go b/bccsp/sw/sw_test.go index a3f340c31f9..8d40878a21d 100644 --- a/bccsp/sw/sw_test.go +++ b/bccsp/sw/sw_test.go @@ -18,11 +18,13 @@ package sw import ( "errors" - "strings" "testing" + "reflect" + "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/mocks" + mocks2 "github.com/hyperledger/fabric/bccsp/sw/mocks" "github.com/stretchr/testify/assert" ) @@ -33,28 +35,44 @@ func TestKeyGenInvalidInputs(t *testing.T) { _, err = csp.KeyGen(nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid Opts parameter. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid Opts parameter. It must not be nil.") _, err = csp.KeyGen(&mocks.KeyGenOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Unsupported 'KeyGenOpts' provided [")) + assert.Contains(t, err.Error(), "Unsupported 'KeyGenOpts' provided [") _, err = csp.KeyGen(&bccsp.ECDSAP256KeyGenOpts{}) assert.Error(t, err, "Generation of a non-ephemeral key must fail. KeyStore is programmed to fail.") - assert.True(t, strings.Contains(err.Error(), "cannot store key"), "Failure must be due to the KeyStore") + assert.Contains(t, err.Error(), "cannot store key") } func TestKeyDerivInvalidInputs(t *testing.T) { - csp, err := New(256, "SHA2", &mocks.KeyStore{}) + csp, err := New(256, "SHA2", &mocks.KeyStore{StoreKeyErr: errors.New("cannot store key")}) assert.NoError(t, err) _, err = csp.KeyDeriv(nil, &bccsp.ECDSAReRandKeyOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid Key. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid Key. It must not be nil.") + + _, err = csp.KeyDeriv(&mocks.MockKey{}, nil) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Invalid opts. It must not be nil.") _, err = csp.KeyDeriv(&mocks.MockKey{}, &bccsp.ECDSAReRandKeyOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Key type not recognized [")) + assert.Contains(t, err.Error(), "Unsupported 'Key' provided [") + + keyDerivers := make(map[reflect.Type]KeyDeriver) + keyDerivers[reflect.TypeOf(&mocks.MockKey{})] = &mocks2.KeyDeriver{ + KeyArg: &mocks.MockKey{}, + OptsArg: &mocks.KeyDerivOpts{EphemeralValue: false}, + Value: nil, + Err: nil, + } + csp.(*impl).keyDerivers = keyDerivers + _, err = csp.KeyDeriv(&mocks.MockKey{}, &mocks.KeyDerivOpts{EphemeralValue: false}) + assert.Error(t, err, "KeyDerivation of a non-ephemeral key must fail. KeyStore is programmed to fail.") + assert.Contains(t, err.Error(), "cannot store key") } func TestKeyImportInvalidInputs(t *testing.T) { @@ -63,15 +81,15 @@ func TestKeyImportInvalidInputs(t *testing.T) { _, err = csp.KeyImport(nil, &bccsp.AES256ImportKeyOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid raw. Cannot be nil")) + assert.Contains(t, err.Error(), "Invalid raw. Cannot be nil") _, err = csp.KeyImport([]byte{0, 1, 2, 3, 4}, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid Opts parameter. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid Opts parameter. It must not be nil.") _, err = csp.KeyImport([]byte{0, 1, 2, 3, 4}, &mocks.KeyImportOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Unsupported 'KeyImportOptions' provided [")) + assert.Contains(t, err.Error(), "Unsupported 'KeyImportOptions' provided [") } func TestGetKeyInvalidInputs(t *testing.T) { @@ -81,7 +99,7 @@ func TestGetKeyInvalidInputs(t *testing.T) { _, err = csp.GetKey(nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "cannot get key")) + assert.Contains(t, err.Error(), "cannot get key") // Init a BCCSP instance with a key store that returns a given key k := &mocks.MockKey{} @@ -99,15 +117,15 @@ func TestSignInvalidInputs(t *testing.T) { _, err = csp.Sign(nil, []byte{1, 2, 3, 5}, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid Key. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid Key. It must not be nil.") _, err = csp.Sign(&mocks.MockKey{}, nil, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid digest. Cannot be empty.")) + assert.Contains(t, err.Error(), "Invalid digest. Cannot be empty.") _, err = csp.Sign(&mocks.MockKey{}, []byte{1, 2, 3, 5}, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Unsupported 'SignKey' provided [")) + assert.Contains(t, err.Error(), "Unsupported 'SignKey' provided [") } func TestVerifyInvalidInputs(t *testing.T) { @@ -116,19 +134,19 @@ func TestVerifyInvalidInputs(t *testing.T) { _, err = csp.Verify(nil, []byte{1, 2, 3, 5}, []byte{1, 2, 3, 5}, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid Key. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid Key. It must not be nil.") _, err = csp.Verify(&mocks.MockKey{}, nil, []byte{1, 2, 3, 5}, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid signature. Cannot be empty.")) + assert.Contains(t, err.Error(), "Invalid signature. Cannot be empty.") _, err = csp.Verify(&mocks.MockKey{}, []byte{1, 2, 3, 5}, nil, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid digest. Cannot be empty.")) + assert.Contains(t, err.Error(), "Invalid digest. Cannot be empty.") _, err = csp.Verify(&mocks.MockKey{}, []byte{1, 2, 3, 5}, []byte{1, 2, 3, 5}, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Unsupported 'VerifyKey' provided [")) + assert.Contains(t, err.Error(), "Unsupported 'VerifyKey' provided [") } func TestEncryptInvalidInputs(t *testing.T) { @@ -137,11 +155,11 @@ func TestEncryptInvalidInputs(t *testing.T) { _, err = csp.Encrypt(nil, []byte{1, 2, 3, 4}, &bccsp.AESCBCPKCS7ModeOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid Key. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid Key. It must not be nil.") _, err = csp.Encrypt(&mocks.MockKey{}, []byte{1, 2, 3, 4}, &bccsp.AESCBCPKCS7ModeOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Unsupported 'EncryptKey' provided [")) + assert.Contains(t, err.Error(), "Unsupported 'EncryptKey' provided [") } func TestDecryptInvalidInputs(t *testing.T) { @@ -150,11 +168,11 @@ func TestDecryptInvalidInputs(t *testing.T) { _, err = csp.Decrypt(nil, []byte{1, 2, 3, 4}, &bccsp.AESCBCPKCS7ModeOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid Key. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid Key. It must not be nil.") _, err = csp.Decrypt(&mocks.MockKey{}, []byte{1, 2, 3, 4}, &bccsp.AESCBCPKCS7ModeOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Unsupported 'DecryptKey' provided [")) + assert.Contains(t, err.Error(), "Unsupported 'DecryptKey' provided [") } func TestHashInvalidInputs(t *testing.T) { @@ -163,11 +181,11 @@ func TestHashInvalidInputs(t *testing.T) { _, err = csp.Hash(nil, nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid opts. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid opts. It must not be nil.") _, err = csp.Hash(nil, &mocks.HashOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Unsupported 'HashOpt' provided [")) + assert.Contains(t, err.Error(), "Unsupported 'HashOpt' provided [") } func TestGetHashInvalidInputs(t *testing.T) { @@ -176,9 +194,9 @@ func TestGetHashInvalidInputs(t *testing.T) { _, err = csp.GetHash(nil) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Invalid opts. It must not be nil.")) + assert.Contains(t, err.Error(), "Invalid opts. It must not be nil.") _, err = csp.GetHash(&mocks.HashOpts{}) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "Unsupported 'HashOpt' provided [")) + assert.Contains(t, err.Error(), "Unsupported 'HashOpt' provided [") }