func (ks *CryptoKeyStore) HasSignKeys() error {
	if len(ks.signKeys) > 0 {
		return nil
	}
	return errors.ErrCryptoKeyStoreNoSignKeysFound
}
HasSignKeys returns true if CryptoKeyStore has key signing
capabilities.
package kms
import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/x509"
	"encoding/pem"
	jwtlib "github.com/golang-jwt/jwt"
	"github.com/greenpau/caddy-authorize/pkg/errors"
	"github.com/greenpau/caddy-authorize/pkg/shared"
	"github.com/greenpau/caddy-authorize/pkg/user"
	"go.uber.org/zap"
	"strings"
)
var (
	reservedTokenNames = map[string]bool{
		"access_token":     true,
		"jwt_access_token": true,
		"bearer":           true,
	}
)
type CryptoKeyStore struct {
	keys       []*CryptoKey
	signKeys   []*CryptoKey
	verifyKeys []*CryptoKey
	logger     *zap.Logger
	defaults   map[string]interface{}
}
func NewCryptoKeyStore() *CryptoKeyStore {
	ks := &CryptoKeyStore{}
	ks.defaults = make(map[string]interface{})
	return ks
}
func (ks *CryptoKeyStore) SetLogger(logger *zap.Logger) {
	ks.logger = logger
}
func (ks *CryptoKeyStore) AddDefaults(m map[string]interface{}) error {
	if m == nil {
		return nil
	}
	if ks.defaults == nil {
		ks.defaults = make(map[string]interface{})
	}
	for k, v := range m {
		switch k {
		case "token_name":
			ks.defaults[k] = v.(string)
		case "token_lifetime":
			ks.defaults[k] = int(v.(float64))
		default:
			ks.defaults[k] = v
		}
	}
	return nil
}
func (ks *CryptoKeyStore) AutoGenerate(tag, algo string) error {
	var generated bool
	var kb string
	cfg := &CryptoKeyConfig{
		ID:            "0",
		Usage:         "sign-verify",
		TokenName:     "access_token",
		Source:        "config",
		TokenLifetime: 900,
		parsed:        true,
	}
	if ks.defaults != nil {
		if _, exists := ks.defaults["token_name"]; exists {
			cfg.TokenName = ks.defaults["token_name"].(string)
		}
		if _, exists := ks.defaults["token_lifetime"]; exists {
			cfg.TokenLifetime = ks.defaults["token_lifetime"].(int)
		}
	}
	if len(ks.keys) > 0 {
		return errors.ErrCryptoKeyStoreAutoGenerateNotAvailable
	}
	for i := 1; i < 5; i++ {
		switch algo {
		case "ES512":
			c := elliptic.P521()
			priv, err := ecdsa.GenerateKey(c, rand.Reader)
			if err != nil {
				break
			}
			if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) {
				break
			}
			derBytes, err := x509.MarshalECPrivateKey(priv)
			if err != nil {
				break
			}
			pemBytes := pem.EncodeToMemory(
				&pem.Block{
					Type:  "EC PRIVATE KEY",
					Bytes: derBytes,
				},
			)
			if pemBytes == nil {
				break
			}
			kb = string(pemBytes)
			generated = true
		default:
			return errors.ErrCryptoKeyStoreAutoGenerateAlgo.WithArgs(algo)
		}
	}
	if !generated {
		return errors.ErrCryptoKeyStoreAutoGenerateFailed.WithArgs("failed")
	}
	if err := shared.Buffer.Add(tag, kb); err != nil {
		if err.Error() != "not empty" {
			return errors.ErrCryptoKeyStoreAutoGenerateFailed.WithArgs(err)
		}
		kb, err = shared.Buffer.Get(tag)
		if err != nil {
			return errors.ErrCryptoKeyStoreAutoGenerateFailed.WithArgs(err)
		}
	}
	key, err := extractKey([]byte(kb), cfg)
	if err != nil {
		return errors.ErrCryptoKeyStoreAutoGenerateFailed.WithArgs(err)
	}
	key.enableUsage()
	ks.keys = append(ks.keys, key)
	ks.signKeys = append(ks.signKeys, key)
	ks.verifyKeys = append(ks.verifyKeys, key)
	return nil
}
func (ks *CryptoKeyStore) GetKeys() []*CryptoKey {
	return ks.keys
}
func (ks *CryptoKeyStore) GetSignKeys() []*CryptoKey {
	return ks.signKeys
}
func (ks *CryptoKeyStore) GetVerifyKeys() []*CryptoKey {
	return ks.verifyKeys
}
func (ks *CryptoKeyStore) AddKeysWithConfigs(cfgs []*CryptoKeyConfig) error {
	keys, err := GetKeysFromConfigs(cfgs)
	if err != nil {
		return err
	}
	for _, k := range keys {
		if err := ks.AddKey(k); err != nil {
			return err
		}
	}
	return nil
}
func (ks *CryptoKeyStore) HasVerifyKeys() error {
	if len(ks.verifyKeys) > 0 {
		return nil
	}
	return errors.ErrCryptoKeyStoreNoVerifyKeysFound
}