// Copyright 2015 Matthew Holt
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package certmagic

import (
	"bytes"
	"context"
	"crypto"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"fmt"
	"log"
	weakrand "math/rand"
	"net"
	"net/url"
	"strings"
	"time"

	"github.com/go-acme/lego/v3/challenge/tlsalpn01"
)

// Config configures a certificate manager instance.
// An empty Config is not valid: use New() to obtain
// a valid Config.
type Config struct {
	// How much of a certificate's lifetime becomes the
	// renewal window, which is the span of time at the
	// end of the certificate's validity period in which
	// it should be renewed; for most certificates, the
	// global default is good, but for exremely short-
	// lived certs, you may want to raise this to ~0.5.
	RenewalWindowRatio float64

	// An optional event callback clients can set
	// to subscribe to certain things happening
	// internally by this config; invocations are
	// synchronous, so make them return quickly!
	OnEvent func(event string, data interface{})

	// DefaultServerName specifies a server name
	// to use when choosing a certificate if the
	// ClientHello's ServerName field is empty
	DefaultServerName string

	// The state needed to operate on-demand TLS;
	// if non-nil, on-demand TLS is enabled and
	// certificate operations are deferred to
	// TLS handshakes (or as-needed)
	// TODO: Can we call this feature "Reactive/Lazy/Passive TLS" instead?
	OnDemand *OnDemandConfig

	// Add the must staple TLS extension to the
	// CSR generated by lego/acme
	MustStaple bool

	// The type that issues certificates; the
	// default Issuer is ACMEManager
	Issuer Issuer

	// The type that revokes certificates; must
	// be configured in conjunction with the Issuer
	// field such that both the Issuer and Revoker
	// are related (because issuance information is
	// required for revocation)
	Revoker Revoker

	// The source of new private keys for certificates;
	// the default KeySource is StandardKeyGenerator
	KeySource KeyGenerator

	// CertSelection chooses one of the certificates
	// with which the ClientHello will be completed;
	// if not set, DefaultCertificateSelector will
	// be used
	CertSelection CertificateSelector

	// The storage to access when storing or
	// loading TLS assets
	Storage Storage

	// required pointer to the in-memory cert cache
	certCache *Cache
}

// NewDefault makes a valid config based on the package
// Default config. Most users will call this function
// instead of New() since most use cases require only a
// single config for any and all certificates.
//
// If your requirements are more advanced (for example,
// multiple configs depending on the certificate), then use
// New() instead. (You will need to make your own Cache
// first.) If you only need a single Config to manage your
// certs (even if that config changes, as long as it is the
// only one), customize the Default package variable before
// calling NewDefault().
//
// All calls to NewDefault() will return configs that use the
// same, default certificate cache. All configs returned
// by NewDefault() are based on the values of the fields of
// Default at the time it is called.
func NewDefault() *Config {
	defaultCacheMu.Lock()
	if defaultCache == nil {
		defaultCache = NewCache(CacheOptions{
			// the cache will likely need to renew certificates,
			// so it will need to know how to do that, which
			// depends on the certificate being managed and which
			// can change during the lifetime of the cache; this
			// callback makes it possible to get the latest and
			// correct config with which to manage the cert,
			// but if the user does not provide one, we can only
			// assume that we are to use the default config
			GetConfigForCert: func(Certificate) (*Config, error) {
				return NewDefault(), nil
			},
		})
	}
	certCache := defaultCache
	defaultCacheMu.Unlock()

	return newWithCache(certCache, Default)
}

// New makes a new, valid config based on cfg and
// uses the provided certificate cache. certCache
// MUST NOT be nil or this function will panic.
//
// Use this method when you have an advanced use case
// that requires a custom certificate cache and config
// that may differ from the Default. For example, if
// not all certificates are managed/renewed the same
// way, you need to make your own Cache value with a
// GetConfigForCert callback that returns the correct
// configuration for each certificate. However, for
// the vast majority of cases, there will be only a
// single Config, thus the default cache (which always
// uses the default Config) and default config will
// suffice, and you should use New() instead.
func New(certCache *Cache, cfg Config) *Config {
	if certCache == nil {
		panic("a certificate cache is required")
	}
	if certCache.options.GetConfigForCert == nil {
		panic("cache must have GetConfigForCert set in its options")
	}
	return newWithCache(certCache, cfg)
}

