From f75e07752c4b535ff45e1a04301fe0a3c8a1aaf2 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 6 Dec 2023 17:32:00 +0100
Subject: [PATCH 01/22] rsa and ecdsa key generation and retrieving

---
 .gitignore           |   1 +
 cryptoKeyTypes.go    |  65 +++++++++++++++++++++++
 go.mod               |  26 ++++++++++
 hsmCryptoProvider.go | 120 +++++++++++++++++++++++++++++++++++++++++++
 main.go              |  11 ++++
 types.go             |  25 +++++++++
 6 files changed, 248 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 cryptoKeyTypes.go
 create mode 100644 go.mod
 create mode 100644 hsmCryptoProvider.go
 create mode 100644 main.go
 create mode 100644 types.go

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..723ef36
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.idea
\ No newline at end of file
diff --git a/cryptoKeyTypes.go b/cryptoKeyTypes.go
new file mode 100644
index 0000000..922cac8
--- /dev/null
+++ b/cryptoKeyTypes.go
@@ -0,0 +1,65 @@
+package main
+
+import (
+	"crypto/dsa"
+	"crypto/elliptic"
+	"fmt"
+	"github.com/ThalesIgnite/crypto11"
+	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
+	"math/big"
+	"strconv"
+	"strings"
+)
+
+func (p *HSMCryptoProvider) generateRSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
+	mkt, param, err := splitKeyTypeAndParams(params.KeyType)
+	if err != nil {
+		return nil, err
+	}
+	if mkt == RSA {
+		rsaParams, err := NewRsaParam(param)
+		if err != nil {
+			return nil, err
+		}
+		return p.controller.api.GenerateDSAKeyPair([]byte(params.Identifier.KeyId), rsaParams)
+	}
+	return nil, fmt.Errorf("expected type %v - got %v", RSA, mkt)
+}
+
+func (p *HSMCryptoProvider) generateECDSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
+	mkt, param, err := splitKeyTypeAndParams(params.KeyType)
+	if err != nil {
+		return nil, err
+	}
+	if mkt == ECDSA {
+		var curve elliptic.Curve
+		switch param {
+		case "p256":
+			curve = elliptic.P256()
+		case "p384":
+			curve = elliptic.P384()
+		case "p521":
+			curve = elliptic.P521()
+		}
+		return p.controller.api.GenerateECDSAKeyPair([]byte(params.Identifier.KeyId), curve)
+	}
+	return nil, fmt.Errorf("expected type %v - got %v", ECDSA, mkt)
+}
+
+func NewRsaParam(bitSize string) (*dsa.Parameters, error) {
+	size, err := strconv.ParseInt(bitSize, 2, 64)
+	if err != nil {
+		return nil, err
+	}
+	rsaParams := new(dsa.Parameters)
+	rsaParams.Q = big.NewInt(size)
+	return rsaParams, nil
+}
+
+func splitKeyTypeAndParams(keyType types.KeyType) (MajorKeyType, string, error) {
+	keyData := strings.Split(string(keyType), "-")
+	if len(keyData) != 2 {
+		return "", "", fmt.Errorf("expected %T in a form `type`-`typeParam`. Got %s", keyType, keyType)
+	}
+	return MajorKeyType(keyData[0]), keyData[1], nil
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..7f41b4b
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,26 @@
+module luna-hsm-provider
+
+go 1.21.4
+
+require (
+	github.com/ThalesIgnite/crypto11 v1.2.5
+	gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core v0.0.0-20231119154038-268abaa20c2c
+)
+
+require (
+	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
+	github.com/lestrrat-go/blackmagic v1.0.2 // indirect
+	github.com/lestrrat-go/httpcc v1.0.1 // indirect
+	github.com/lestrrat-go/httprc v1.0.4 // indirect
+	github.com/lestrrat-go/iter v1.0.2 // indirect
+	github.com/lestrrat-go/jwx/v2 v2.0.16 // indirect
+	github.com/lestrrat-go/option v1.0.1 // indirect
+	github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f // indirect
+	github.com/pkg/errors v0.8.1 // indirect
+	github.com/segmentio/asm v1.2.0 // indirect
+	github.com/thales-e-security/pool v0.0.2 // indirect
+	golang.org/x/crypto v0.14.0 // indirect
+	golang.org/x/sys v0.13.0 // indirect
+)
diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
new file mode 100644
index 0000000..131cea6
--- /dev/null
+++ b/hsmCryptoProvider.go
@@ -0,0 +1,120 @@
+package main
+
+import (
+	"context"
+	"crypto"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	b64 "encoding/base64"
+	"fmt"
+	"github.com/ThalesIgnite/crypto11"
+	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
+	"io"
+)
+
+func (p *HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
+	id := []byte(parameter.KeyId)
+	return p.controller.api.FindKeyPair(id, nil)
+}
+
+func (p *HSMCryptoProvider) GetNamespaces(context context.Context) ([]string, error) {
+	//todo
+	return []string{}, nil
+}
+func (p *HSMCryptoProvider) GenerateRandom(context types.CryptoContext, number int) ([]byte, error) {
+	// todo
+	reader, err := p.controller.api.NewRandomReader()
+	if err != nil {
+		return nil, err
+	}
+	b, err := io.ReadAll(reader)
+	if err != nil {
+		return nil, err
+	}
+	return b, nil
+}
+func (p *HSMCryptoProvider) Hash(parameter types.CryptoHashParameter, msg []byte) ([]byte, error) {
+	//todo
+	return nil, nil
+}
+func (p *HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
+	id := []byte(parameter.KeyId)
+	key, err := p.controller.api.FindKey(id, nil)
+	if err != nil {
+		return nil, err
+	}
+	var res []byte
+	key.Encrypt(res, data)
+	return res, nil
+}
+func (p *HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
+	id := []byte(parameter.KeyId)
+	key, err := p.controller.api.FindKey(id, nil)
+	if err != nil {
+		return nil, err
+	}
+	var res []byte
+	key.Decrypt(res, data)
+	return res, nil
+}
+func (p *HSMCryptoProvider) Sign(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
+	signer, err := p.getSigner(parameter)
+	if err != nil {
+		return nil, err
+	}
+	return signer.Sign(p.rand, data, p.controller.signerOptions)
+}
+func (p *HSMCryptoProvider) GetKeys(parameter types.CryptoIdentifier) (*types.CryptoKeySet, error) {
+	// todo
+	return nil, nil
+}
+func (p *HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.CryptoKey, error) {
+	signer, err := p.getSigner(parameter)
+	if err != nil {
+		return nil, err
+	}
+	pubKeyObj := signer.Public()
+	var key = new(types.CryptoKey)
+	if pubKey, ok := pubKeyObj.(*ecdsa.PublicKey); ok {
+		repr, err := pubKey.ECDH()
+		if err != nil {
+			fmt.Printf("Could not convert to ECDH: %s", err.Error())
+		}
+		key.Key = repr.Bytes()
+	} else if pubKey, ok := pubKeyObj.(*dsa.PublicKey); ok {
+		key.Key = pubKey.Y.Bytes()
+	} else if pubKey, ok := pubKeyObj.(*crypto.PublicKey); ok {
+		fmt.Print(pubKey)
+		//	todo other key types
+	} else {
+		return nil, fmt.Errorf("key %s has unsupported key format", parameter.KeyId)
+	}
+	return key, nil
+}
+func (p *HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte, signature []byte) (bool, error) {
+	// todo
+	return false, nil
+
+}
+func (p *HSMCryptoProvider) GenerateKey(parameter types.CryptoKeyParameter) error {
+	switch parameter.KeyType {
+	case types.Rsa2048, types.Rsa3072, types.Rsa4096:
+		_, err := p.generateRSA(parameter)
+		return err
+	case types.Ecdsap256, types.Ecdsap384, types.Ecdsap521:
+		_, err := p.generateECDSA(parameter)
+		return err
+	case types.Aes256GCM:
+	//	todo
+	case types.Ed25519:
+	//	todo
+	default:
+		return fmt.Errorf("unsupported key type %v", parameter.KeyType)
+	}
+	return nil
+}
+func (p *HSMCryptoProvider) GetSeed(context context.Context) string {
+	// todo
+	random, _ := io.ReadAll(p.rand)
+	return b64.StdEncoding.EncodeToString(random)
+}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..c257469
--- /dev/null
+++ b/main.go
@@ -0,0 +1,11 @@
+package main
+
+import (
+	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
+)
+
+var Plugin types.CryptoProviderModule //export Plugin Symbol, dont
+
+func GetCryptoProvider() types.CryptoProvider {
+	return new(HSMCryptoProvider)
+}
diff --git a/types.go b/types.go
new file mode 100644
index 0000000..3ece2e2
--- /dev/null
+++ b/types.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+	"crypto"
+	"github.com/ThalesIgnite/crypto11"
+	"io"
+)
+
+type hsmController struct {
+	config        *crypto11.Config
+	api           *crypto11.Context
+	signerOptions crypto.SignerOpts
+}
+
+type HSMCryptoProvider struct {
+	controller hsmController
+	rand       io.Reader
+}
+
+type MajorKeyType string
+
+const (
+	RSA   MajorKeyType = "rsa"
+	ECDSA MajorKeyType = "ecdsa"
+)
-- 
GitLab


From 0eac3d549262e249dc5ea2a47a29b53038419506 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Thu, 7 Dec 2023 18:19:40 +0100
Subject: [PATCH 02/22] provider methods implemented

---
 cryptoKeyTypes.go    | 22 +++++-----
 hsmCryptoProvider.go | 95 ++++++++++++++++++++++++++++++++------------
 2 files changed, 82 insertions(+), 35 deletions(-)

diff --git a/cryptoKeyTypes.go b/cryptoKeyTypes.go
index 922cac8..53a3d89 100644
--- a/cryptoKeyTypes.go
+++ b/cryptoKeyTypes.go
@@ -1,12 +1,11 @@
 package main
 
 import (
-	"crypto/dsa"
 	"crypto/elliptic"
+	"errors"
 	"fmt"
 	"github.com/ThalesIgnite/crypto11"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
-	"math/big"
 	"strconv"
 	"strings"
 )
@@ -17,11 +16,12 @@ func (p *HSMCryptoProvider) generateRSA(params types.CryptoKeyParameter) (crypto
 		return nil, err
 	}
 	if mkt == RSA {
-		rsaParams, err := NewRsaParam(param)
+		bits, err := strconv.Atoi(param)
 		if err != nil {
 			return nil, err
 		}
-		return p.controller.api.GenerateDSAKeyPair([]byte(params.Identifier.KeyId), rsaParams)
+		id := []byte(params.Identifier.KeyId)
+		return p.controller.api.GenerateRSAKeyPair(id, bits)
 	}
 	return nil, fmt.Errorf("expected type %v - got %v", RSA, mkt)
 }
@@ -46,14 +46,16 @@ func (p *HSMCryptoProvider) generateECDSA(params types.CryptoKeyParameter) (cryp
 	return nil, fmt.Errorf("expected type %v - got %v", ECDSA, mkt)
 }
 
