func (s *service) ResolveKeystore(req *http.Request) (keystore.Keystore, error) {
	start := time.Now()
	defer func() { s.metrics.ResolveKeystoreTime(time.Since(start)) }()
	keystoreID := mux.Vars(req)[keystoreIDQueryParam]
	keystoreData, err := s.GetKeystoreData(keystoreID)
	if err != nil {
		return nil, fmt.Errorf("resolve keystore: %w", err)
	}
	storageProvider := s.config.UserKeysStorageProvider
	if s.config.EDVServerURL != "" {
		p, e := s.prepareEDVStorageProvider(keystoreData)
		if e != nil {
			return nil, fmt.Errorf("resolve keystore: %w", e)
		}
		storageProvider = p
	}
	primaryKeyLock := s.config.PrimaryKeyLock
	keyURI := fmt.Sprintf(primaryKeyURI, keystoreDB)
	if s.config.HubAuthURL != "" {
		l, e := s.prepareSecretSplitLock(req)
		if e != nil {
			return nil, fmt.Errorf("resolve keystore: %w", e)
		}
		primaryKeyLock = l
		keyURI = fmt.Sprintf(primaryKeyURI, keystoreID)
	}
	secLockProvider := &secretLockProvider{
		storageProvider: storageProvider,
		secretLock:      primaryKeyLock,
	}
	secretLock, err := s.config.CreateSecretLockFunc(keyURI, secLockProvider, s.config.SyncTimeout)
	if err != nil {
		return nil, fmt.Errorf("resolve keystore: %w", err)
	}
	k, err := keystore.New(
		keystore.WithPrimaryKeyURI(keyURI),
		keystore.WithStorageProvider(storageProvider),
		keystore.WithSecretLock(secretLock),
	)
	if err != nil {
		return nil, fmt.Errorf("resolve keystore: %w", err)
	}
	return k, nil
}
ResolveKeystore resolves Keystore for the given request.
package kms
import (
	"crypto/tls"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"time"
	"github.com/gorilla/mux"
	"github.com/hyperledger/aries-framework-go/pkg/crypto"
	"github.com/hyperledger/aries-framework-go/pkg/kms"
	"github.com/hyperledger/aries-framework-go/pkg/secretlock"
	"github.com/hyperledger/aries-framework-go/spi/storage"
	"github.com/rs/xid"
	"github.com/trustbloc/kms/pkg/internal/support"
	"github.com/trustbloc/kms/pkg/keystore"
	lock "github.com/trustbloc/kms/pkg/secretlock"
	"github.com/trustbloc/kms/pkg/secretlock/secretsplitlock"
	"github.com/trustbloc/kms/pkg/storage/edv"
)
const (
	keystoreDB           = "keystoredb"
	primaryKeyURI        = "local-lock://%s"
	keystoreIDQueryParam = "keystoreID"
	secretHeader         = "Hub-Kms-Secret"  
	userHeader           = "Hub-Kms-User"
)
type metricsProvider interface {
	ResolveKeystoreTime(value time.Duration)
}
type Config struct {
	StorageProvider         storage.Provider
	CacheProvider           storage.Provider
	UserKeysStorageProvider storage.Provider
	LocalKMS      kms.KeyManager
	CryptoService crypto.Crypto
	HeaderSigner  edv.HeaderSigner
	Metrics       metricsProvider
	PrimaryKeyLock       secretlock.Service
	CreateSecretLockFunc func(keyURI string, provider lock.Provider, timeout uint64) (secretlock.Service, error)
	EDVServerURL    string
	HubAuthURL      string
	HubAuthAPIToken string
	HTTPClient support.HTTPClient
	TLSConfig  *tls.Config
	SyncTimeout         uint64
	EdvRecipientKeyType kms.KeyType
}
type service struct {
	store    storage.Store
	localKMS kms.KeyManager
	crypto   crypto.Crypto
	config   *Config
	metrics  metricsProvider
}
func NewService(c *Config) (Service, error) {
	store, err := c.StorageProvider.OpenStore(keystoreDB)
	if err != nil {
		return nil, fmt.Errorf("new service: %w", err)
	}
	return &service{
		store:    store,
		localKMS: c.LocalKMS,
		crypto:   c.CryptoService,
		config:   c,
		metrics:  c.Metrics,
	}, nil
}
func (s *service) CreateKeystore(controller, vaultID string) (*KeystoreData, error) {
	var recipientKeyID, macKeyID string
	if vaultID != "" {
		recKID, _, err := s.localKMS.Create(s.config.EdvRecipientKeyType)
		if err != nil {
			return nil, fmt.Errorf("create keystore: %w", err)
		}
		recipientKeyID = recKID
		macKID, _, err := s.localKMS.Create(kms.HMACSHA256Tag256)
		if err != nil {
			return nil, fmt.Errorf("create keystore: %w", err)
		}
		macKeyID = macKID
	}
	createdAt := time.Now().UTC()
	keystoreData := &KeystoreData{
		ID:             xid.New().String(),
		Controller:     controller,
		RecipientKeyID: recipientKeyID,
		MACKeyID:       macKeyID,
		VaultID:        vaultID,
		CreatedAt:      &createdAt,
	}
	err := s.SaveKeystoreData(keystoreData)
	if err != nil {
		return nil, fmt.Errorf("create keystore: %w", err)
	}
	return keystoreData, nil
}