// newWithCache ensures that cfg is a valid config by populating
// zero-value fields from the Default Config. If certCache is
// nil, this function panics.
func newWithCache(certCache *Cache, cfg Config) *Config {
	if certCache == nil {
		panic("cannot make a valid config without a pointer to a certificate cache")
	}

	if cfg.OnDemand == nil {
		cfg.OnDemand = Default.OnDemand
	}
	if cfg.RenewalWindowRatio == 0 {
		cfg.RenewalWindowRatio = Default.RenewalWindowRatio
	}
	if cfg.OnEvent == nil {
		cfg.OnEvent = Default.OnEvent
	}
	if cfg.KeySource == nil {
		cfg.KeySource = Default.KeySource
	}
	if cfg.DefaultServerName == "" {
		cfg.DefaultServerName = Default.DefaultServerName
	}
	if cfg.OnDemand == nil {
		cfg.OnDemand = Default.OnDemand
	}
	if !cfg.MustStaple {
		cfg.MustStaple = Default.MustStaple
	}
	if cfg.Storage == nil {
		cfg.Storage = Default.Storage
	}
	if cfg.Issuer == nil {
		cfg.Issuer = Default.Issuer
		if cfg.Issuer == nil {
			// okay really, we need an issuer,
			// that's kind of the point; most
			// people would probably want ACME
			cfg.Issuer = NewACMEManager(&cfg, DefaultACME)
		}
		// issuer and revoker go together; if user
		// specifies their own issuer, we don't want
		// to override their revoker, hence we only
		// do this if Issuer was also nil
		if cfg.Revoker == nil {
			cfg.Revoker = Default.Revoker
			if cfg.Revoker == nil {
				cfg.Revoker = NewACMEManager(&cfg, DefaultACME)
			}
		}
	}

	// absolutely don't allow a nil storage,
	// because that would make almost anything
	// a config can do pointless
	if cfg.Storage == nil {
		cfg.Storage = defaultFileStorage
	}

	// ensure the unexported fields are valid
	cfg.certCache = certCache

	return &cfg
}

// ManageSync causes the certificates for domainNames to be managed
// according to cfg. If cfg.OnDemand is not nil, then this simply
// whitelists the domain names and defers the certificate operations
// to when they are needed. Otherwise, the certificates for each
// name are loaded from storage or obtained from the CA. If loaded
// from storage, they are renewed if they are expiring or expired.
// It then caches the certificate in memory and is prepared to serve
// them up during TLS handshakes.
//
// Note that name whitelisting for on-demand management only takes
// effect if cfg.OnDemand.DecisionFunc is not set (is nil); it will
// not overwrite an existing DecisionFunc, nor will it overwrite
// its decision; i.e. the implicit whitelist is only used if no
// DecisionFunc is set.
//
// This method is synchronous, meaning that certificates for all
// domainNames must be successfully obtained (or renewed) before
// it returns. It returns immediately on the first error for any
// of the given domainNames. This behavior is recommended for
// interactive use (i.e. when an administrator is present) so
// that errors can be reported and fixed immediately.
func (cfg *Config) ManageSync(domainNames []string) error {
	return cfg.manageAll(nil, domainNames, false)
}

// ManageAsync is the same as ManageSync, except that ACME
// operations are performed asynchronously (in the background).
// This method returns before certificates are ready. It is
// crucial that the administrator monitors the logs and is
// notified of any errors so that corrective action can be
// taken as soon as possible. Any errors returned from this
// method occurred before ACME transactions started.
//
// As long as logs are monitored, this method is typically
// recommended for non-interactive environments.
//
// If there are failures loading, obtaining, or renewing a
// certificate, it will be retried with exponential backoff
// for up to about 30 days, with a maximum interval of about
// 24 hours. Cancelling ctx will cancel retries and shut down
// any goroutines spawned by ManageAsync.
func (cfg *Config) ManageAsync(ctx context.Context, domainNames []string) error {
	return cfg.manageAll(ctx, domainNames, true)
}