-func NewRsaParam(bitSize string) (*dsa.Parameters, error) {
-	size, err := strconv.ParseInt(bitSize, 2, 64)
-	if err != nil {
+func (p *HSMCryptoProvider) generateEDDSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
+	return nil, errors.ErrUnsupported
+}
+
+func (p *HSMCryptoProvider) generateAES(params types.CryptoKeyParameter) (crypto11.Signer, error) {
+	if params.KeyType == types.Aes256GCM {
+		_, err := p.controller.api.GenerateSecretKey([]byte(params.Identifier.KeyId), 256, crypto11.CipherAES)
 		return nil, err
 	}
-	rsaParams := new(dsa.Parameters)
-	rsaParams.Q = big.NewInt(size)
-	return rsaParams, nil
+	return nil, fmt.Errorf("expected type %s got %s", types.Aes256GCM, params.KeyType)
 }
 
 func splitKeyTypeAndParams(keyType types.KeyType) (MajorKeyType, string, error) {
diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index 131cea6..808c5a6 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -3,13 +3,16 @@ package main
 import (
 	"context"
 	"crypto"
-	"crypto/dsa"
 	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/sha256"
+	"crypto/x509"
 	b64 "encoding/base64"
+	"errors"
 	"fmt"
 	"github.com/ThalesIgnite/crypto11"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
-	"io"
+	"math/rand"
 )
 
 func (p *HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
@@ -18,24 +21,34 @@ func (p *HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto1
 }
 
 func (p *HSMCryptoProvider) GetNamespaces(context context.Context) ([]string, error) {
-	//todo
-	return []string{}, nil
+	return nil, errors.ErrUnsupported
 }
 func (p *HSMCryptoProvider) GenerateRandom(context types.CryptoContext, number int) ([]byte, error) {
-	// todo
+	key := make([]byte, number)
 	reader, err := p.controller.api.NewRandomReader()
 	if err != nil {
 		return nil, err
 	}
-	b, err := io.ReadAll(reader)
+	_, err = reader.Read(key)
 	if err != nil {
 		return nil, err
 	}
-	return b, nil
+	return key, nil
 }
 func (p *HSMCryptoProvider) Hash(parameter types.CryptoHashParameter, msg []byte) ([]byte, error) {
-	//todo
-	return nil, nil
+	// todo use hsm?
+	if parameter.HashAlgorithm == types.Sha2256 {
+		msgHash := sha256.New()
+		_, err := msgHash.Write(msg)
+		if err != nil {
+			return nil, err
+		}
+		msgHashSum := msgHash.Sum(nil)
+		return msgHashSum, nil
+	} else {
+		return nil, errors.ErrUnsupported
+	}
+
 }
 func (p *HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
 	id := []byte(parameter.KeyId)
@@ -65,8 +78,13 @@ func (p *HSMCryptoProvider) Sign(parameter types.CryptoIdentifier, data []byte)
 	return signer.Sign(p.rand, data, p.controller.signerOptions)
 }
 func (p *HSMCryptoProvider) GetKeys(parameter types.CryptoIdentifier) (*types.CryptoKeySet, error) {
-	// todo
-	return nil, nil
+	key, err := p.GetKey(parameter)
+	if err != nil {
+		return nil, err
+	} else {
+		keySet := &types.CryptoKeySet{Keys: []types.CryptoKey{*key}}
+		return keySet, nil
+	}
 }
 func (p *HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.CryptoKey, error) {
 	signer, err := p.getSigner(parameter)
@@ -75,26 +93,48 @@ func (p *HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.Cry
 	}
 	pubKeyObj := signer.Public()
 	var key = new(types.CryptoKey)
+
 	if pubKey, ok := pubKeyObj.(*ecdsa.PublicKey); ok {
 		repr, err := pubKey.ECDH()
 		if err != nil {
-			fmt.Printf("Could not convert to ECDH: %s", err.Error())
+			return nil, err
 		}
 		key.Key = repr.Bytes()
-	} else if pubKey, ok := pubKeyObj.(*dsa.PublicKey); ok {
-		key.Key = pubKey.Y.Bytes()
-	} else if pubKey, ok := pubKeyObj.(*crypto.PublicKey); ok {
-		fmt.Print(pubKey)
-		//	todo other key types
+
+	} else if pubKey, ok := pubKeyObj.(*rsa.PublicKey); ok {
+		keyBytes, err := x509.MarshalPKIXPublicKey(pubKey)
+		if err != nil {
+			return nil, err
+		}
+		key.Key = keyBytes
+
+	} else if pubKey, ok := pubKeyObj.(*crypto11.SecretKey); ok {
+		return nil, fmt.Errorf("keys of type %T are not retrievable", pubKey)
+
 	} else {
 		return nil, fmt.Errorf("key %s has unsupported key format", parameter.KeyId)
 	}
 	return key, nil
 }
 func (p *HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte, signature []byte) (bool, error) {
-	// todo
-	return false, nil
-
+	signer, err := p.getSigner(parameter)
+	if err != nil {
+		return false, err
+	}
+	pubKeyObj := signer.Public()
+	if pubKey, ok := pubKeyObj.(*ecdsa.PublicKey); ok {
+		hashed := sha256.Sum256(data)
+		result := ecdsa.VerifyASN1(pubKey, hashed[:], signature)
+		return result, nil
+	} else if pubKey, ok := pubKeyObj.(*rsa.PublicKey); ok {
+		hashed := sha256.Sum256(data)
+		err = rsa.VerifyPSS(pubKey, crypto.SHA256, hashed[:], signature, nil)
+		return err == nil, err
+	} else if pubKey, ok := pubKeyObj.(*crypto11.SecretKey); ok {
+		return false, fmt.Errorf("keys of type %T are not retrievable", pubKey)
+	} else {
+		return false, fmt.Errorf("key %s has unsupported key format", parameter.KeyId)
+	}
 }
 func (p *HSMCryptoProvider) GenerateKey(parameter types.CryptoKeyParameter) error {
 	switch parameter.KeyType {
@@ -105,16 +145,21 @@ func (p *HSMCryptoProvider) GenerateKey(parameter types.CryptoKeyParameter) erro
 		_, err := p.generateECDSA(parameter)
 		return err
 	case types.Aes256GCM:
-	//	todo
+		_, err := p.generateAES(parameter)
+		return err
 	case types.Ed25519:
-	//	todo
+		_, err := p.generateEDDSA(parameter)
+		return err
 	default:
 		return fmt.Errorf("unsupported key type %v", parameter.KeyType)
 	}
-	return nil
 }
 func (p *HSMCryptoProvider) GetSeed(context context.Context) string {
-	// todo
-	random, _ := io.ReadAll(p.rand)
+	n := rand.Int()
+	random, err := p.GenerateRandom(types.CryptoContext{}, n)
+	if err != nil {
+		fmt.Print(err.Error())
+		return ""
+	}
 	return b64.StdEncoding.EncodeToString(random)
 }
-- 
GitLab


From 4ce3d25f66da097e188af7fa8ef6c5bfae455d0a Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Fri, 8 Dec 2023 17:45:23 +0100
Subject: [PATCH 03/22] test implemented

---
 cryptoKeyTypes.go         |  8 ++++----
 go.mod                    | 22 ++++++++++++++++++++-
 hsmController.go          | 20 +++++++++++++++++++
 hsmCryptoProvider.go      | 29 ++++++++++++++-------------
 hsmCryptoProvider_test.go | 41 +++++++++++++++++++++++++++++++++++++++
 main.go                   | 21 +++++++++++++++++---
 types.go                  |  4 ++--
 7 files changed, 122 insertions(+), 23 deletions(-)
 create mode 100644 hsmController.go
 create mode 100644 hsmCryptoProvider_test.go

diff --git a/cryptoKeyTypes.go b/cryptoKeyTypes.go
index 53a3d89..e0d2f5c 100644
--- a/cryptoKeyTypes.go
+++ b/cryptoKeyTypes.go
@@ -10,7 +10,7 @@ import (
 	"strings"
 )
 
-func (p *HSMCryptoProvider) generateRSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
+func (p HSMCryptoProvider) generateRSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
 	mkt, param, err := splitKeyTypeAndParams(params.KeyType)
 	if err != nil {
 		return nil, err
@@ -26,7 +26,7 @@ func (p *HSMCryptoProvider) generateRSA(params types.CryptoKeyParameter) (crypto
 	return nil, fmt.Errorf("expected type %v - got %v", RSA, mkt)
 }
 
-func (p *HSMCryptoProvider) generateECDSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
+func (p HSMCryptoProvider) generateECDSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
 	mkt, param, err := splitKeyTypeAndParams(params.KeyType)
 	if err != nil {
 		return nil, err
@@ -46,11 +46,11 @@ func (p *HSMCryptoProvider) generateECDSA(params types.CryptoKeyParameter) (cryp
 	return nil, fmt.Errorf("expected type %v - got %v", ECDSA, mkt)
 }
 
-func (p *HSMCryptoProvider) generateEDDSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
+func (p HSMCryptoProvider) generateEDDSA(params types.CryptoKeyParameter) (crypto11.Signer, error) {
 	return nil, errors.ErrUnsupported
 }
 
-func (p *HSMCryptoProvider) generateAES(params types.CryptoKeyParameter) (crypto11.Signer, error) {
+func (p HSMCryptoProvider) generateAES(params types.CryptoKeyParameter) (crypto11.Signer, error) {
 	if params.KeyType == types.Aes256GCM {
 		_, err := p.controller.api.GenerateSecretKey([]byte(params.Identifier.KeyId), 256, crypto11.CipherAES)
 		return nil, err
diff --git a/go.mod b/go.mod
index 7f41b4b..048bd1e 100644
--- a/go.mod
+++ b/go.mod
@@ -3,24 +3,44 @@ module luna-hsm-provider
 go 1.21.4
 
 require (
+	bou.ke/monkey v1.0.2
 	github.com/ThalesIgnite/crypto11 v1.2.5
+	github.com/spf13/viper v1.17.0
 	gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core v0.0.0-20231119154038-268abaa20c2c
 )
 
 require (
 	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
+	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/goccy/go-json v0.10.2 // indirect
 	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
+	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/lestrrat-go/blackmagic v1.0.2 // indirect
 	github.com/lestrrat-go/httpcc v1.0.1 // indirect
 	github.com/lestrrat-go/httprc v1.0.4 // indirect
 	github.com/lestrrat-go/iter v1.0.2 // indirect
 	github.com/lestrrat-go/jwx/v2 v2.0.16 // indirect
 	github.com/lestrrat-go/option v1.0.1 // indirect
+	github.com/magiconair/properties v1.8.7 // indirect
 	github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f // indirect
-	github.com/pkg/errors v0.8.1 // indirect
+	github.com/mitchellh/mapstructure v1.5.0 // indirect
+	github.com/pelletier/go-toml/v2 v2.1.0 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/sagikazarmark/locafero v0.3.0 // indirect
+	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
 	github.com/segmentio/asm v1.2.0 // indirect
+	github.com/sourcegraph/conc v0.3.0 // indirect
+	github.com/spf13/afero v1.10.0 // indirect
+	github.com/spf13/cast v1.5.1 // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/subosito/gotenv v1.6.0 // indirect
 	github.com/thales-e-security/pool v0.0.2 // indirect
+	go.uber.org/atomic v1.9.0 // indirect
+	go.uber.org/multierr v1.9.0 // indirect
 	golang.org/x/crypto v0.14.0 // indirect
+	golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
 	golang.org/x/sys v0.13.0 // indirect
+	golang.org/x/text v0.13.0 // indirect
+	gopkg.in/ini.v1 v1.67.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/hsmController.go b/hsmController.go
new file mode 100644
index 0000000..a151e20
--- /dev/null
+++ b/hsmController.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+	"fmt"
+	"github.com/ThalesIgnite/crypto11"
+)
+
+func (c hsmController) withApiAndRandomReader() (*hsmController, error) {
+	ctx, err := crypto11.Configure(c.config)
+	if err != nil {
+		fmt.Printf("failed configuring %v", err.Error())
+		return nil, err
+	}
+	randReader, err := ctx.NewRandomReader()
+	if err != nil {
+		return nil, err
+	}
+	controller := &hsmController{api: ctx, config: c.config, signerOptions: c.signerOptions, rand: randReader}
+	return controller, nil
+}
diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index 808c5a6..f8afc56 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -15,15 +15,15 @@ import (
 	"math/rand"
 )
 
-func (p *HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
+func (p HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
 	id := []byte(parameter.KeyId)
 	return p.controller.api.FindKeyPair(id, nil)
 }
 
-func (p *HSMCryptoProvider) GetNamespaces(context context.Context) ([]string, error) {
+func (p HSMCryptoProvider) GetNamespaces(context context.Context) ([]string, error) {
 	return nil, errors.ErrUnsupported
 }
-func (p *HSMCryptoProvider) GenerateRandom(context types.CryptoContext, number int) ([]byte, error) {
+func (p HSMCryptoProvider) GenerateRandom(context types.CryptoContext, number int) ([]byte, error) {
 	key := make([]byte, number)
 	reader, err := p.controller.api.NewRandomReader()
 	if err != nil {
@@ -35,7 +35,7 @@ func (p *HSMCryptoProvider) GenerateRandom(context types.CryptoContext, number i
 	}
 	return key, nil
 }
-func (p *HSMCryptoProvider) Hash(parameter types.CryptoHashParameter, msg []byte) ([]byte, error) {
+func (p HSMCryptoProvider) Hash(parameter types.CryptoHashParameter, msg []byte) ([]byte, error) {
 	// todo use hsm?
 	if parameter.HashAlgorithm == types.Sha2256 {
 		msgHash := sha256.New()
@@ -50,7 +50,7 @@ func (p *HSMCryptoProvider) Hash(parameter types.CryptoHashParameter, msg []byte
 	}
 
 }
-func (p *HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
+func (p HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
 	id := []byte(parameter.KeyId)
 	key, err := p.controller.api.FindKey(id, nil)
 	if err != nil {
@@ -60,7 +60,7 @@ func (p *HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byt
 	key.Encrypt(res, data)
 	return res, nil
 }
-func (p *HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
+func (p HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
 	id := []byte(parameter.KeyId)
 	key, err := p.controller.api.FindKey(id, nil)
 	if err != nil {
@@ -70,14 +70,17 @@ func (p *HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byt
 	key.Decrypt(res, data)
 	return res, nil
 }
-func (p *HSMCryptoProvider) Sign(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
+func (p HSMCryptoProvider) Sign(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
 	signer, err := p.getSigner(parameter)
 	if err != nil {
 		return nil, err
 	}
-	return signer.Sign(p.rand, data, p.controller.signerOptions)
+	if err != nil {
+		return nil, err
+	}
+	return signer.Sign(p.controller.rand, data, p.controller.signerOptions)
 }
-func (p *HSMCryptoProvider) GetKeys(parameter types.CryptoIdentifier) (*types.CryptoKeySet, error) {
+func (p HSMCryptoProvider) GetKeys(parameter types.CryptoIdentifier) (*types.CryptoKeySet, error) {
 	key, err := p.GetKey(parameter)
 	if err != nil {
 		return nil, err
@@ -86,7 +89,7 @@ func (p *HSMCryptoProvider) GetKeys(parameter types.CryptoIdentifier) (*types.Cr
 		return keySet, nil
 	}
 }
-func (p *HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.CryptoKey, error) {
+func (p HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.CryptoKey, error) {
 	signer, err := p.getSigner(parameter)
 	if err != nil {
 		return nil, err
@@ -116,7 +119,7 @@ func (p *HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.Cry
 	}
 	return key, nil
 }
-func (p *HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte, signature []byte) (bool, error) {
+func (p HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte, signature []byte) (bool, error) {
 	signer, err := p.getSigner(parameter)
 	if err != nil {
 		return false, err
@@ -136,7 +139,7 @@ func (p *HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte
 		return false, fmt.Errorf("key %s has unsupported key format", parameter.KeyId)
 	}
 }
-func (p *HSMCryptoProvider) GenerateKey(parameter types.CryptoKeyParameter) error {
+func (p HSMCryptoProvider) GenerateKey(parameter types.CryptoKeyParameter) error {
 	switch parameter.KeyType {
 	case types.Rsa2048, types.Rsa3072, types.Rsa4096:
 		_, err := p.generateRSA(parameter)
@@ -154,7 +157,7 @@ func (p *HSMCryptoProvider) GenerateKey(parameter types.CryptoKeyParameter) erro
 		return fmt.Errorf("unsupported key type %v", parameter.KeyType)
 	}
 }
-func (p *HSMCryptoProvider) GetSeed(context context.Context) string {
+func (p HSMCryptoProvider) GetSeed(context context.Context) string {
 	n := rand.Int()
 	random, err := p.GenerateRandom(types.CryptoContext{}, n)
 	if err != nil {
diff --git a/hsmCryptoProvider_test.go b/hsmCryptoProvider_test.go
new file mode 100644
index 0000000..890b7e2
--- /dev/null
+++ b/hsmCryptoProvider_test.go
@@ -0,0 +1,41 @@
+package main
+
+import (
+	"bou.ke/monkey"
+	"crypto/elliptic"
+	"crypto/rand"
+	"github.com/ThalesIgnite/crypto11"
+	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
+	"reflect"
+	"testing"
+)
+
+var testId = "test id"
+
+func getTestHSMCryptoProvider() HSMCryptoProvider {
+	return HSMCryptoProvider{
+		controller: &hsmController{
+			config: &crypto11.Config{},
+			rand:   rand.Reader,
+			api:    &crypto11.Context{},
+		},
+	}
+}
+
+func TestHSMCryptoProvider_GenerateKey(t *testing.T) {
+	defer monkey.UnpatchAll()
+	var mockGenerateECDSA = func(ctx *crypto11.Context, id []byte, curve elliptic.Curve) (crypto11.Signer, error) {
+		if string(id) != testId {
+			t.Errorf("expected %s actual %s", testId, string(id))
+		}
+		if curve != elliptic.P256() {
+			t.Errorf("expected %s actual %s", elliptic.P256().Params().Name, curve.Params().Name)
+
+		}
+		return nil, nil
+	}
+	monkey.PatchInstanceMethod(reflect.TypeOf(&crypto11.Context{}), "GenerateECDSAKeyPair", mockGenerateECDSA)
+	provider := getTestHSMCryptoProvider()
+	param := types.CryptoKeyParameter{KeyType: types.Ecdsap256, Identifier: types.CryptoIdentifier{KeyId: testId}}
+	_ = provider.GenerateKey(param)
+}
diff --git a/main.go b/main.go
index c257469..fa66220 100644
--- a/main.go
+++ b/main.go
@@ -1,11 +1,26 @@
 package main
 
 import (
+	"github.com/ThalesIgnite/crypto11"
+	"github.com/spf13/viper"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
 )
 
-var Plugin types.CryptoProviderModule //export Plugin Symbol, dont
+var Plugin types.CryptoProviderModule = plugin{} //export Plugin Symbol, dont
 
-func GetCryptoProvider() types.CryptoProvider {
-	return new(HSMCryptoProvider)
+type plugin struct{}
+
+func (p plugin) GetCryptoProvider() types.CryptoProvider {
+	config := crypto11.Config{
+		Path:       viper.GetString("CRYPTO_EXECUTABLE_PATH"),
+		TokenLabel: viper.GetString("HSM_PARTITION_LABEL"),
+		Pin:        viper.GetString("HSM_PARTITION_PASSWORD"),
+	}
+	def := hsmController{config: &config, signerOptions: nil}
+	controller, err := def.withApiAndRandomReader()
+	if err != nil {
+		panic(err)
+	}
+	provider := HSMCryptoProvider{controller: controller}
+	return provider
 }
diff --git a/types.go b/types.go
index 3ece2e2..da50c2d 100644
--- a/types.go
+++ b/types.go
@@ -10,11 +10,11 @@ type hsmController struct {
 	config        *crypto11.Config
 	api           *crypto11.Context
 	signerOptions crypto.SignerOpts
+	rand          io.Reader
 }
 
 type HSMCryptoProvider struct {
-	controller hsmController
-	rand       io.Reader
+	controller *hsmController
 }
 
 type MajorKeyType string
-- 
GitLab


From 6a0021e32a3c47a028872126d46e869bff3e857f Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 13 Dec 2023 11:52:36 +0100
Subject: [PATCH 04/22] tests added

---
 go.mod                    |   5 +-
 go.sum                    | 557 ++++++++++++++++++++++++++++++++++++++
 hsmContextMock_test.go    | 250 +++++++++++++++++
 hsmCryptoProvider.go      |   8 +-
 hsmCryptoProvider_test.go |  36 +--
 types.go                  | 116 +++++++-
 6 files changed, 952 insertions(+), 20 deletions(-)
 create mode 100644 go.sum
 create mode 100644 hsmContextMock_test.go

diff --git a/go.mod b/go.mod
index 048bd1e..703c2b3 100644
--- a/go.mod
+++ b/go.mod
@@ -3,13 +3,14 @@ module luna-hsm-provider
 go 1.21.4
 
 require (
-	bou.ke/monkey v1.0.2
 	github.com/ThalesIgnite/crypto11 v1.2.5
 	github.com/spf13/viper v1.17.0
+	github.com/stretchr/testify v1.8.4
 	gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core v0.0.0-20231119154038-268abaa20c2c
 )
 
 require (
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/goccy/go-json v0.10.2 // indirect
@@ -26,6 +27,7 @@ require (
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/pelletier/go-toml/v2 v2.1.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
 	github.com/sagikazarmark/locafero v0.3.0 // indirect
 	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
 	github.com/segmentio/asm v1.2.0 // indirect
@@ -33,6 +35,7 @@ require (
 	github.com/spf13/afero v1.10.0 // indirect
 	github.com/spf13/cast v1.5.1 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/stretchr/objx v0.5.0 // indirect
 	github.com/subosito/gotenv v1.6.0 // indirect
 	github.com/thales-e-security/pool v0.0.2 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..ce7a319
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,557 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
+cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
+cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
+cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E=
+github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
+github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
+github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
+github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
+github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
+github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
+github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8=
+github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
+github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
+github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
+github.com/lestrrat-go/jwx/v2 v2.0.16 h1:TuH3dBkYTy2giQg/9D8f20znS3JtMRuQJ372boS3lWk=
+github.com/lestrrat-go/jwx/v2 v2.0.16/go.mod h1:jBHyESp4e7QxfERM0UKkQ80/94paqNIEcdEfiUYz5zE=
+github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
+github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
+github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
+github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f h1:eVB9ELsoq5ouItQBr5Tj334bhPJG/MX+m7rTchmzVUQ=
+github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
+github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ=
+github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
+github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
+github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
+github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
+github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
+github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
+github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
+github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
+github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
+github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
+github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
+github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
+github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gtvVDbmPg=
+github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core v0.0.0-20231119154038-268abaa20c2c h1:yP/AgqO5R9yJUidPR0JmmZL3Wg/0U2lucIL58EhRcdQ=
+gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core v0.0.0-20231119154038-268abaa20c2c/go.mod h1:6RSRbAdy0XX7FXdJcs0PCBoZ9TRwY8Tj9NmRRicyTMk=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
+go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
+go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
+google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/hsmContextMock_test.go b/hsmContextMock_test.go
new file mode 100644
index 0000000..5b7a6fa
--- /dev/null
+++ b/hsmContextMock_test.go
@@ -0,0 +1,250 @@
+package main
+
+import (
+	"crypto"
+	"crypto/elliptic"
+	"crypto/rand"
+	"github.com/ThalesIgnite/crypto11"
+	"github.com/stretchr/testify/mock"
+	"io"
+)
+
+type ContextTypeMock struct {
+	mock.Mock
+}
+
+type SignerMock struct {
+	public crypto.PublicKey
+}
+
+func (s *SignerMock) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
+	return []byte("signed"), nil
+}
+func (s *SignerMock) Delete() error {
+	return nil
+}
+func (s *SignerMock) Public() crypto.PublicKey {
+	return s.public
+}
+
+// GenerateRSAKeyPair creates an RSA key pair on the token. The id parameter is used to
+// set CKA_ID and must be non-nil. RSA private keys are generated with both sign and decrypt
+// permissions, and a public exponent of 65537.
+func (t *ContextTypeMock) GenerateRSAKeyPair(id []byte, bits int) (crypto11.SignerDecrypter, error) {
+
+	args := t.Called(id, bits)
+
+	return args.Get(0).(crypto11.SignerDecrypter), args.Error(1)
+}
+
+// GenerateRSAKeyPairWithLabel creates an RSA key pair on the token. The id and label parameters are used to
+// set CKA_ID and CKA_LABEL respectively and must be non-nil. RSA private keys are generated with both sign and decrypt
+// permissions, and a public exponent of 65537.
+
+func (t *ContextTypeMock) GenerateRSAKeyPairWithLabel(id, label []byte, bits int) (crypto11.SignerDecrypter, error) {
+
+	args := t.Called(id, label, bits)
+
+	return args.Get(0).(crypto11.SignerDecrypter), args.Error(1)
+}
+
+// GenerateRSAKeyPairWithAttributes generates an RSA key pair on the token. After this function returns, public and
+// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to
+// a default value.
+func (t *ContextTypeMock) GenerateRSAKeyPairWithAttributes(public, private crypto11.AttributeSet, bits int) (crypto11.SignerDecrypter, error) {
+
+	args := t.Called(public, private, bits)
+
+	return args.Get(0).(crypto11.SignerDecrypter), args.Error(1)
+}
+
+// FindKeyPair retrieves a previously created asymmetric key pair, or nil if it cannot be found.
+//
+// At least one of id and label must be specified.
+// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+// because we cannot implement crypto.Signer without the public key.
+func (t *ContextTypeMock) FindKeyPair(id []byte, label []byte) (crypto11.Signer, error) {
+
+	args := t.Called(id, label)
+
+	return args.Get(0).(crypto11.Signer), args.Error(1)
+}
+
+// FindKeyPairs retrieves all matching asymmetric key pairs, or a nil slice if none can be found.
+//
+// At least one of id and label must be specified.
+// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+// because we cannot implement crypto.Signer without the public key.
+func (t *ContextTypeMock) FindKeyPairs(id []byte, label []byte) (signer []crypto11.Signer, err error) {
+
+	args := t.Called(id, label)
+
+	return args.Get(0).([]crypto11.Signer), args.Error(1)
+}
+
+// FindKeyPairWithAttributes retrieves a previously created asymmetric key pair, or nil if it cannot be found.
+// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID
+// and CKA_LABEL values is found.
+//
+// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+// because we cannot implement crypto.Signer without the public key.
+func (t *ContextTypeMock) FindKeyPairWithAttributes(attributes crypto11.AttributeSet) (crypto11.Signer, error) {
+
+	args := t.Called(attributes)
+
+	return args.Get(0).(crypto11.Signer), args.Error(1)
+}
+
+// FindKeyPairsWithAttributes retrieves previously created asymmetric key pairs, or nil if none can be found.
+// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID
+// and CKA_LABEL values is found.
+//
+// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+// because we cannot implement crypto.Signer without the public key.
+func (t *ContextTypeMock) FindKeyPairsWithAttributes(attributes crypto11.AttributeSet) (signer []crypto11.Signer, err error) {
+
+	args := t.Called(attributes)
+
+	return args.Get(0).([]crypto11.Signer), args.Error(1)
+}
+
+// FindAllKeyPairs retrieves all existing asymmetric key pairs, or a nil slice if none can be found.
+//
+// If a private key is found, but the corresponding public key is not, the key is not returned because we cannot
+// implement crypto.Signer without the public key.
+func (t *ContextTypeMock) FindAllKeyPairs() ([]crypto11.Signer, error) {
+
+	args := t.Called()
+
+	return args.Get(0).([]crypto11.Signer), args.Error(1)
+}
+
+// FindKey retrieves a previously created symmetric key, or nil if it cannot be found.
+//
+// Either (but not both) of id and label may be nil, in which case they are ignored.
+func (t *ContextTypeMock) FindKey(id []byte, label []byte) (*crypto11.SecretKey, error) {
+
+	args := t.Called(id, label)
+
+	return args.Get(0).(*crypto11.SecretKey), args.Error(1)
+}
+
+// FindKeys retrieves all matching symmetric keys, or a nil slice if none can be found.
+//
+// At least one of id and label must be specified.
+func (t *ContextTypeMock) FindKeys(id []byte, label []byte) (key []*crypto11.SecretKey, err error) {
+
+	args := t.Called(id, label)
+
+	return args.Get(0).([]*crypto11.SecretKey), args.Error(1)
+}
+
+// FindKeyWithAttributes retrieves a previously created symmetric key, or nil if it cannot be found.
+func (t *ContextTypeMock) FindKeyWithAttributes(attributes crypto11.AttributeSet) (*crypto11.SecretKey, error) {
+
+	args := t.Called(attributes)
+
+	return args.Get(0).(*crypto11.SecretKey), args.Error(1)
+}
+
+// FindKeysWithAttributes retrieves previously created symmetric keys, or a nil slice if none can be found.
+func (t *ContextTypeMock) FindKeysWithAttributes(attributes crypto11.AttributeSet) ([]*crypto11.SecretKey, error) {
+
+	args := t.Called(attributes)
+
+	return args.Get(0).([]*crypto11.SecretKey), args.Error(1)
+}
+
+// FindAllKeyPairs retrieves all existing symmetric keys, or a nil slice if none can be found.
+func (t *ContextTypeMock) FindAllKeys() ([]*crypto11.SecretKey, error) {
+
+	args := t.Called()
+
+	return args.Get(0).([]*crypto11.SecretKey), args.Error(1)
+}
+
+// GetAttributes gets the values of the specified attributes on the given key or keypair.
+// If the key is asymmetric, then the attributes are retrieved from the private half.
+//
+// If the object is not a crypto11 key or keypair then an error is returned.
+func (t *ContextTypeMock) GetAttributes(key interface{}, attributes []crypto11.AttributeType) (a crypto11.AttributeSet, err error) {
+	return nil, nil
+}
+
+// GetAttribute gets the value of the specified attribute on the given key or keypair.
+// If the key is asymmetric, then the attribute is retrieved from the private half.
+//
+// If the object is not a crypto11 key or keypair then an error is returned.
+func (t *ContextTypeMock) GetAttribute(key interface{}, attribute crypto11.AttributeType) (a *crypto11.Attribute, err error) {
+	return nil, nil
+}
+
+// GetPubAttributes gets the values of the specified attributes on the public half of the given keypair.
+//
+// If the object is not a crypto11 keypair then an error is returned.
+func (t *ContextTypeMock) GetPubAttributes(key interface{}, attributes []crypto11.AttributeType) (a crypto11.AttributeSet, err error) {
+	return nil, nil
+}
+
+// GetPubAttribute gets the value of the specified attribute on the public half of the given key.
+//
+// If the object is not a crypto11 keypair then an error is returned.
+func (t *ContextTypeMock) GetPubAttribute(key interface{}, attribute crypto11.AttributeType) (a *crypto11.Attribute, err error) {
+	return nil, nil
+}
+
+// GenerateECDSAKeyPair creates a ECDSA key pair on the token using curve c. The id parameter is used to
+// set CKA_ID and must be non-nil. Only a limited set of named elliptic curves are supported. The
+// underlying PKCS#11 implementation may impose further restrictions.
+func (t *ContextTypeMock) GenerateECDSAKeyPair(id []byte, curve elliptic.Curve) (crypto11.Signer, error) {
+
+	args := t.Called(id, curve)
+
+	return args.Get(0).(crypto11.Signer), args.Error(1)
+}
+
+// GenerateECDSAKeyPairWithLabel creates a ECDSA key pair on the token using curve c. The id and label parameters are used to
+// set CKA_ID and CKA_LABEL respectively and must be non-nil. Only a limited set of named elliptic curves are supported. The
+// underlying PKCS#11 implementation may impose further restrictions.
+func (t *ContextTypeMock) GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (crypto11.Signer, error) {
+
+	args := t.Called(id, label, curve)
+
+	return args.Get(0).(crypto11.Signer), args.Error(1)
+}
+
+// GenerateECDSAKeyPairWithAttributes generates an ECDSA key pair on the token. After this function returns, public and
+// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to
+// a default value.
+func (t *ContextTypeMock) GenerateECDSAKeyPairWithAttributes(public, private crypto11.AttributeSet, curve elliptic.Curve) (crypto11.Signer, error) {
+	return nil, nil
+}
+
+func (t *ContextTypeMock) GenerateSecretKey(id []byte, bits int, cipher *crypto11.SymmetricCipher) (*crypto11.SecretKey, error) {
+
+	args := t.Called(id, bits, cipher)
+
+	return args.Get(0).(*crypto11.SecretKey), args.Error(1)
+}
+
+// GenerateSecretKey creates an secret key of given length and type. The id and label parameters are used to
+// set CKA_ID and CKA_LABEL respectively and must be non-nil.
+func (t *ContextTypeMock) GenerateSecretKeyWithLabel(id, label []byte, bits int, cipher *crypto11.SymmetricCipher) (*crypto11.SecretKey, error) {
+	return nil, nil
+}
+
+// GenerateSecretKeyWithAttributes creates an secret key of given length and type. After this function returns, template
+// will contain the attributes applied to the key. If required attributes are missing, they will be set to a default
+// value.
+func (t *ContextTypeMock) GenerateSecretKeyWithAttributes(template crypto11.AttributeSet, bits int, cipher *crypto11.SymmetricCipher) (k *crypto11.SecretKey, err error) {
+	return nil, nil
+}
+
+// NewRandomReader returns a reader for the random number generator on the token.
+func (t *ContextTypeMock) NewRandomReader() (io.Reader, error) {
+	return rand.Reader, nil
+}
diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index f8afc56..e9e2343 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -13,6 +13,7 @@ import (
 	"github.com/ThalesIgnite/crypto11"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
 	"math/rand"
+	"strconv"
 )
 
 func (p HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
@@ -96,6 +97,7 @@ func (p HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.Cryp
 	}
 	pubKeyObj := signer.Public()
 	var key = new(types.CryptoKey)
+	var params = new(types.CryptoKeyParameter)
 
 	if pubKey, ok := pubKeyObj.(*ecdsa.PublicKey); ok {
 		repr, err := pubKey.ECDH()
@@ -103,13 +105,15 @@ func (p HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.Cryp
 			return nil, err
 		}
 		key.Key = repr.Bytes()
-
+		params.Identifier = parameter
+		params.KeyType = constructKeyType(ECDSA, pubKey.Curve.Params().Name)
 	} else if pubKey, ok := pubKeyObj.(*rsa.PublicKey); ok {
 		keyBytes, err := x509.MarshalPKIXPublicKey(pubKey)
 		if err != nil {
 			return nil, err
 		}
 		key.Key = keyBytes
+		params.KeyType = constructKeyType(RSA, strconv.Itoa(pubKey.Size()))
 
 	} else if pubKey, ok := pubKeyObj.(*crypto11.SecretKey); ok {
 		return nil, fmt.Errorf("keys of type %T are not retrievable", pubKey)
@@ -117,6 +121,8 @@ func (p HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.Cryp
 	} else {
 		return nil, fmt.Errorf("key %s has unsupported key format", parameter.KeyId)
 	}
+
+	key.CryptoKeyParameter = *params
 	return key, nil
 }
 func (p HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte, signature []byte) (bool, error) {
diff --git a/hsmCryptoProvider_test.go b/hsmCryptoProvider_test.go
index 890b7e2..6b2d621 100644
--- a/hsmCryptoProvider_test.go
+++ b/hsmCryptoProvider_test.go
@@ -1,41 +1,43 @@
 package main
 
 import (
-	"bou.ke/monkey"
+	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
 	"github.com/ThalesIgnite/crypto11"
+	"github.com/stretchr/testify/assert"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
-	"reflect"
 	"testing"
 )
 
 var testId = "test id"
 
-func getTestHSMCryptoProvider() HSMCryptoProvider {
+func getTestHSMCryptoProvider(mock *ContextTypeMock) HSMCryptoProvider {
 	return HSMCryptoProvider{
 		controller: &hsmController{
 			config: &crypto11.Config{},
 			rand:   rand.Reader,
-			api:    &crypto11.Context{},
+			api:    mock,
 		},
 	}
 }
 
 func TestHSMCryptoProvider_GenerateKey(t *testing.T) {
-	defer monkey.UnpatchAll()
-	var mockGenerateECDSA = func(ctx *crypto11.Context, id []byte, curve elliptic.Curve) (crypto11.Signer, error) {
-		if string(id) != testId {
-			t.Errorf("expected %s actual %s", testId, string(id))
-		}
-		if curve != elliptic.P256() {
-			t.Errorf("expected %s actual %s", elliptic.P256().Params().Name, curve.Params().Name)
-
-		}
-		return nil, nil
-	}
-	monkey.PatchInstanceMethod(reflect.TypeOf(&crypto11.Context{}), "GenerateECDSAKeyPair", mockGenerateECDSA)
-	provider := getTestHSMCryptoProvider()
+	var mockApi = new(ContextTypeMock)
+	provider := getTestHSMCryptoProvider(mockApi)
 	param := types.CryptoKeyParameter{KeyType: types.Ecdsap256, Identifier: types.CryptoIdentifier{KeyId: testId}}
+	mockApi.On("GenerateECDSAKeyPair", []byte(testId), elliptic.P256()).Return(&SignerMock{}, nil)
 	_ = provider.GenerateKey(param)
+	mockApi.AssertExpectations(t)
+}
+
+func TestHSMCryptoProvider_GetKey(t *testing.T) {
+	key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	expected, _ := key.Public().(*ecdsa.PublicKey).ECDH()
+	var mockApi = new(ContextTypeMock)
+	mockApi.On("FindKeyPair", []byte(testId), []byte(nil)).Return(&SignerMock{public: key.Public()}, nil)
+	provider := getTestHSMCryptoProvider(mockApi)
+	actual, _ := provider.GetKey(types.CryptoIdentifier{KeyId: testId})
+	assert.Equal(t, expected.Bytes(), actual.Key)
+	assert.Equal(t, types.Ecdsap256, actual.CryptoKeyParameter.KeyType)
 }
diff --git a/types.go b/types.go
index da50c2d..fae74f0 100644
--- a/types.go
+++ b/types.go
@@ -2,13 +2,16 @@ package main
 
 import (
 	"crypto"
+	"crypto/elliptic"
 	"github.com/ThalesIgnite/crypto11"
+	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
 	"io"
+	"strings"
 )
 
 type hsmController struct {
 	config        *crypto11.Config
-	api           *crypto11.Context
+	api           ContextType
 	signerOptions crypto.SignerOpts
 	rand          io.Reader
 }
@@ -23,3 +26,114 @@ const (
 	RSA   MajorKeyType = "rsa"
 	ECDSA MajorKeyType = "ecdsa"
 )
+
+func constructKeyType(typ MajorKeyType, typParam string) types.KeyType {
+	typParam = strings.ToLower(strings.Replace(typParam, "-", "", -1))
+	return types.KeyType(strings.Join([]string{string(typ), typParam}, "-"))
+}
+
+// methods used from crypto11.Context
+type ContextType interface {
+	// GenerateRSAKeyPair creates an RSA key pair on the token. The id parameter is used to
+	// set CKA_ID and must be non-nil. RSA private keys are generated with both sign and decrypt
+	// permissions, and a public exponent of 65537.
+	GenerateRSAKeyPair(id []byte, bits int) (crypto11.SignerDecrypter, error)
+	// GenerateRSAKeyPairWithLabel creates an RSA key pair on the token. The id and label parameters are used to
+	// set CKA_ID and CKA_LABEL respectively and must be non-nil. RSA private keys are generated with both sign and decrypt
+	// permissions, and a public exponent of 65537.
+	GenerateRSAKeyPairWithLabel(id, label []byte, bits int) (crypto11.SignerDecrypter, error)
+	// GenerateRSAKeyPairWithAttributes generates an RSA key pair on the token. After this function returns, public and
+	// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to
+	// a default value.
+	GenerateRSAKeyPairWithAttributes(public, private crypto11.AttributeSet, bits int) (crypto11.SignerDecrypter, error)
+	// FindKeyPair retrieves a previously created asymmetric key pair, or nil if it cannot be found.
+	//
+	// At least one of id and label must be specified.
+	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+	// because we cannot implement crypto.Signer without the public key.
+	FindKeyPair(id []byte, label []byte) (crypto11.Signer, error)
+	// FindKeyPairs retrieves all matching asymmetric key pairs, or a nil slice if none can be found.
+	//
+	// At least one of id and label must be specified.
+	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+	// because we cannot implement crypto.Signer without the public key.
+	FindKeyPairs(id []byte, label []byte) (signer []crypto11.Signer, err error)
+	// FindKeyPairWithAttributes retrieves a previously created asymmetric key pair, or nil if it cannot be found.
+	// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID
+	// and CKA_LABEL values is found.
+	//
+	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+	// because we cannot implement crypto.Signer without the public key.
+	FindKeyPairWithAttributes(attributes crypto11.AttributeSet) (crypto11.Signer, error)
+	// FindKeyPairsWithAttributes retrieves previously created asymmetric key pairs, or nil if none can be found.
+	// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID
+	// and CKA_LABEL values is found.
+	//
+	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+	// because we cannot implement crypto.Signer without the public key.
+	FindKeyPairsWithAttributes(attributes crypto11.AttributeSet) (signer []crypto11.Signer, err error)
+	// FindAllKeyPairs retrieves all existing asymmetric key pairs, or a nil slice if none can be found.
+	//
+	// If a private key is found, but the corresponding public key is not, the key is not returned because we cannot
+	// implement crypto.Signer without the public key.
+	FindAllKeyPairs() ([]crypto11.Signer, error)
+	// FindKey retrieves a previously created symmetric key, or nil if it cannot be found.
+	//
+	// Either (but not both) of id and label may be nil, in which case they are ignored.
+	FindKey(id []byte, label []byte) (*crypto11.SecretKey, error)
+	// FindKeys retrieves all matching symmetric keys, or a nil slice if none can be found.
+	//
+	// At least one of id and label must be specified.
+	FindKeys(id []byte, label []byte) (key []*crypto11.SecretKey, err error)
+	// FindKeyWithAttributes retrieves a previously created symmetric key, or nil if it cannot be found.
+	FindKeyWithAttributes(attributes crypto11.AttributeSet) (*crypto11.SecretKey, error)
+	// FindKeysWithAttributes retrieves previously created symmetric keys, or a nil slice if none can be found.
+	FindKeysWithAttributes(attributes crypto11.AttributeSet) ([]*crypto11.SecretKey, error)
+	// FindAllKeyPairs retrieves all existing symmetric keys, or a nil slice if none can be found.
+	FindAllKeys() ([]*crypto11.SecretKey, error)
+	// GetAttributes gets the values of the specified attributes on the given key or keypair.
+	// If the key is asymmetric, then the attributes are retrieved from the private half.
+	//
+	// If the object is not a crypto11 key or keypair then an error is returned.
+	GetAttributes(key interface{}, attributes []crypto11.AttributeType) (a crypto11.AttributeSet, err error)
+	// GetAttribute gets the value of the specified attribute on the given key or keypair.
+	// If the key is asymmetric, then the attribute is retrieved from the private half.
+	//
+	// If the object is not a crypto11 key or keypair then an error is returned.
+	GetAttribute(key interface{}, attribute crypto11.AttributeType) (a *crypto11.Attribute, err error)
+	// GetPubAttributes gets the values of the specified attributes on the public half of the given keypair.
+	//
+	// If the object is not a crypto11 keypair then an error is returned.
+	GetPubAttributes(key interface{}, attributes []crypto11.AttributeType) (a crypto11.AttributeSet, err error)
+	// GetPubAttribute gets the value of the specified attribute on the public half of the given key.
+	//
+	// If the object is not a crypto11 keypair then an error is returned.
+	GetPubAttribute(key interface{}, attribute crypto11.AttributeType) (a *crypto11.Attribute, err error)
+	// GenerateECDSAKeyPair creates a ECDSA key pair on the token using curve c. The id parameter is used to
+	// set CKA_ID and must be non-nil. Only a limited set of named elliptic curves are supported. The
+	// underlying PKCS#11 implementation may impose further restrictions.
+	GenerateECDSAKeyPair(id []byte, curve elliptic.Curve) (crypto11.Signer, error)
+	// GenerateECDSAKeyPairWithLabel creates a ECDSA key pair on the token using curve c. The id and label parameters are used to
+	// set CKA_ID and CKA_LABEL respectively and must be non-nil. Only a limited set of named elliptic curves are supported. The
+	// underlying PKCS#11 implementation may impose further restrictions.
+	GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (crypto11.Signer, error)
+	// GenerateECDSAKeyPairWithAttributes generates an ECDSA key pair on the token. After this function returns, public and
+	// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to
+	// a default value.
+	GenerateECDSAKeyPairWithAttributes(public, private crypto11.AttributeSet, curve elliptic.Curve) (crypto11.Signer, error)
+
+	GenerateSecretKey(id []byte, bits int, cipher *crypto11.SymmetricCipher) (*crypto11.SecretKey, error)
+	// GenerateSecretKey creates an secret key of given length and type. The id and label parameters are used to
+	// set CKA_ID and CKA_LABEL respectively and must be non-nil.
+	GenerateSecretKeyWithLabel(id, label []byte, bits int, cipher *crypto11.SymmetricCipher) (*crypto11.SecretKey, error)
+	// GenerateSecretKeyWithAttributes creates an secret key of given length and type. After this function returns, template
+	// will contain the attributes applied to the key. If required attributes are missing, they will be set to a default
+	// value.
+	GenerateSecretKeyWithAttributes(template crypto11.AttributeSet, bits int, cipher *crypto11.SymmetricCipher) (k *crypto11.SecretKey, err error)
+	// NewRandomReader returns a reader for the random number generator on the token.
+	NewRandomReader() (io.Reader, error)
+}
-- 
GitLab


From 7ff4dd9a70a6c3d109116b445d00ac9a83513468 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 13 Dec 2023 11:56:57 +0100
Subject: [PATCH 05/22] ContextType extracted

---
 crypto11ContextType.go | 113 +++++++++++++++++++++++++++++++++++++++++
 types.go               | 107 --------------------------------------
 2 files changed, 113 insertions(+), 107 deletions(-)
 create mode 100644 crypto11ContextType.go

diff --git a/crypto11ContextType.go b/crypto11ContextType.go
new file mode 100644
index 0000000..ba85d2f
--- /dev/null
+++ b/crypto11ContextType.go
@@ -0,0 +1,113 @@
+package main
+
+import (
+	"crypto/elliptic"
+	"github.com/ThalesIgnite/crypto11"
+	"io"
+)
+
+// methods used from crypto11.Context
+type ContextType interface {
+	// GenerateRSAKeyPair creates an RSA key pair on the token. The id parameter is used to
+	// set CKA_ID and must be non-nil. RSA private keys are generated with both sign and decrypt
+	// permissions, and a public exponent of 65537.
+	GenerateRSAKeyPair(id []byte, bits int) (crypto11.SignerDecrypter, error)
+	// GenerateRSAKeyPairWithLabel creates an RSA key pair on the token. The id and label parameters are used to
+	// set CKA_ID and CKA_LABEL respectively and must be non-nil. RSA private keys are generated with both sign and decrypt
+	// permissions, and a public exponent of 65537.
+	GenerateRSAKeyPairWithLabel(id, label []byte, bits int) (crypto11.SignerDecrypter, error)
+	// GenerateRSAKeyPairWithAttributes generates an RSA key pair on the token. After this function returns, public and
+	// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to
+	// a default value.
+	GenerateRSAKeyPairWithAttributes(public, private crypto11.AttributeSet, bits int) (crypto11.SignerDecrypter, error)
+	// FindKeyPair retrieves a previously created asymmetric key pair, or nil if it cannot be found.
+	//
+	// At least one of id and label must be specified.
+	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+	// because we cannot implement crypto.Signer without the public key.
+	FindKeyPair(id []byte, label []byte) (crypto11.Signer, error)
+	// FindKeyPairs retrieves all matching asymmetric key pairs, or a nil slice if none can be found.
+	//
+	// At least one of id and label must be specified.
+	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+	// because we cannot implement crypto.Signer without the public key.
+	FindKeyPairs(id []byte, label []byte) (signer []crypto11.Signer, err error)
+	// FindKeyPairWithAttributes retrieves a previously created asymmetric key pair, or nil if it cannot be found.
+	// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID
+	// and CKA_LABEL values is found.
+	//
+	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+	// because we cannot implement crypto.Signer without the public key.
+	FindKeyPairWithAttributes(attributes crypto11.AttributeSet) (crypto11.Signer, error)
+	// FindKeyPairsWithAttributes retrieves previously created asymmetric key pairs, or nil if none can be found.
+	// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID
+	// and CKA_LABEL values is found.
+	//
+	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
+	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
+	// because we cannot implement crypto.Signer without the public key.
+	FindKeyPairsWithAttributes(attributes crypto11.AttributeSet) (signer []crypto11.Signer, err error)
+	// FindAllKeyPairs retrieves all existing asymmetric key pairs, or a nil slice if none can be found.
+	//
+	// If a private key is found, but the corresponding public key is not, the key is not returned because we cannot
+	// implement crypto.Signer without the public key.
+	FindAllKeyPairs() ([]crypto11.Signer, error)
+	// FindKey retrieves a previously created symmetric key, or nil if it cannot be found.
+	//
+	// Either (but not both) of id and label may be nil, in which case they are ignored.
+	FindKey(id []byte, label []byte) (*crypto11.SecretKey, error)
+	// FindKeys retrieves all matching symmetric keys, or a nil slice if none can be found.
+	//
+	// At least one of id and label must be specified.
+	FindKeys(id []byte, label []byte) (key []*crypto11.SecretKey, err error)
+	// FindKeyWithAttributes retrieves a previously created symmetric key, or nil if it cannot be found.
+	FindKeyWithAttributes(attributes crypto11.AttributeSet) (*crypto11.SecretKey, error)
+	// FindKeysWithAttributes retrieves previously created symmetric keys, or a nil slice if none can be found.
+	FindKeysWithAttributes(attributes crypto11.AttributeSet) ([]*crypto11.SecretKey, error)
+	// FindAllKeyPairs retrieves all existing symmetric keys, or a nil slice if none can be found.
+	FindAllKeys() ([]*crypto11.SecretKey, error)
+	// GetAttributes gets the values of the specified attributes on the given key or keypair.
+	// If the key is asymmetric, then the attributes are retrieved from the private half.
+	//
+	// If the object is not a crypto11 key or keypair then an error is returned.
+	GetAttributes(key interface{}, attributes []crypto11.AttributeType) (a crypto11.AttributeSet, err error)
+	// GetAttribute gets the value of the specified attribute on the given key or keypair.
+	// If the key is asymmetric, then the attribute is retrieved from the private half.
+	//
+	// If the object is not a crypto11 key or keypair then an error is returned.
+	GetAttribute(key interface{}, attribute crypto11.AttributeType) (a *crypto11.Attribute, err error)
+	// GetPubAttributes gets the values of the specified attributes on the public half of the given keypair.
+	//
+	// If the object is not a crypto11 keypair then an error is returned.
+	GetPubAttributes(key interface{}, attributes []crypto11.AttributeType) (a crypto11.AttributeSet, err error)
+	// GetPubAttribute gets the value of the specified attribute on the public half of the given key.
+	//
+	// If the object is not a crypto11 keypair then an error is returned.
+	GetPubAttribute(key interface{}, attribute crypto11.AttributeType) (a *crypto11.Attribute, err error)
+	// GenerateECDSAKeyPair creates a ECDSA key pair on the token using curve c. The id parameter is used to
+	// set CKA_ID and must be non-nil. Only a limited set of named elliptic curves are supported. The
+	// underlying PKCS#11 implementation may impose further restrictions.
+	GenerateECDSAKeyPair(id []byte, curve elliptic.Curve) (crypto11.Signer, error)
+	// GenerateECDSAKeyPairWithLabel creates a ECDSA key pair on the token using curve c. The id and label parameters are used to
+	// set CKA_ID and CKA_LABEL respectively and must be non-nil. Only a limited set of named elliptic curves are supported. The
+	// underlying PKCS#11 implementation may impose further restrictions.
+	GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (crypto11.Signer, error)
+	// GenerateECDSAKeyPairWithAttributes generates an ECDSA key pair on the token. After this function returns, public and
+	// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to
+	// a default value.
+	GenerateECDSAKeyPairWithAttributes(public, private crypto11.AttributeSet, curve elliptic.Curve) (crypto11.Signer, error)
+
+	GenerateSecretKey(id []byte, bits int, cipher *crypto11.SymmetricCipher) (*crypto11.SecretKey, error)
+	// GenerateSecretKey creates an secret key of given length and type. The id and label parameters are used to
+	// set CKA_ID and CKA_LABEL respectively and must be non-nil.
+	GenerateSecretKeyWithLabel(id, label []byte, bits int, cipher *crypto11.SymmetricCipher) (*crypto11.SecretKey, error)
+	// GenerateSecretKeyWithAttributes creates an secret key of given length and type. After this function returns, template
+	// will contain the attributes applied to the key. If required attributes are missing, they will be set to a default
+	// value.
+	GenerateSecretKeyWithAttributes(template crypto11.AttributeSet, bits int, cipher *crypto11.SymmetricCipher) (k *crypto11.SecretKey, err error)
+	// NewRandomReader returns a reader for the random number generator on the token.
+	NewRandomReader() (io.Reader, error)
+}
diff --git a/types.go b/types.go
index fae74f0..e99e33a 100644
--- a/types.go
+++ b/types.go
@@ -2,7 +2,6 @@ package main
 
 import (
 	"crypto"
-	"crypto/elliptic"
 	"github.com/ThalesIgnite/crypto11"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
 	"io"
@@ -31,109 +30,3 @@ func constructKeyType(typ MajorKeyType, typParam string) types.KeyType {
 	typParam = strings.ToLower(strings.Replace(typParam, "-", "", -1))
 	return types.KeyType(strings.Join([]string{string(typ), typParam}, "-"))
 }
-
-// methods used from crypto11.Context
-type ContextType interface {
-	// GenerateRSAKeyPair creates an RSA key pair on the token. The id parameter is used to
-	// set CKA_ID and must be non-nil. RSA private keys are generated with both sign and decrypt
-	// permissions, and a public exponent of 65537.
-	GenerateRSAKeyPair(id []byte, bits int) (crypto11.SignerDecrypter, error)
-	// GenerateRSAKeyPairWithLabel creates an RSA key pair on the token. The id and label parameters are used to
-	// set CKA_ID and CKA_LABEL respectively and must be non-nil. RSA private keys are generated with both sign and decrypt
-	// permissions, and a public exponent of 65537.
-	GenerateRSAKeyPairWithLabel(id, label []byte, bits int) (crypto11.SignerDecrypter, error)
-	// GenerateRSAKeyPairWithAttributes generates an RSA key pair on the token. After this function returns, public and
-	// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to
-	// a default value.
-	GenerateRSAKeyPairWithAttributes(public, private crypto11.AttributeSet, bits int) (crypto11.SignerDecrypter, error)
-	// FindKeyPair retrieves a previously created asymmetric key pair, or nil if it cannot be found.
-	//
-	// At least one of id and label must be specified.
-	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
-	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
-	// because we cannot implement crypto.Signer without the public key.
-	FindKeyPair(id []byte, label []byte) (crypto11.Signer, error)
-	// FindKeyPairs retrieves all matching asymmetric key pairs, or a nil slice if none can be found.
-	//
-	// At least one of id and label must be specified.
-	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
-	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
-	// because we cannot implement crypto.Signer without the public key.
-	FindKeyPairs(id []byte, label []byte) (signer []crypto11.Signer, err error)
-	// FindKeyPairWithAttributes retrieves a previously created asymmetric key pair, or nil if it cannot be found.
-	// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID
-	// and CKA_LABEL values is found.
-	//
-	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
-	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
-	// because we cannot implement crypto.Signer without the public key.
-	FindKeyPairWithAttributes(attributes crypto11.AttributeSet) (crypto11.Signer, error)
-	// FindKeyPairsWithAttributes retrieves previously created asymmetric key pairs, or nil if none can be found.
-	// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID
-	// and CKA_LABEL values is found.
-	//
-	// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key.
-	// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned
-	// because we cannot implement crypto.Signer without the public key.
-	FindKeyPairsWithAttributes(attributes crypto11.AttributeSet) (signer []crypto11.Signer, err error)
-	// FindAllKeyPairs retrieves all existing asymmetric key pairs, or a nil slice if none can be found.
-	//
-	// If a private key is found, but the corresponding public key is not, the key is not returned because we cannot
-	// implement crypto.Signer without the public key.
-	FindAllKeyPairs() ([]crypto11.Signer, error)
-	// FindKey retrieves a previously created symmetric key, or nil if it cannot be found.
-	//
-	// Either (but not both) of id and label may be nil, in which case they are ignored.
-	FindKey(id []byte, label []byte) (*crypto11.SecretKey, error)
-	// FindKeys retrieves all matching symmetric keys, or a nil slice if none can be found.
-	//
-	// At least one of id and label must be specified.
-	FindKeys(id []byte, label []byte) (key []*crypto11.SecretKey, err error)
-	// FindKeyWithAttributes retrieves a previously created symmetric key, or nil if it cannot be found.
-	FindKeyWithAttributes(attributes crypto11.AttributeSet) (*crypto11.SecretKey, error)
-	// FindKeysWithAttributes retrieves previously created symmetric keys, or a nil slice if none can be found.
-	FindKeysWithAttributes(attributes crypto11.AttributeSet) ([]*crypto11.SecretKey, error)
-	// FindAllKeyPairs retrieves all existing symmetric keys, or a nil slice if none can be found.
-	FindAllKeys() ([]*crypto11.SecretKey, error)
-	// GetAttributes gets the values of the specified attributes on the given key or keypair.
-	// If the key is asymmetric, then the attributes are retrieved from the private half.
-	//
-	// If the object is not a crypto11 key or keypair then an error is returned.
-	GetAttributes(key interface{}, attributes []crypto11.AttributeType) (a crypto11.AttributeSet, err error)
-	// GetAttribute gets the value of the specified attribute on the given key or keypair.
-	// If the key is asymmetric, then the attribute is retrieved from the private half.
-	//
-	// If the object is not a crypto11 key or keypair then an error is returned.
-	GetAttribute(key interface{}, attribute crypto11.AttributeType) (a *crypto11.Attribute, err error)
-	// GetPubAttributes gets the values of the specified attributes on the public half of the given keypair.
-	//
-	// If the object is not a crypto11 keypair then an error is returned.
-	GetPubAttributes(key interface{}, attributes []crypto11.AttributeType) (a crypto11.AttributeSet, err error)
-	// GetPubAttribute gets the value of the specified attribute on the public half of the given key.
-	//
-	// If the object is not a crypto11 keypair then an error is returned.
-	GetPubAttribute(key interface{}, attribute crypto11.AttributeType) (a *crypto11.Attribute, err error)
-	// GenerateECDSAKeyPair creates a ECDSA key pair on the token using curve c. The id parameter is used to
-	// set CKA_ID and must be non-nil. Only a limited set of named elliptic curves are supported. The
-	// underlying PKCS#11 implementation may impose further restrictions.
-	GenerateECDSAKeyPair(id []byte, curve elliptic.Curve) (crypto11.Signer, error)
-	// GenerateECDSAKeyPairWithLabel creates a ECDSA key pair on the token using curve c. The id and label parameters are used to
-	// set CKA_ID and CKA_LABEL respectively and must be non-nil. Only a limited set of named elliptic curves are supported. The
-	// underlying PKCS#11 implementation may impose further restrictions.
-	GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (crypto11.Signer, error)
-	// GenerateECDSAKeyPairWithAttributes generates an ECDSA key pair on the token. After this function returns, public and
-	// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to
-	// a default value.
-	GenerateECDSAKeyPairWithAttributes(public, private crypto11.AttributeSet, curve elliptic.Curve) (crypto11.Signer, error)
-
-	GenerateSecretKey(id []byte, bits int, cipher *crypto11.SymmetricCipher) (*crypto11.SecretKey, error)
-	// GenerateSecretKey creates an secret key of given length and type. The id and label parameters are used to
-	// set CKA_ID and CKA_LABEL respectively and must be non-nil.
-	GenerateSecretKeyWithLabel(id, label []byte, bits int, cipher *crypto11.SymmetricCipher) (*crypto11.SecretKey, error)
-	// GenerateSecretKeyWithAttributes creates an secret key of given length and type. After this function returns, template
-	// will contain the attributes applied to the key. If required attributes are missing, they will be set to a default
-	// value.
-	GenerateSecretKeyWithAttributes(template crypto11.AttributeSet, bits int, cipher *crypto11.SymmetricCipher) (k *crypto11.SecretKey, err error)
-	// NewRandomReader returns a reader for the random number generator on the token.
-	NewRandomReader() (io.Reader, error)
-}
-- 
GitLab


From bf27488d84dc42665a67120b23f30d6e15de92ee Mon Sep 17 00:00:00 2001
From: Steffen Schulze <steffen.schulze@t-systems.com>
Date: Thu, 21 Dec 2023 08:09:01 +0000
Subject: [PATCH 06/22] Initial commit

---
 README.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 README.md

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b6b6caa
--- /dev/null
+++ b/README.md
@@ -0,0 +1,93 @@
+# luna-cloud-hsm-provider
+
+
+
+## Getting started
+
+To make it easy for you to get started with GitLab, here's a list of recommended next steps.
+
+Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
+
+## Add your files
+
+- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
+- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
+
+```
+cd existing_repo
+git remote add origin https://gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/plugins/luna-cloud-hsm-provider.git
+git branch -M main
+git push -uf origin main
+```
+
+## Integrate with your tools
+
+- [ ] [Set up project integrations](https://gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/plugins/luna-cloud-hsm-provider/-/settings/integrations)
+
+## Collaborate with your team
+
+- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
+- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
+- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
+- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
+- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
+
+## Test and Deploy
+
+Use the built-in continuous integration in GitLab.
+
+- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
+- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
+- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
+- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
+- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
+
+***
+
+# Editing this README
+
+When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
+
+## Suggestions for a good README
+
+Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
+
+## Name
+Choose a self-explaining name for your project.
+
+## Description
+Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
+
+## Badges
+On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
+
+## Visuals
+Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
+
+## Installation
+Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
+
+## Usage
+Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
+
+## Support
+Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
+
+## Roadmap
+If you have ideas for releases in the future, it is a good idea to list them in the README.
+
+## Contributing
+State if you are open to contributions and what your requirements are for accepting them.
+
+For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
+
+You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
+
+## Authors and acknowledgment
+Show your appreciation to those who have contributed to the project.
+
+## License
+For open source projects, say how it is licensed.
+
+## Project status
+If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
-- 
GitLab


From ebae63175042bb66a72780ebd0db7f560e56d204 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Mon, 8 Jan 2024 10:40:21 +0100
Subject: [PATCH 07/22] default namespace returned

---
 hsmCryptoProvider.go | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index e9e2343..26c8f4b 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -16,13 +16,17 @@ import (
 	"strconv"
 )
 
+const (
+	HsmNamespace = "luna-cloud-hsm"
+)
+
 func (p HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
 	id := []byte(parameter.KeyId)
 	return p.controller.api.FindKeyPair(id, nil)
 }
 
 func (p HSMCryptoProvider) GetNamespaces(context context.Context) ([]string, error) {
-	return nil, errors.ErrUnsupported
+	return []string{HsmNamespace}, nil
 }
 func (p HSMCryptoProvider) GenerateRandom(context types.CryptoContext, number int) ([]byte, error) {
 	key := make([]byte, number)
-- 
GitLab


From 7ab70e276568eb5a00478bf4ee79fff84c500488 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 10 Jan 2024 14:14:10 +0100
Subject: [PATCH 08/22] go min version updated

---
 go.mod | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/go.mod b/go.mod
index 703c2b3..0fc8a15 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module luna-hsm-provider
 
-go 1.21.4
+go 1.21
 
 require (
 	github.com/ThalesIgnite/crypto11 v1.2.5
-- 
GitLab


From 63b6d2c75b3bdf5e8ed7fdc87f020674fb561fe1 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 10 Jan 2024 15:08:30 +0100
Subject: [PATCH 09/22] golang.org/x/crypto v0.15.0

---
 go.mod | 10 ++++++----
 go.sum |  9 ++++++---
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/go.mod b/go.mod
index 0fc8a15..e5d47d8 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,8 @@
 module luna-hsm-provider
 
-go 1.21
+go 1.21.3
+
+toolchain go1.21.4
 
 require (
 	github.com/ThalesIgnite/crypto11 v1.2.5
@@ -40,10 +42,10 @@ require (
 	github.com/thales-e-security/pool v0.0.2 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/multierr v1.9.0 // indirect
-	golang.org/x/crypto v0.14.0 // indirect
+	golang.org/x/crypto v0.15.0 // indirect
 	golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
-	golang.org/x/sys v0.13.0 // indirect
-	golang.org/x/text v0.13.0 // indirect
+	golang.org/x/sys v0.14.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/go.sum b/go.sum
index ce7a319..0aa1e8e 100644
--- a/go.sum
+++ b/go.sum
@@ -235,8 +235,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
+golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -371,8 +372,9 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
 golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
+golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -388,8 +390,9 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-- 
GitLab


From ccd59542a150d518d1ae3929e82970619d23f784 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Thu, 11 Jan 2024 10:34:51 +0100
Subject: [PATCH 10/22] plugin export fixed

---
 main.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/main.go b/main.go
index fa66220..0c71788 100644
--- a/main.go
+++ b/main.go
@@ -6,11 +6,11 @@ import (
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
 )
 
-var Plugin types.CryptoProviderModule = plugin{} //export Plugin Symbol, dont
+var Plugin plugin //export Plugin Symbol, dont
 
 type plugin struct{}
 
-func (p plugin) GetCryptoProvider() types.CryptoProvider {
+func (p *plugin) GetCryptoProvider() types.CryptoProvider {
 	config := crypto11.Config{
 		Path:       viper.GetString("CRYPTO_EXECUTABLE_PATH"),
 		TokenLabel: viper.GetString("HSM_PARTITION_LABEL"),
-- 
GitLab


From 9a07d667bd4a9c64e7dadc452729ef2baf48487e Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Thu, 11 Jan 2024 12:13:57 +0100
Subject: [PATCH 11/22] viper reads env vars

---
 main.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/main.go b/main.go
index 0c71788..03ebd9c 100644
--- a/main.go
+++ b/main.go
@@ -11,6 +11,7 @@ var Plugin plugin //export Plugin Symbol, dont
 type plugin struct{}
 
 func (p *plugin) GetCryptoProvider() types.CryptoProvider {
+	viper.AutomaticEnv()
 	config := crypto11.Config{
 		Path:       viper.GetString("CRYPTO_EXECUTABLE_PATH"),
 		TokenLabel: viper.GetString("HSM_PARTITION_LABEL"),
-- 
GitLab


From 7cef5ca1260edca6b7b1092e9757fae37b785e07 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Thu, 11 Jan 2024 16:43:30 +0100
Subject: [PATCH 12/22] key pair not found error

---
 hsmCryptoProvider.go | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index 26c8f4b..a94bbfc 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -22,7 +22,14 @@ const (
 
 func (p HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
 	id := []byte(parameter.KeyId)
-	return p.controller.api.FindKeyPair(id, nil)
+	keyPair, err := p.controller.api.FindKeyPair(id, nil)
+	if err != nil {
+		return nil, err
+	} else if keyPair == nil {
+		return nil, fmt.Errorf("key pair for identifier `%s` not found", parameter.KeyId)
+	} else {
+		return keyPair, err
+	}
 }
 
 func (p HSMCryptoProvider) GetNamespaces(context context.Context) ([]string, error) {
-- 
GitLab


From f224c7138daf907c0b6165bf065ca1cd3538b9a8 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Thu, 11 Jan 2024 17:04:54 +0100
Subject: [PATCH 13/22] nil returned if keypair not found

---
 hsmCryptoProvider.go | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index a94bbfc..f16c16e 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -22,14 +22,7 @@ const (
 
 func (p HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
 	id := []byte(parameter.KeyId)
-	keyPair, err := p.controller.api.FindKeyPair(id, nil)
-	if err != nil {
-		return nil, err
-	} else if keyPair == nil {
-		return nil, fmt.Errorf("key pair for identifier `%s` not found", parameter.KeyId)
-	} else {
-		return keyPair, err
-	}
+	return p.controller.api.FindKeyPair(id, nil)
 }
 
 func (p HSMCryptoProvider) GetNamespaces(context context.Context) ([]string, error) {
@@ -87,15 +80,18 @@ func (p HSMCryptoProvider) Sign(parameter types.CryptoIdentifier, data []byte) (
 	if err != nil {
 		return nil, err
 	}
-	if err != nil {
-		return nil, err
+	if signer == nil {
+		return nil, nil
 	}
 	return signer.Sign(p.controller.rand, data, p.controller.signerOptions)
 }
 func (p HSMCryptoProvider) GetKeys(parameter types.CryptoIdentifier) (*types.CryptoKeySet, error) {
 	key, err := p.GetKey(parameter)
+
 	if err != nil {
 		return nil, err
+	} else if key == nil {
+		return nil, nil
 	} else {
 		keySet := &types.CryptoKeySet{Keys: []types.CryptoKey{*key}}
 		return keySet, nil
@@ -106,6 +102,9 @@ func (p HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.Cryp
 	if err != nil {
 		return nil, err
 	}
+	if signer == nil {
+		return nil, nil
+	}
 	pubKeyObj := signer.Public()
 	var key = new(types.CryptoKey)
 	var params = new(types.CryptoKeyParameter)
@@ -141,6 +140,9 @@ func (p HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte,
 	if err != nil {
 		return false, err
 	}
+	if signer == nil {
+		return false, nil
+	}
 	pubKeyObj := signer.Public()
 	if pubKey, ok := pubKeyObj.(*ecdsa.PublicKey); ok {
 		hashed := sha256.Sum256(data)
-- 
GitLab


From eaef6826afc2e0d5bc0e21d244b1d14b146acb67 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Mon, 15 Jan 2024 16:50:11 +0100
Subject: [PATCH 14/22] not found error returned if key not found

---
 hsmCryptoProvider.go | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index f16c16e..28fa79c 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -22,7 +22,11 @@ const (
 
 func (p HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
 	id := []byte(parameter.KeyId)
-	return p.controller.api.FindKeyPair(id, nil)
+	signer, err := p.controller.api.FindKeyPair(id, nil)
+	if signer == nil && err == nil {
+		return nil, fmt.Errorf("could not find key with identifier `%s`", parameter.KeyId)
+	}
+	return signer, err
 }
 
 func (p HSMCryptoProvider) GetNamespaces(context context.Context) ([]string, error) {
@@ -80,9 +84,6 @@ func (p HSMCryptoProvider) Sign(parameter types.CryptoIdentifier, data []byte) (
 	if err != nil {
 		return nil, err
 	}
-	if signer == nil {
-		return nil, nil
-	}
 	return signer.Sign(p.controller.rand, data, p.controller.signerOptions)
 }
 func (p HSMCryptoProvider) GetKeys(parameter types.CryptoIdentifier) (*types.CryptoKeySet, error) {
@@ -102,9 +103,6 @@ func (p HSMCryptoProvider) GetKey(parameter types.CryptoIdentifier) (*types.Cryp
 	if err != nil {
 		return nil, err
 	}
-	if signer == nil {
-		return nil, nil
-	}
 	pubKeyObj := signer.Public()
 	var key = new(types.CryptoKey)
 	var params = new(types.CryptoKeyParameter)
@@ -140,9 +138,6 @@ func (p HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte,
 	if err != nil {
 		return false, err
 	}
-	if signer == nil {
-		return false, nil
-	}
 	pubKeyObj := signer.Public()
 	if pubKey, ok := pubKeyObj.(*ecdsa.PublicKey); ok {
 		hashed := sha256.Sum256(data)
-- 
GitLab


From c2f448dce746a66a3f2680f4b57f5893de778c63 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Tue, 16 Jan 2024 15:45:34 +0100
Subject: [PATCH 15/22] signerOptions defined

---
 hsmContextMock_test.go    |  9 ++++++---
 hsmController.go          |  2 +-
 hsmCryptoProvider.go      |  7 +++----
 hsmCryptoProvider_test.go | 36 ++++++++++++++++++++++++++++++++----
 main.go                   |  4 +++-
 types.go                  |  1 +
 6 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/hsmContextMock_test.go b/hsmContextMock_test.go
index 5b7a6fa..e233c6f 100644
--- a/hsmContextMock_test.go
+++ b/hsmContextMock_test.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"crypto"
+	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
 	"github.com/ThalesIgnite/crypto11"
@@ -14,17 +15,19 @@ type ContextTypeMock struct {
 }
 
 type SignerMock struct {
-	public crypto.PublicKey
+	private *ecdsa.PrivateKey
+	hashSum func([]byte) [32]byte
 }
 
 func (s *SignerMock) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
-	return []byte("signed"), nil
+	hash := s.hashSum(digest)
+	return ecdsa.SignASN1(rand, s.private, hash[:])
 }
 func (s *SignerMock) Delete() error {
 	return nil
 }
 func (s *SignerMock) Public() crypto.PublicKey {
-	return s.public
+	return s.private.Public()
 }
 
 // GenerateRSAKeyPair creates an RSA key pair on the token. The id parameter is used to
diff --git a/hsmController.go b/hsmController.go
index a151e20..06259f3 100644
--- a/hsmController.go
+++ b/hsmController.go
@@ -15,6 +15,6 @@ func (c hsmController) withApiAndRandomReader() (*hsmController, error) {
 	if err != nil {
 		return nil, err
 	}
-	controller := &hsmController{api: ctx, config: c.config, signerOptions: c.signerOptions, rand: randReader}
+	controller := &hsmController{api: ctx, config: c.config, signerOptions: c.signerOptions, rand: randReader, hashSum: c.hashSum}
 	return controller, nil
 }
diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index 28fa79c..52c0bc4 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -2,7 +2,6 @@ package main
 
 import (
 	"context"
-	"crypto"
 	"crypto/ecdsa"
 	"crypto/rsa"
 	"crypto/sha256"
@@ -140,12 +139,12 @@ func (p HSMCryptoProvider) Verify(parameter types.CryptoIdentifier, data []byte,
 	}
 	pubKeyObj := signer.Public()
 	if pubKey, ok := pubKeyObj.(*ecdsa.PublicKey); ok {
-		hashed := sha256.Sum256(data)
+		hashed := p.controller.hashSum(data)
 		result := ecdsa.VerifyASN1(pubKey, hashed[:], signature)
 		return result, nil
 	} else if pubKey, ok := pubKeyObj.(*rsa.PublicKey); ok {
-		hashed := sha256.Sum256(data)
-		err = rsa.VerifyPSS(pubKey, crypto.SHA256, hashed[:], signature, nil)
+		hashed := p.controller.hashSum(data)
+		err = rsa.VerifyPSS(pubKey, p.controller.signerOptions.HashFunc(), hashed[:], signature, nil)
 		return err == nil, err
 	} else if pubKey, ok := pubKeyObj.(*crypto11.SecretKey); ok {
 		return false, fmt.Errorf("keys of type %T are not retrievable", pubKey)
diff --git a/hsmCryptoProvider_test.go b/hsmCryptoProvider_test.go
index 6b2d621..c8238c1 100644
--- a/hsmCryptoProvider_test.go
+++ b/hsmCryptoProvider_test.go
@@ -1,9 +1,11 @@
 package main
 
 import (
+	"crypto"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
+	"crypto/sha256"
 	"github.com/ThalesIgnite/crypto11"
 	"github.com/stretchr/testify/assert"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
@@ -12,12 +14,21 @@ import (
 
 var testId = "test id"
 
+type hasher struct{}
+
+func (h hasher) HashFunc() crypto.Hash {
+	return crypto.SHA256
+	//return 0
+}
+
 func getTestHSMCryptoProvider(mock *ContextTypeMock) HSMCryptoProvider {
 	return HSMCryptoProvider{
 		controller: &hsmController{
-			config: &crypto11.Config{},
-			rand:   rand.Reader,
-			api:    mock,
+			config:        &crypto11.Config{},
+			rand:          rand.Reader,
+			api:           mock,
+			signerOptions: hasher{},
+			hashSum:       sha256.Sum256,
 		},
 	}
 }
@@ -35,9 +46,26 @@ func TestHSMCryptoProvider_GetKey(t *testing.T) {
 	key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 	expected, _ := key.Public().(*ecdsa.PublicKey).ECDH()
 	var mockApi = new(ContextTypeMock)
-	mockApi.On("FindKeyPair", []byte(testId), []byte(nil)).Return(&SignerMock{public: key.Public()}, nil)
+	mockApi.On("FindKeyPair", []byte(testId), []byte(nil)).Return(&SignerMock{private: key, hashSum: sha256.Sum256}, nil)
 	provider := getTestHSMCryptoProvider(mockApi)
 	actual, _ := provider.GetKey(types.CryptoIdentifier{KeyId: testId})
 	assert.Equal(t, expected.Bytes(), actual.Key)
 	assert.Equal(t, types.Ecdsap256, actual.CryptoKeyParameter.KeyType)
 }
+
+func TestHSMCryptoProvider_Verify(t *testing.T) {
+	key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	var mockApi = new(ContextTypeMock)
+	mockApi.On("FindKeyPair", []byte(testId), []byte(nil)).Return(&SignerMock{private: key, hashSum: sha256.Sum256}, nil)
+	provider := getTestHSMCryptoProvider(mockApi)
+	data := []byte("test data")
+	sign, err := provider.Sign(types.CryptoIdentifier{KeyId: testId}, data)
+	if err != nil {
+		print(err.Error())
+	}
+	actual, err := provider.Verify(types.CryptoIdentifier{KeyId: testId}, data, sign)
+	if err != nil {
+		print(err.Error())
+	}
+	assert.True(t, actual)
+}
diff --git a/main.go b/main.go
index 03ebd9c..5fadb16 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,8 @@
 package main
 
 import (
+	"crypto"
+	"crypto/sha256"
 	"github.com/ThalesIgnite/crypto11"
 	"github.com/spf13/viper"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
@@ -17,7 +19,7 @@ func (p *plugin) GetCryptoProvider() types.CryptoProvider {
 		TokenLabel: viper.GetString("HSM_PARTITION_LABEL"),
 		Pin:        viper.GetString("HSM_PARTITION_PASSWORD"),
 	}
-	def := hsmController{config: &config, signerOptions: nil}
+	def := hsmController{config: &config, signerOptions: crypto.SHA256, hashSum: sha256.Sum256}
 	controller, err := def.withApiAndRandomReader()
 	if err != nil {
 		panic(err)
diff --git a/types.go b/types.go
index e99e33a..e147176 100644
--- a/types.go
+++ b/types.go
@@ -12,6 +12,7 @@ type hsmController struct {
 	config        *crypto11.Config
 	api           ContextType
 	signerOptions crypto.SignerOpts
+	hashSum       func(h []byte) [32]byte
 	rand          io.Reader
 }
 
-- 
GitLab


From 689276153717c12d8debf3efd8143739be34e561 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Tue, 16 Jan 2024 16:11:26 +0100
Subject: [PATCH 16/22] RunHashSum method

---
 types.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/types.go b/types.go
index e147176..a6a0e44 100644
--- a/types.go
+++ b/types.go
@@ -20,6 +20,10 @@ type HSMCryptoProvider struct {
 	controller *hsmController
 }
 
+func (p HSMCryptoProvider) RunHashSum(h []byte) [32]byte {
+	return p.controller.hashSum(h)
+}
+
 type MajorKeyType string
 
 const (
-- 
GitLab


From b234dc0ea4e09bb11a0635cdb9991b80a207b49e Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Tue, 16 Jan 2024 17:02:22 +0100
Subject: [PATCH 17/22] default SignerOptions changed

---
 hsmContextMock_test.go    |  2 +-
 hsmCryptoProvider_test.go | 17 ++++-------------
 main.go                   |  6 +++---
 types.go                  | 18 ++++++++++++++++--
 4 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/hsmContextMock_test.go b/hsmContextMock_test.go
index e233c6f..c45ddc7 100644
--- a/hsmContextMock_test.go
+++ b/hsmContextMock_test.go
@@ -16,7 +16,7 @@ type ContextTypeMock struct {
 
 type SignerMock struct {
 	private *ecdsa.PrivateKey
-	hashSum func([]byte) [32]byte
+	hashSum func([]byte) []byte
 }
 
 func (s *SignerMock) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
diff --git a/hsmCryptoProvider_test.go b/hsmCryptoProvider_test.go
index c8238c1..1561ec4 100644
--- a/hsmCryptoProvider_test.go
+++ b/hsmCryptoProvider_test.go
@@ -1,11 +1,9 @@
 package main
 
 import (
-	"crypto"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
-	"crypto/sha256"
 	"github.com/ThalesIgnite/crypto11"
 	"github.com/stretchr/testify/assert"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
@@ -14,21 +12,14 @@ import (
 
 var testId = "test id"
 
-type hasher struct{}
-
-func (h hasher) HashFunc() crypto.Hash {
-	return crypto.SHA256
-	//return 0
-}
-
 func getTestHSMCryptoProvider(mock *ContextTypeMock) HSMCryptoProvider {
 	return HSMCryptoProvider{
 		controller: &hsmController{
 			config:        &crypto11.Config{},
 			rand:          rand.Reader,
 			api:           mock,
-			signerOptions: hasher{},
-			hashSum:       sha256.Sum256,
+			signerOptions: DefaultSignerOptions{},
+			hashSum:       DefaultHashSum,
 		},
 	}
 }
@@ -46,7 +37,7 @@ func TestHSMCryptoProvider_GetKey(t *testing.T) {
 	key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 	expected, _ := key.Public().(*ecdsa.PublicKey).ECDH()
 	var mockApi = new(ContextTypeMock)
-	mockApi.On("FindKeyPair", []byte(testId), []byte(nil)).Return(&SignerMock{private: key, hashSum: sha256.Sum256}, nil)
+	mockApi.On("FindKeyPair", []byte(testId), []byte(nil)).Return(&SignerMock{private: key, hashSum: DefaultHashSum}, nil)
 	provider := getTestHSMCryptoProvider(mockApi)
 	actual, _ := provider.GetKey(types.CryptoIdentifier{KeyId: testId})
 	assert.Equal(t, expected.Bytes(), actual.Key)
@@ -56,7 +47,7 @@ func TestHSMCryptoProvider_GetKey(t *testing.T) {
 func TestHSMCryptoProvider_Verify(t *testing.T) {
 	key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 	var mockApi = new(ContextTypeMock)
-	mockApi.On("FindKeyPair", []byte(testId), []byte(nil)).Return(&SignerMock{private: key, hashSum: sha256.Sum256}, nil)
+	mockApi.On("FindKeyPair", []byte(testId), []byte(nil)).Return(&SignerMock{private: key, hashSum: DefaultHashSum}, nil)
 	provider := getTestHSMCryptoProvider(mockApi)
 	data := []byte("test data")
 	sign, err := provider.Sign(types.CryptoIdentifier{KeyId: testId}, data)
diff --git a/main.go b/main.go
index 5fadb16..9e5b983 100644
--- a/main.go
+++ b/main.go
@@ -1,8 +1,6 @@
 package main
 
 import (
-	"crypto"
-	"crypto/sha256"
 	"github.com/ThalesIgnite/crypto11"
 	"github.com/spf13/viper"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
@@ -19,7 +17,9 @@ func (p *plugin) GetCryptoProvider() types.CryptoProvider {
 		TokenLabel: viper.GetString("HSM_PARTITION_LABEL"),
 		Pin:        viper.GetString("HSM_PARTITION_PASSWORD"),
 	}
-	def := hsmController{config: &config, signerOptions: crypto.SHA256, hashSum: sha256.Sum256}
+	//def := hsmController{config: &config, signerOptions: crypto.SHA256, hashSum: sha256.Sum256}
+	def := hsmController{config: &config, signerOptions: DefaultSignerOptions{}, hashSum: DefaultHashSum}
+
 	controller, err := def.withApiAndRandomReader()
 	if err != nil {
 		panic(err)
diff --git a/types.go b/types.go
index a6a0e44..a25daa8 100644
--- a/types.go
+++ b/types.go
@@ -12,7 +12,7 @@ type hsmController struct {
 	config        *crypto11.Config
 	api           ContextType
 	signerOptions crypto.SignerOpts
-	hashSum       func(h []byte) [32]byte
+	hashSum       func(h []byte) []byte
 	rand          io.Reader
 }
 
@@ -20,7 +20,7 @@ type HSMCryptoProvider struct {
 	controller *hsmController
 }
 
-func (p HSMCryptoProvider) RunHashSum(h []byte) [32]byte {
+func (p HSMCryptoProvider) RunHashSum(h []byte) []byte {
 	return p.controller.hashSum(h)
 }
 
@@ -35,3 +35,17 @@ func constructKeyType(typ MajorKeyType, typParam string) types.KeyType {
 	typParam = strings.ToLower(strings.Replace(typParam, "-", "", -1))
 	return types.KeyType(strings.Join([]string{string(typ), typParam}, "-"))
 }
+
+func DefaultHashSum(h []byte) []byte {
+	arr := make([]byte, 32)
+	for i, b := range arr {
+		arr[i] = b
+	}
+	return arr
+}
+
+type DefaultSignerOptions struct{}
+
+func (h DefaultSignerOptions) HashFunc() crypto.Hash {
+	return 0
+}
-- 
GitLab


From ca9c53f4ae9b4dbc88544fff7138cdbf2d175454 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Tue, 16 Jan 2024 17:40:56 +0100
Subject: [PATCH 18/22] digest hashed before signing

---
 hsmCryptoProvider.go | 3 ++-
 main.go              | 9 +++++++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index 52c0bc4..6f9a14c 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -83,7 +83,8 @@ func (p HSMCryptoProvider) Sign(parameter types.CryptoIdentifier, data []byte) (
 	if err != nil {
 		return nil, err
 	}
-	return signer.Sign(p.controller.rand, data, p.controller.signerOptions)
+	hash := p.controller.hashSum(data)
+	return signer.Sign(p.controller.rand, hash, p.controller.signerOptions)
 }
 func (p HSMCryptoProvider) GetKeys(parameter types.CryptoIdentifier) (*types.CryptoKeySet, error) {
 	key, err := p.GetKey(parameter)
diff --git a/main.go b/main.go
index 9e5b983..1091740 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,8 @@
 package main
 
 import (
+	"crypto"
+	"crypto/sha256"
 	"github.com/ThalesIgnite/crypto11"
 	"github.com/spf13/viper"
 	"gitlab.eclipse.org/eclipse/xfsc/libraries/crypto/engine/core/types"
@@ -17,8 +19,11 @@ func (p *plugin) GetCryptoProvider() types.CryptoProvider {
 		TokenLabel: viper.GetString("HSM_PARTITION_LABEL"),
 		Pin:        viper.GetString("HSM_PARTITION_PASSWORD"),
 	}
-	//def := hsmController{config: &config, signerOptions: crypto.SHA256, hashSum: sha256.Sum256}
-	def := hsmController{config: &config, signerOptions: DefaultSignerOptions{}, hashSum: DefaultHashSum}
+	def := hsmController{config: &config, signerOptions: crypto.SHA256, hashSum: func(h []byte) []byte {
+		res := sha256.Sum256(h)
+		return res[:]
+	}}
+	//def := hsmController{config: &config, signerOptions: crypto.SHA35, hashSum: DefaultHashSum}
 
 	controller, err := def.withApiAndRandomReader()
 	if err != nil {
-- 
GitLab


From 452015f96f2780a2ee0ae56015f8cea5473344ce Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 17 Jan 2024 11:01:15 +0100
Subject: [PATCH 19/22] encrypt decrypt if key not found

---
 hsmCryptoProvider.go | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index 6f9a14c..18878c1 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -19,11 +19,15 @@ const (
 	HsmNamespace = "luna-cloud-hsm"
 )
 
+func getNotFoundError(keyId string) error {
+	return fmt.Errorf("could not find key with identifier `%s`", keyId)
+}
+
 func (p HSMCryptoProvider) getSigner(parameter types.CryptoIdentifier) (crypto11.Signer, error) {
 	id := []byte(parameter.KeyId)
 	signer, err := p.controller.api.FindKeyPair(id, nil)
 	if signer == nil && err == nil {
-		return nil, fmt.Errorf("could not find key with identifier `%s`", parameter.KeyId)
+		return nil, getNotFoundError(parameter.KeyId)
 	}
 	return signer, err
 }
@@ -64,6 +68,9 @@ func (p HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byte
 	if err != nil {
 		return nil, err
 	}
+	if key == nil {
+		return nil, getNotFoundError(parameter.KeyId)
+	}
 	var res []byte
 	key.Encrypt(res, data)
 	return res, nil
@@ -74,6 +81,9 @@ func (p HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byte
 	if err != nil {
 		return nil, err
 	}
+	if key == nil {
+		return nil, getNotFoundError(parameter.KeyId)
+	}
 	var res []byte
 	key.Decrypt(res, data)
 	return res, nil
-- 
GitLab


From a02bfaa8366a1923e4292da42141570fc37ec972 Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 17 Jan 2024 11:06:32 +0100
Subject: [PATCH 20/22] encrypt decrypt fixed

---
 hsmCryptoProvider.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index 18878c1..0ca9c55 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -71,7 +71,7 @@ func (p HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byte
 	if key == nil {
 		return nil, getNotFoundError(parameter.KeyId)
 	}
-	var res []byte
+	res := make([]byte, 0)
 	key.Encrypt(res, data)
 	return res, nil
 }
@@ -84,7 +84,7 @@ func (p HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byte
 	if key == nil {
 		return nil, getNotFoundError(parameter.KeyId)
 	}
-	var res []byte
+	res := make([]byte, 0)
 	key.Decrypt(res, data)
 	return res, nil
 }
-- 
GitLab


From 8e2e493240d95741fa4710763e1b2a1178beffba Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 17 Jan 2024 12:01:59 +0100
Subject: [PATCH 21/22] encrypt decrypt fixed

---
 hsmCryptoProvider.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index 0ca9c55..d4b8dd0 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -71,7 +71,7 @@ func (p HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byte
 	if key == nil {
 		return nil, getNotFoundError(parameter.KeyId)
 	}
-	res := make([]byte, 0)
+	res := make([]byte, key.BlockSize())
 	key.Encrypt(res, data)
 	return res, nil
 }
@@ -84,7 +84,7 @@ func (p HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byte
 	if key == nil {
 		return nil, getNotFoundError(parameter.KeyId)
 	}
-	res := make([]byte, 0)
+	res := make([]byte, key.BlockSize())
 	key.Decrypt(res, data)
 	return res, nil
 }
-- 
GitLab


From abffe4fd1ac2b273cc376b810bfd9d0b0a6b0d5f Mon Sep 17 00:00:00 2001
From: Maksim Gorelik <Maksim.Gorelik@t-systems.com>
Date: Wed, 17 Jan 2024 13:41:30 +0100
Subject: [PATCH 22/22] encrypt decrypt fixed

---
 hsmCryptoProvider.go | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/hsmCryptoProvider.go b/hsmCryptoProvider.go
index d4b8dd0..0f0d0cc 100644
--- a/hsmCryptoProvider.go
+++ b/hsmCryptoProvider.go
@@ -71,8 +71,12 @@ func (p HSMCryptoProvider) Encrypt(parameter types.CryptoIdentifier, data []byte
 	if key == nil {
 		return nil, getNotFoundError(parameter.KeyId)
 	}
-	res := make([]byte, key.BlockSize())
-	key.Encrypt(res, data)
+	res := make([]byte, key.BlockSize()+len(data))
+	mod, err := key.NewCBCEncrypter(res[:key.BlockSize()])
+	if err != nil {
+		return nil, err
+	}
+	mod.CryptBlocks(res[key.BlockSize():], data)
 	return res, nil
 }
 func (p HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
@@ -84,8 +88,9 @@ func (p HSMCryptoProvider) Decrypt(parameter types.CryptoIdentifier, data []byte
 	if key == nil {
 		return nil, getNotFoundError(parameter.KeyId)
 	}
-	res := make([]byte, key.BlockSize())
-	key.Decrypt(res, data)
+	res := make([]byte, key.BlockSize()+len(data))
+	mod, err := key.NewCBCDecrypter(res[:key.BlockSize()])
+	mod.CryptBlocks(res[key.BlockSize():], data)
 	return res, nil
 }
 func (p HSMCryptoProvider) Sign(parameter types.CryptoIdentifier, data []byte) ([]byte, error) {
-- 
GitLab