diff --git a/bccsp/sw/hash_test.go b/bccsp/sw/hash_test.go index b7a50f174fc..a3ffa9cb60a 100644 --- a/bccsp/sw/hash_test.go +++ b/bccsp/sw/hash_test.go @@ -31,40 +31,59 @@ func TestHash(t *testing.T) { expectetMsg := []byte{1, 2, 3, 4} expectedOpts := &mocks2.HashOpts{} expectetValue := []byte{1, 2, 3, 4, 5} - expectedErr := errors.New("no error") + expectedErr := errors.New("Expected Error") hashers := make(map[reflect.Type]Hasher) hashers[reflect.TypeOf(&mocks2.HashOpts{})] = &mocks.Hasher{ MsgArg: expectetMsg, OptsArg: expectedOpts, Value: expectetValue, - Err: expectedErr, + Err: nil, } - csp := impl{hashers: hashers} - value, err := csp.Hash(expectetMsg, expectedOpts) assert.Equal(t, expectetValue, value) - assert.Equal(t, expectedErr, err) + assert.Nil(t, err) + + hashers = make(map[reflect.Type]Hasher) + hashers[reflect.TypeOf(&mocks2.HashOpts{})] = &mocks.Hasher{ + MsgArg: expectetMsg, + OptsArg: expectedOpts, + Value: nil, + Err: expectedErr, + } + csp = impl{hashers: hashers} + value, err = csp.Hash(expectetMsg, expectedOpts) + assert.Nil(t, value) + assert.Contains(t, err.Error(), expectedErr.Error()) } func TestGetHash(t *testing.T) { expectedOpts := &mocks2.HashOpts{} expectetValue := sha256.New() - expectedErr := errors.New("no error") + expectedErr := errors.New("Expected Error") hashers := make(map[reflect.Type]Hasher) hashers[reflect.TypeOf(&mocks2.HashOpts{})] = &mocks.Hasher{ OptsArg: expectedOpts, ValueHash: expectetValue, - Err: expectedErr, + Err: nil, } - csp := impl{hashers: hashers} - value, err := csp.GetHash(expectedOpts) assert.Equal(t, expectetValue, value) - assert.Equal(t, expectedErr, err) + assert.Nil(t, err) + + hashers = make(map[reflect.Type]Hasher) + hashers[reflect.TypeOf(&mocks2.HashOpts{})] = &mocks.Hasher{ + OptsArg: expectedOpts, + ValueHash: expectetValue, + Err: expectedErr, + } + csp = impl{hashers: hashers} + value, err = csp.GetHash(expectedOpts) + assert.Nil(t, value) + assert.Contains(t, err.Error(), expectedErr.Error()) } func TestHasher(t *testing.T) { diff --git a/bccsp/sw/impl.go b/bccsp/sw/impl.go index 77cedb9b70e..c3ba0610d85 100644 --- a/bccsp/sw/impl.go +++ b/bccsp/sw/impl.go @@ -19,12 +19,11 @@ import ( "crypto/elliptic" "crypto/sha256" "crypto/sha512" - "errors" - "fmt" "hash" "reflect" "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/common/errors" "github.com/hyperledger/fabric/common/flogging" "golang.org/x/crypto/sha3" ) @@ -38,7 +37,7 @@ var ( func NewDefaultSecurityLevel(keyStorePath string) (bccsp.BCCSP, error) { ks := &fileBasedKeyStore{} if err := ks.Init(nil, keyStorePath, false); err != nil { - return nil, fmt.Errorf("Failed initializing key store [%s]", err) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed initializing key store at [%v]", keyStorePath).WrapError(err) } return New(256, "SHA2", ks) @@ -57,12 +56,12 @@ func New(securityLevel int, hashFamily string, keyStore bccsp.KeyStore) (bccsp.B conf := &config{} err := conf.setSecurityLevel(securityLevel, hashFamily) if err != nil { - return nil, fmt.Errorf("Failed initializing configuration [%s]", err) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed initializing configuration at [%v,%v]", securityLevel, hashFamily).WrapError(err) } // Check KeyStore if keyStore == nil { - return nil, errors.New("Invalid bccsp.KeyStore instance. It must be different from nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid bccsp.KeyStore instance. It must be different from nil.") } // Set the encryptors @@ -159,17 +158,17 @@ type impl struct { func (csp *impl) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) { // Validate arguments if opts == nil { - return nil, errors.New("Invalid Opts parameter. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid Opts parameter. It must not be nil.") } keyGenerator, found := csp.keyGenerators[reflect.TypeOf(opts)] if !found { - return nil, fmt.Errorf("Unsupported 'KeyGenOpts' provided [%v]", opts) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'KeyGenOpts' provided [%v]", opts) } k, err = keyGenerator.KeyGen(opts) if err != nil { - return nil, err + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed generating key with opts [%v]", opts).WrapError(err) } // If the key is not Ephemeral, store it. @@ -177,7 +176,7 @@ func (csp *impl) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) { // Store the key err = csp.ks.StoreKey(k) if err != nil { - return nil, fmt.Errorf("Failed storing key [%s]. [%s]", opts.Algorithm(), err) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed storing key [%s]. [%s]", opts.Algorithm(), err) } } @@ -189,20 +188,20 @@ func (csp *impl) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) { func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) { // Validate arguments if k == nil { - return nil, errors.New("Invalid Key. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid Key. It must not be nil.") } if opts == nil { - return nil, errors.New("Invalid opts. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid opts. It must not be nil.") } keyDeriver, found := csp.keyDerivers[reflect.TypeOf(k)] if !found { - return nil, fmt.Errorf("Unsupported 'Key' provided [%v]", k) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'Key' provided [%v]", k) } k, err = keyDeriver.KeyDeriv(k, opts) if err != nil { - return nil, err + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed deriving key with opts [%v]", opts).WrapError(err) } // If the key is not Ephemeral, store it. @@ -210,7 +209,7 @@ func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, e // Store the key err = csp.ks.StoreKey(k) if err != nil { - return nil, fmt.Errorf("Failed storing key [%s]. [%s]", opts.Algorithm(), err) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed storing key [%s]. [%s]", opts.Algorithm(), err) } } @@ -222,20 +221,20 @@ func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, e func (csp *impl) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) { // Validate arguments if raw == nil { - return nil, errors.New("Invalid raw. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid raw. It must not be nil.") } if opts == nil { - return nil, errors.New("Invalid opts. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid opts. It must not be nil.") } keyImporter, found := csp.keyImporters[reflect.TypeOf(opts)] if !found { - return nil, fmt.Errorf("Unsupported 'KeyImportOpts' provided [%v]", opts) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'KeyImportOpts' provided [%v]", opts) } k, err = keyImporter.KeyImport(raw, opts) if err != nil { - return nil, err + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed importing key with opts [%v]", opts).WrapError(err) } // If the key is not Ephemeral, store it. @@ -243,32 +242,42 @@ func (csp *impl) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.K // Store the key err = csp.ks.StoreKey(k) if err != nil { - return nil, fmt.Errorf("Failed storing key [%s]. [%s]", opts.Algorithm(), err) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed storing imported key with opts [%v]", opts).WrapError(err) } } - return k, nil + return } // GetKey returns the key this CSP associates to // the Subject Key Identifier ski. func (csp *impl) GetKey(ski []byte) (k bccsp.Key, err error) { - return csp.ks.GetKey(ski) + k, err = csp.ks.GetKey(ski) + if err != nil { + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed getting key for SKI [%v]", ski).WrapError(err) + } + + return } // Hash hashes messages msg using options opts. func (csp *impl) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error) { // Validate arguments if opts == nil { - return nil, errors.New("Invalid opts. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid opts. It must not be nil.") } hasher, found := csp.hashers[reflect.TypeOf(opts)] if !found { - return nil, fmt.Errorf("Unsupported 'HashOpt' provided [%v]", opts) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'HashOpt' provided [%v]", opts) } - return hasher.Hash(msg, opts) + digest, err = hasher.Hash(msg, opts) + if err != nil { + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed hashing with opts [%v]", opts).WrapError(err) + } + + return } // GetHash returns and instance of hash.Hash using options opts. @@ -276,15 +285,20 @@ func (csp *impl) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error func (csp *impl) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) { // Validate arguments if opts == nil { - return nil, errors.New("Invalid opts. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid opts. It must not be nil.") } hasher, found := csp.hashers[reflect.TypeOf(opts)] if !found { - return nil, fmt.Errorf("Unsupported 'HashOpt' provided [%v]", opts) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'HashOpt' provided [%v]", opts) + } + + h, err = hasher.GetHash(opts) + if err != nil { + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed getting hash function with opts [%v]", opts).WrapError(err) } - return hasher.GetHash(opts) + return } // Sign signs digest using key k. @@ -296,40 +310,49 @@ func (csp *impl) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) { func (csp *impl) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) { // Validate arguments if k == nil { - return nil, errors.New("Invalid Key. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid Key. It must not be nil.") } if len(digest) == 0 { - return nil, errors.New("Invalid digest. Cannot be empty.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid digest. Cannot be empty.") } signer, found := csp.signers[reflect.TypeOf(k)] if !found { - return nil, fmt.Errorf("Unsupported 'SignKey' provided [%v]", k) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'SignKey' provided [%v]", k) } - return signer.Sign(k, digest, opts) + signature, err = signer.Sign(k, digest, opts) + if err != nil { + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed signing with opts [%v]", opts).WrapError(err) + } + + return } // Verify verifies signature against key k and digest func (csp *impl) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) { // Validate arguments if k == nil { - return false, errors.New("Invalid Key. It must not be nil.") + return false, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid Key. It must not be nil.") } if len(signature) == 0 { - return false, errors.New("Invalid signature. Cannot be empty.") + return false, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid signature. Cannot be empty.") } if len(digest) == 0 { - return false, errors.New("Invalid digest. Cannot be empty.") + return false, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid digest. Cannot be empty.") } verifier, found := csp.verifiers[reflect.TypeOf(k)] if !found { - return false, fmt.Errorf("Unsupported 'VerifyKey' provided [%v]", k) + return false, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'VerifyKey' provided [%v]", k) } - return verifier.Verify(k, signature, digest, opts) + valid, err = verifier.Verify(k, signature, digest, opts) + if err != nil { + return false, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed verifing with opts [%v]", opts).WrapError(err) + } + return } // Encrypt encrypts plaintext using key k. @@ -337,12 +360,12 @@ func (csp *impl) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.Signer func (csp *impl) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) (ciphertext []byte, err error) { // Validate arguments if k == nil { - return nil, errors.New("Invalid Key. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid Key. It must not be nil.") } encryptor, found := csp.encryptors[reflect.TypeOf(k)] if !found { - return nil, fmt.Errorf("Unsupported 'EncryptKey' provided [%v]", k) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'EncryptKey' provided [%v]", k) } return encryptor.Encrypt(k, plaintext, opts) @@ -353,13 +376,18 @@ func (csp *impl) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts func (csp *impl) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) (plaintext []byte, err error) { // Validate arguments if k == nil { - return nil, errors.New("Invalid Key. It must not be nil.") + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid Key. It must not be nil.") } decryptor, found := csp.decryptors[reflect.TypeOf(k)] if !found { - return nil, fmt.Errorf("Unsupported 'DecryptKey' provided [%v]", k) + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.NotFound, "Unsupported 'DecryptKey' provided [%v]", k) + } + + plaintext, err = decryptor.Decrypt(k, ciphertext, opts) + if err != nil { + return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed decrypting with opts [%v]", opts).WrapError(err) } - return decryptor.Decrypt(k, ciphertext, opts) + return } diff --git a/bccsp/sw/keyderiv_test.go b/bccsp/sw/keyderiv_test.go index 4e5916ab4f7..a9d6b9de93b 100644 --- a/bccsp/sw/keyderiv_test.go +++ b/bccsp/sw/keyderiv_test.go @@ -30,7 +30,7 @@ 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") + expectedErr := errors.New("Expected Error") keyDerivers := make(map[reflect.Type]KeyDeriver) keyDerivers[reflect.TypeOf(&mocks2.MockKey{})] = &mocks.KeyDeriver{ @@ -41,8 +41,8 @@ func TestKeyDeriv(t *testing.T) { } csp := impl{keyDerivers: keyDerivers} value, err := csp.KeyDeriv(expectedKey, expectedOpts) - assert.Equal(t, nil, value) - assert.Equal(t, expectedErr, err) + assert.Nil(t, value) + assert.Contains(t, err.Error(), expectedErr.Error()) keyDerivers = make(map[reflect.Type]KeyDeriver) keyDerivers[reflect.TypeOf(&mocks2.MockKey{})] = &mocks.KeyDeriver{ @@ -54,7 +54,7 @@ func TestKeyDeriv(t *testing.T) { csp = impl{keyDerivers: keyDerivers} value, err = csp.KeyDeriv(expectedKey, expectedOpts) assert.Equal(t, expectetValue, value) - assert.Equal(t, nil, err) + assert.Nil(t, err) } func TestECDSAPublicKeyKeyDeriver(t *testing.T) { diff --git a/bccsp/sw/keygen_test.go b/bccsp/sw/keygen_test.go index e6ed1a37027..b69becd8123 100644 --- a/bccsp/sw/keygen_test.go +++ b/bccsp/sw/keygen_test.go @@ -30,7 +30,7 @@ import ( func TestKeyGen(t *testing.T) { expectedOpts := &mocks2.KeyGenOpts{EphemeralValue: true} expectetValue := &mocks2.MockKey{} - expectedErr := errors.New("no error") + expectedErr := errors.New("Expected Error") keyGenerators := make(map[reflect.Type]KeyGenerator) keyGenerators[reflect.TypeOf(&mocks2.KeyGenOpts{})] = &mocks.KeyGenerator{ @@ -40,8 +40,8 @@ func TestKeyGen(t *testing.T) { } csp := impl{keyGenerators: keyGenerators} value, err := csp.KeyGen(expectedOpts) - assert.Equal(t, nil, value) - assert.Equal(t, expectedErr, err) + assert.Nil(t, value) + assert.Contains(t, err.Error(), expectedErr.Error()) keyGenerators = make(map[reflect.Type]KeyGenerator) keyGenerators[reflect.TypeOf(&mocks2.KeyGenOpts{})] = &mocks.KeyGenerator{ @@ -52,8 +52,7 @@ func TestKeyGen(t *testing.T) { csp = impl{keyGenerators: keyGenerators} value, err = csp.KeyGen(expectedOpts) assert.Equal(t, expectetValue, value) - assert.Equal(t, nil, err) - + assert.Nil(t, err) } func TestECDSAKeyGenerator(t *testing.T) { diff --git a/bccsp/sw/keyimport_test.go b/bccsp/sw/keyimport_test.go index 52609d988d4..61ccfbed8fa 100644 --- a/bccsp/sw/keyimport_test.go +++ b/bccsp/sw/keyimport_test.go @@ -34,7 +34,7 @@ func TestKeyImport(t *testing.T) { expectedRaw := []byte{1, 2, 3} expectedOpts := &mocks2.KeyDerivOpts{EphemeralValue: true} expectetValue := &mocks2.MockKey{BytesValue: []byte{1, 2, 3, 4, 5}} - expectedErr := errors.New("no error") + expectedErr := errors.New("Expected Error") keyImporters := make(map[reflect.Type]KeyImporter) keyImporters[reflect.TypeOf(&mocks2.KeyDerivOpts{})] = &mocks.KeyImporter{ @@ -45,8 +45,8 @@ func TestKeyImport(t *testing.T) { } csp := impl{keyImporters: keyImporters} value, err := csp.KeyImport(expectedRaw, expectedOpts) - assert.Equal(t, nil, value) - assert.Equal(t, expectedErr, err) + assert.Nil(t, value) + assert.Contains(t, err.Error(), expectedErr.Error()) keyImporters = make(map[reflect.Type]KeyImporter) keyImporters[reflect.TypeOf(&mocks2.KeyDerivOpts{})] = &mocks.KeyImporter{ @@ -58,7 +58,7 @@ func TestKeyImport(t *testing.T) { csp = impl{keyImporters: keyImporters} value, err = csp.KeyImport(expectedRaw, expectedOpts) assert.Equal(t, expectetValue, value) - assert.Equal(t, nil, err) + assert.Nil(t, err) } func TestAES256ImportKeyOptsKeyImporter(t *testing.T) { diff --git a/bccsp/sw/sign_test.go b/bccsp/sw/sign_test.go index 5ec87919f88..f077fdd5dd6 100644 --- a/bccsp/sw/sign_test.go +++ b/bccsp/sw/sign_test.go @@ -31,7 +31,7 @@ func TestSign(t *testing.T) { expectetDigest := []byte{1, 2, 3, 4} expectedOpts := &mocks2.SignerOpts{} expectetValue := []byte{0, 1, 2, 3, 4} - expectedErr := errors.New("no error") + expectedErr := errors.New("Expected Error") signers := make(map[reflect.Type]Signer) signers[reflect.TypeOf(&mocks2.MockKey{})] = &mocks.Signer{ @@ -39,12 +39,23 @@ func TestSign(t *testing.T) { DigestArg: expectetDigest, OptsArg: expectedOpts, Value: expectetValue, - Err: expectedErr, + Err: nil, } - csp := impl{signers: signers} - value, err := csp.Sign(expectedKey, expectetDigest, expectedOpts) assert.Equal(t, expectetValue, value) - assert.Equal(t, expectedErr, err) + assert.Nil(t, err) + + signers = make(map[reflect.Type]Signer) + signers[reflect.TypeOf(&mocks2.MockKey{})] = &mocks.Signer{ + KeyArg: expectedKey, + DigestArg: expectetDigest, + OptsArg: expectedOpts, + Value: nil, + Err: expectedErr, + } + csp = impl{signers: signers} + value, err = csp.Sign(expectedKey, expectetDigest, expectedOpts) + assert.Nil(t, value) + assert.Contains(t, err.Error(), expectedErr.Error()) } diff --git a/bccsp/sw/verify_test.go b/bccsp/sw/verify_test.go index 6b89da7cdf2..8f62203877c 100644 --- a/bccsp/sw/verify_test.go +++ b/bccsp/sw/verify_test.go @@ -32,7 +32,7 @@ func TestVerify(t *testing.T) { expectetDigest := []byte{1, 2, 3, 4} expectedOpts := &mocks2.SignerOpts{} expectetValue := true - expectedErr := errors.New("no error") + expectedErr := errors.New("Expected Error") verifiers := make(map[reflect.Type]Verifier) verifiers[reflect.TypeOf(&mocks2.MockKey{})] = &mocks.Verifier{ @@ -41,12 +41,24 @@ func TestVerify(t *testing.T) { DigestArg: expectetDigest, OptsArg: expectedOpts, Value: expectetValue, - Err: expectedErr, + Err: nil, } - csp := impl{verifiers: verifiers} - value, err := csp.Verify(expectedKey, expectetSignature, expectetDigest, expectedOpts) assert.Equal(t, expectetValue, value) - assert.Equal(t, expectedErr, err) + assert.Nil(t, err) + + verifiers = make(map[reflect.Type]Verifier) + verifiers[reflect.TypeOf(&mocks2.MockKey{})] = &mocks.Verifier{ + KeyArg: expectedKey, + SignatureArg: expectetSignature, + DigestArg: expectetDigest, + OptsArg: expectedOpts, + Value: false, + Err: expectedErr, + } + csp = impl{verifiers: verifiers} + value, err = csp.Verify(expectedKey, expectetSignature, expectetDigest, expectedOpts) + assert.False(t, value) + assert.Contains(t, err.Error(), expectedErr.Error()) }