func (cfg *Config) manageAll(ctx context.Context, domainNames []string, async bool) error {
	if ctx == nil {
		ctx = context.Background()
	}

	for _, domainName := range domainNames {
		// if on-demand is configured, defer obtain and renew operations
		if cfg.OnDemand != nil {
			if !cfg.OnDemand.whitelistContains(domainName) {
				cfg.OnDemand.hostWhitelist = append(cfg.OnDemand.hostWhitelist, domainName)
			}
			continue
		}

		// otherwise, begin management immediately
		err := cfg.manageOne(ctx, domainName, async)
		if err != nil {
			return err
		}
	}

	return nil
}

func (cfg *Config) manageOne(ctx context.Context, domainName string, async bool) error {
	// first try loading existing certificate from storage
	cert, err := cfg.CacheManagedCertificate(domainName)
	if err != nil {
		if _, ok := err.(ErrNotExist); !ok {
			return fmt.Errorf("%s: caching certificate: %v", domainName, err)
		}
		// if we don't have one in storage, obtain one
		obtain := func() error {
			err := cfg.ObtainCert(ctx, domainName, !async)
			if err != nil {
				return fmt.Errorf("%s: obtaining certificate: %w", domainName, err)
			}
			cert, err = cfg.CacheManagedCertificate(domainName)
			if err != nil {
				return fmt.Errorf("%s: caching certificate after obtaining it: %v", domainName, err)
			}
			return nil
		}
		if async {
			// Leave the job name empty so as to allow duplicate 'obtain'
			// jobs; this is because Caddy calls ManageAsync() before the
			// previous config is stopped (and before its context is
			// canceled), which means that if an obtain job is still
			// running for the same domain, Submit() would not queue the
			// new one because it is still running, even though it is
			// (probably) about to be canceled (it might not if the new
			// config fails to finish loading, however). In any case, we
			// presume it is safe to enqueue a duplicate obtain job because
			// either the old one (or sometimes the new one) is about to be
			// canceled. This seems like reasonable logic for any consumer
			// of this lib. See https://github.com/caddyserver/caddy/issues/3202
			jm.Submit("", obtain)
			return nil
		}
		return obtain()
	}

	// for an existing certificate, make sure it is renewed
	renew := func() error {
		err := cfg.RenewCert(ctx, domainName, !async)
		if err != nil {
			return fmt.Errorf("%s: renewing certificate: %w", domainName, err)
		}
		// successful renewal, so update in-memory cache
		err = cfg.reloadManagedCertificate(cert)
		if err != nil {
			return fmt.Errorf("%s: reloading renewed certificate into memory: %v", domainName, err)
		}
		return nil
	}
	if cert.NeedsRenewal(cfg) {
		if async {
			jm.Submit("renew_"+domainName, renew)
			return nil
		}
		return renew()
	}

	return nil
}

// ObtainCert obtains a certificate for name using cfg, as long
// as a certificate does not already exist in storage for that
// name. The name must qualify and cfg must be flagged as Managed.
// This function is a no-op if storage already has a certificate
// for name.
//
// It only obtains and stores certificates (and their keys),
// it does not load them into memory. If interactive is true,
// the user may be shown a prompt.
// TODO: consider moving interactive param into the Config struct,
// and maybe retry settings into the Config struct as well? (same for RenewCert)
func (cfg *Config) ObtainCert(ctx context.Context, name string, interactive bool) error {
	if cfg.storageHasCertResources(name) {
		return nil
	}
	issuer, err := cfg.getPrecheckedIssuer([]string{name}, interactive)
	if err != nil {
		return err
	}
	if issuer == nil {
		return nil
	}
	return cfg.obtainWithIssuer(ctx, issuer, name, interactive)
}

func (cfg *Config) obtainWithIssuer(ctx context.Context, issuer Issuer, name string, interactive bool) error {
	log.Printf("[INFO][%s] Obtain certificate; acquiring lock...", name)

	// ensure idempotency of the obtain operation for this name
	lockKey := cfg.lockKey("cert_acme", name)
	err := obtainLock(cfg.Storage, lockKey)
	if err != nil {
		return err
	}
	defer func() {
		log.Printf("[INFO][%s] Obtain: Releasing lock", name)
		if err := releaseLock(cfg.Storage, lockKey); err != nil {
			log.Printf("[ERROR][%s] Obtain: Unable to unlock '%s': %v", name, lockKey, err)
		}
	}()
	log.Printf("[INFO][%s] Obtain: Lock acquired; proceeding...", name)

	f := func(ctx context.Context) error {
		// check if obtain is still needed -- might have been obtained during lock
		if cfg.storageHasCertResources(name) {
			log.Printf("[INFO][%s] Obtain: Certificate already exists in storage", name)
			return nil
		}

		privateKey, err := cfg.KeySource.GenerateKey()
		if err != nil {
			return err
		}
		privKeyPEM, err := encodePrivateKey(privateKey)
		if err != nil {
			return err
		}

		csr, err := cfg.generateCSR(privateKey, []string{name})
		if err != nil {
			return err
		}

		issuedCert, err := issuer.Issue(ctx, csr)
		if err != nil {
			return fmt.Errorf("[%s] Obtain: %w", name, err)
		}

		// success - immediately save the certificate resource
		certRes := CertificateResource{
			SANs:           namesFromCSR(csr),
			CertificatePEM: issuedCert.Certificate,
			PrivateKeyPEM:  privKeyPEM,
			IssuerData:     issuedCert.Metadata,
		}
		err = cfg.saveCertResource(certRes)
		if err != nil {
			return fmt.Errorf("[%s] Obtain: saving assets: %v", name, err)
		}
		return nil
	}
	if interactive {
		err = f(ctx)
	} else {
		err = doWithRetry(ctx, f)
	}
	if err != nil {
		return err
	}

	cfg.emit("cert_obtained", name)

	log.Printf("[INFO][%s] Certificate obtained successfully", name)

	return nil
}

// RenewCert renews the certificate for name using cfg. It stows the
// renewed certificate and its assets in storage if successful. It
// DOES NOT update the in-memory cache with the new certificate.
func (cfg *Config) RenewCert(ctx context.Context, name string, interactive bool) error {
	issuer, err := cfg.getPrecheckedIssuer([]string{name}, interactive)
	if err != nil {
		return err
	}
	if issuer == nil {
		return nil
	}
	return cfg.renewWithIssuer(ctx, issuer, name, interactive)
}

func (cfg *Config) renewWithIssuer(ctx context.Context, issuer Issuer, name string, interactive bool) error {
	log.Printf("[INFO][%s] Renew certificate; acquiring lock...", name)

	// ensure idempotency of the renew operation for this name
	lockKey := cfg.lockKey("cert_acme", name)
	err := obtainLock(cfg.Storage, lockKey)
	if err != nil {
		return err
	}
	defer func() {
		log.Printf("[INFO][%s] Renew: Releasing lock", name)
		if err := releaseLock(cfg.Storage, lockKey); err != nil {
			log.Printf("[ERROR][%s] Renew: Unable to unlock '%s': %v", name, lockKey, err)
		}
	}()
	log.Printf("[INFO][%s] Renew: Lock acquired; proceeding...", name)

	f := func(ctx context.Context) error {
		// prepare for renewal (load PEM cert, key, and meta)
		certRes, err := cfg.loadCertResource(name)
		if err != nil {
			return err
		}

		// check if renew is still needed - might have been renewed while waiting for lock
		timeLeft, needsRenew := cfg.managedCertNeedsRenewal(certRes)
		if !needsRenew {
			log.Printf("[INFO][%s] Renew: Certificate appears to have been renewed already (expires in %s)", name, timeLeft)
			return nil
		}
		log.Printf("[INFO][%s] Renew: %s remaining", name, timeLeft)

		privateKey, err := decodePrivateKey(certRes.PrivateKeyPEM)
		if err != nil {
			return err
		}
		csr, err := cfg.generateCSR(privateKey, []string{name})
		if err != nil {
			return err
		}

		issuedCert, err := issuer.Issue(ctx, csr)
		if err != nil {
			return fmt.Errorf("[%s] Renew: %w", name, err)
		}

		// success - immediately save the renewed certificate resource
		newCertRes := CertificateResource{
			SANs:           namesFromCSR(csr),
			CertificatePEM: issuedCert.Certificate,
			PrivateKeyPEM:  certRes.PrivateKeyPEM,
			IssuerData:     issuedCert.Metadata,
		}
		err = cfg.saveCertResource(newCertRes)
		if err != nil {
			return fmt.Errorf("[%s] Renew: saving assets: %v", name, err)
		}
		return nil
	}
	if interactive {
		err = f(ctx)
	} else {
		err = doWithRetry(ctx, f)
	}
	if err != nil {
		return err
	}

	cfg.emit("cert_renewed", name)

	log.Printf("[INFO][%s] Certificate renewed successfully", name)

	return nil
}

func (cfg *Config) generateCSR(privateKey crypto.PrivateKey, sans []string) (*x509.CertificateRequest, error) {
	csrTemplate := new(x509.CertificateRequest)

	for _, name := range sans {
		if ip := net.ParseIP(name); ip != nil {
			csrTemplate.IPAddresses = append(csrTemplate.IPAddresses, ip)
		} else if strings.Contains(name, "@") {
			csrTemplate.EmailAddresses = append(csrTemplate.EmailAddresses, name)
		} else if u, err := url.Parse(name); err == nil && strings.Contains(name, "/") {
			csrTemplate.URIs = append(csrTemplate.URIs, u)
		} else {
			csrTemplate.DNSNames = append(csrTemplate.DNSNames, name)
		}
	}

	if cfg.MustStaple {
		csrTemplate.ExtraExtensions = append(csrTemplate.ExtraExtensions, mustStapleExtension)
	}

	csrDER, err := x509.CreateCertificateRequest(rand.Reader, csrTemplate, privateKey)
	if err != nil {
		return nil, err
	}

	return x509.ParseCertificateRequest(csrDER)
}

// RevokeCert revokes the certificate for domain via ACME protocol. It requires
// that cfg.Issuer is properly configured with the same issuer that issued the
// certificate being revoked.
func (cfg *Config) RevokeCert(ctx context.Context, domain string, interactive bool) error {
	rev := cfg.Revoker
	if rev == nil {
		rev = Default.Revoker
	}

	certRes, err := cfg.loadCertResource(domain)
	if err != nil {
		return err
	}

	issuerKey := cfg.Issuer.IssuerKey()

	if !cfg.Storage.Exists(StorageKeys.SitePrivateKey(issuerKey, domain)) {
		return fmt.Errorf("private key not found for %s", certRes.SANs)
	}

	err = rev.Revoke(ctx, certRes)
	if err != nil {
		return err
	}

	cfg.emit("cert_revoked", domain)

	err = cfg.Storage.Delete(StorageKeys.SiteCert(issuerKey, domain))
	if err != nil {
		return fmt.Errorf("certificate revoked, but unable to delete certificate file: %v", err)
	}
	err = cfg.Storage.Delete(StorageKeys.SitePrivateKey(issuerKey, domain))
	if err != nil {
		return fmt.Errorf("certificate revoked, but unable to delete private key: %v", err)
	}
	err = cfg.Storage.Delete(StorageKeys.SiteMeta(issuerKey, domain))
	if err != nil {
		return fmt.Errorf("certificate revoked, but unable to delete certificate metadata: %v", err)
	}

	return nil
}

// TLSConfig is an opinionated method that returns a
// recommended, modern TLS configuration that can be
// used to configure TLS listeners, which also supports
// the TLS-ALPN challenge and serves up certificates
// managed by cfg.
//
// Unlike the package TLS() function, this method does
// not, by itself, enable certificate management for
// any domain names.
//
// Feel free to further customize the returned tls.Config,
// but do not mess with the GetCertificate or NextProtos
// fields unless you know what you're doing, as they're
// necessary to solve the TLS-ALPN challenge.
func (cfg *Config) TLSConfig() *tls.Config {
	return &tls.Config{
		// these two fields necessary for TLS-ALPN challenge
		GetCertificate: cfg.GetCertificate,
		NextProtos:     []string{"h2", "http/1.1", tlsalpn01.ACMETLS1Protocol},

		// the rest recommended for modern TLS servers
		MinVersion: tls.VersionTLS12,
		CurvePreferences: []tls.CurveID{
			tls.X25519,
			tls.CurveP256,
		},
		CipherSuites:             preferredDefaultCipherSuites(),
		PreferServerCipherSuites: true,
	}
}

// getPrecheckedIssuer returns an Issuer with pre-checks
// completed, if it is also a PreChecker. It also checks
// that storage is functioning. If a nil Issuer is returned
// with a nil error, that means to skip this operation
// (not an error, just a no-op).
func (cfg *Config) getPrecheckedIssuer(names []string, interactive bool) (Issuer, error) {
	// ensure storage is writeable and readable
	// TODO: this is not necessary every time; should only
	// perform check once every so often for each storage,
	// which may require some global state...
	err := cfg.checkStorage()
	if err != nil {
		return nil, fmt.Errorf("failed storage check: %v - storage is probably misconfigured", err)
	}
	if prechecker, ok := cfg.Issuer.(PreChecker); ok {
		err := prechecker.PreCheck(names, interactive)
		if err != nil {
			return nil, err
		}
	}
	return cfg.Issuer, nil
}

// checkStorage tests the storage by writing random bytes
// to a random key, and then loading those bytes and
// comparing the loaded value. If this fails, the provided
// cfg.Storage mechanism should not be used.
func (cfg *Config) checkStorage() error {
	key := fmt.Sprintf("rw_test_%d", weakrand.Int())
	contents := make([]byte, 1024*10) // size sufficient for one or two ACME resources
	_, err := weakrand.Read(contents)
	if err != nil {
		return err
	}
	err = cfg.Storage.Store(key, contents)
	if err != nil {
		return err
	}
	defer func() {
		deleteErr := cfg.Storage.Delete(key)
		if deleteErr != nil {
			log.Printf("[ERROR] Deleting test key %s from storage: %v", key, err)
		}
		// if there was no other error, make sure
		// to return any error returned from Delete
		if err == nil {
			err = deleteErr
		}
	}()
	loaded, err := cfg.Storage.Load(key)
	if err != nil {
		return err
	}
	if !bytes.Equal(contents, loaded) {
		return fmt.Errorf("load yielded different value than was stored; expected %d bytes, got %d bytes of differing elements", len(contents), len(loaded))
	}
	return nil
}

// storageHasCertResources returns true if the storage
// associated with cfg's certificate cache has all the
// resources related to the certificate for domain: the
// certificate, the private key, and the metadata.
func (cfg *Config) storageHasCertResources(domain string) bool {
	issuerKey := cfg.Issuer.IssuerKey()
	certKey := StorageKeys.SiteCert(issuerKey, domain)
	keyKey := StorageKeys.SitePrivateKey(issuerKey, domain)
	metaKey := StorageKeys.SiteMeta(issuerKey, domain)
	return cfg.Storage.Exists(certKey) &&
		cfg.Storage.Exists(keyKey) &&
		cfg.Storage.Exists(metaKey)
}

// lockKey returns a key for a lock that is specific to the operation
// named op being performed related to domainName and this config's CA.
func (cfg *Config) lockKey(op, domainName string) string {
	return fmt.Sprintf("%s_%s_%s", op, domainName, cfg.Issuer.IssuerKey())
}

// managedCertNeedsRenewal returns true if certRes is
// expiring soon or already expired, or if the process
// of checking the expiration returned an error.
func (cfg *Config) managedCertNeedsRenewal(certRes CertificateResource) (time.Duration, bool) {
	cert, err := makeCertificate(certRes.CertificatePEM, certRes.PrivateKeyPEM)
	if err != nil {
		return 0, true
	}
	return time.Until(cert.Leaf.NotAfter), cert.NeedsRenewal(cfg)
}

func (cfg *Config) emit(eventName string, data interface{}) {
	if cfg.OnEvent == nil {
		return
	}
	cfg.OnEvent(eventName, data)
}

// CertificateSelector is a type which can select a certificate to use given multiple choices.
type CertificateSelector interface {
	SelectCertificate(*tls.ClientHelloInfo, []Certificate) (Certificate, error)
}

// Constants for PKIX MustStaple extension.
var (
	tlsFeatureExtensionOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 24}
	ocspMustStapleFeature  = []byte{0x30, 0x03, 0x02, 0x01, 0x05}
	mustStapleExtension    = pkix.Extension{
		Id:    tlsFeatureExtensionOID,
		Value: ocspMustStapleFeature,
	}
)