func (sp *StandardProvider) Store() error {
	if !sp.Ready() {
		return errors.New("transport: provider does not have a key and certificate")
	}
	err := ioutil.WriteFile(sp.Paths.CertFile, sp.internal.certPEM, 0644)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(sp.Paths.KeyFile, sp.internal.keyPEM, 0600)
}
Store writes the key and certificate to disk, if necessary.
package kp
import (
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"errors"
	"io/ioutil"
	"strings"
	"github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/helpers"
	"github.com/cloudflare/cfssl/transport/core"
)
const (
	curveP256 = 256
	curveP384 = 384
	curveP521 = 521
)
type KeyProvider interface {
	Certificate() *x509.Certificate
	CertificateRequest(*csr.CertificateRequest) ([]byte, error)
	Check() error
	Generate(algo string, size int) error
	Load() error
	Persistent() bool
	Ready() bool
	SetCertificatePEM([]byte) error
	SignalFailure(err error) bool
	SignCSR(csr *x509.CertificateRequest) ([]byte, error)
	Store() error
	X509KeyPair() (tls.Certificate, error)
}
type StandardPaths struct {
	KeyFile  string `json:"private_key"`
	CertFile string `json:"certificate"`
}
type StandardProvider struct {
	Paths    StandardPaths `json:"paths"`
	internal struct {
		priv crypto.Signer
		cert *x509.Certificate
		keyPEM  []byte
		certPEM []byte
	}
}
func NewStandardProvider(id *core.Identity) (*StandardProvider, error) {
	if id == nil {
		return nil, errors.New("transport: the identity hasn't been initialised. Has it been loaded from disk?")
	}
	paths := id.Profiles["paths"]
	if paths == nil {
		return &StandardProvider{}, nil
	}
	sp := &StandardProvider{
		Paths: StandardPaths{
			KeyFile:  paths["private_key"],
			CertFile: paths["certificate"],
		},
	}
	err := sp.Check()
	if err != nil {
		return nil, err
	}
	return sp, nil
}
func (sp *StandardProvider) resetCert() {
	sp.internal.cert = nil
	sp.internal.certPEM = nil
}
func (sp *StandardProvider) resetKey() {
	sp.internal.priv = nil
	sp.internal.keyPEM = nil
}
var (
	ErrMissingKeyPath = errors.New("transport: standard provider is missing a private key path to accompany the certificate path")
	ErrMissingCertPath = errors.New("transport: standard provider is missing a certificate path to accompany the certificate path")
)
func (sp *StandardProvider) Check() error {
	if sp.Paths.KeyFile == "" && sp.Paths.CertFile == "" {
		return nil
	}
	if sp.Paths.KeyFile == "" {
		return ErrMissingKeyPath
	}
	if sp.Paths.CertFile == "" {
		return ErrMissingCertPath
	}
	return nil
}
func (sp *StandardProvider) Persistent() bool {
	return sp.Paths.KeyFile != "" && sp.Paths.CertFile != ""
}
func (sp *StandardProvider) Generate(algo string, size int) (err error) {
	sp.resetKey()
	sp.resetCert()
	algo = strings.ToLower(algo)
	switch algo {
	case "rsa":
		var priv *rsa.PrivateKey
		if size < 2048 {
			return errors.New("transport: RSA keys must be at least 2048 bits")
		}
		priv, err = rsa.GenerateKey(rand.Reader, size)
		if err != nil {
			return err
		}
		keyPEM := x509.MarshalPKCS1PrivateKey(priv)
		p := &pem.Block{
			Type:  "RSA PRIVATE KEY",
			Bytes: keyPEM,
		}
		sp.internal.keyPEM = pem.EncodeToMemory(p)
		sp.internal.priv = priv
	case "ecdsa":
		var priv *ecdsa.PrivateKey
		var curve elliptic.Curve
		switch size {
		case curveP256:
			curve = elliptic.P256()
		case curveP384:
			curve = elliptic.P384()
		case curveP521:
			curve = elliptic.P521()
		default:
			return errors.New("transport: invalid elliptic curve key size; only 256-, 384-, and 521-bit keys are accepted")
		}
		priv, err = ecdsa.GenerateKey(curve, rand.Reader)
		if err != nil {
			return err
		}
		var keyPEM []byte
		keyPEM, err = x509.MarshalECPrivateKey(priv)
		if err != nil {
			return err
		}
		p := &pem.Block{
			Type:  "EC PRIVATE KEY",
			Bytes: keyPEM,
		}
		sp.internal.keyPEM = pem.EncodeToMemory(p)
		sp.internal.priv = priv
	default:
		return errors.New("transport: invalid key algorithm; only RSA and ECDSA are supported")
	}
	return nil
}
func (sp *StandardProvider) Certificate() *x509.Certificate {
	return sp.internal.cert
}
func (sp *StandardProvider) CertificateRequest(req *csr.CertificateRequest) ([]byte, error) {
	if sp.internal.priv == nil {
		if req.KeyRequest == nil {
			return nil, errors.New("transport: invalid key request in csr.CertificateRequest")
		}
		sp.Generate(req.KeyRequest.Algo(), req.KeyRequest.Size())
	}
	return csr.Generate(sp.internal.priv, req)
}
var ErrCertificateUnavailable = errors.New("transport: certificate unavailable")
func (sp *StandardProvider) Load() (err error) {
	if !sp.Persistent() {
		return
	}
	var clearKey = true
	defer func() {
		if err != nil {
			if clearKey {
				sp.resetKey()
			}
			sp.resetCert()
		}
	}()
	sp.internal.keyPEM, err = ioutil.ReadFile(sp.Paths.KeyFile)
	if err != nil {
		return
	}
	sp.internal.priv, err = helpers.ParsePrivateKeyPEM(sp.internal.keyPEM)
	if err != nil {
		return
	}
	clearKey = false
	sp.internal.certPEM, err = ioutil.ReadFile(sp.Paths.CertFile)
	if err != nil {
		return ErrCertificateUnavailable
	}
	sp.internal.cert, err = helpers.ParseCertificatePEM(sp.internal.certPEM)
	if err != nil {
		err = errors.New("transport: invalid certificate")
		return
	}
	p, _ := pem.Decode(sp.internal.keyPEM)
	switch sp.internal.cert.PublicKey.(type) {
	case *rsa.PublicKey:
		if p.Type != "RSA PRIVATE KEY" {
			err = errors.New("transport: PEM type " + p.Type + " is invalid for an RSA key")
			return
		}
	case *ecdsa.PublicKey:
		if p.Type != "EC PRIVATE KEY" {
			err = errors.New("transport: PEM type " + p.Type + " is invalid for an ECDSA key")
			return
		}
	default:
		err = errors.New("transport: invalid public key type")
	}
	if err != nil {
		clearKey = true
		return
	}
	return nil
}
func (sp *StandardProvider) Ready() bool {
	switch {
	case sp.internal.priv == nil:
		return false
	case sp.internal.cert == nil:
		return false
	case sp.internal.keyPEM == nil:
		return false
	case sp.internal.certPEM == nil:
		return false
	default:
		return true
	}
}
func (sp *StandardProvider) SetCertificatePEM(certPEM []byte) error {
	cert, err := helpers.ParseCertificatePEM(certPEM)
	if err != nil {
		return errors.New("transport: invalid certificate")
	}
	sp.internal.certPEM = certPEM
	sp.internal.cert = cert
	return nil
}
func (sp *StandardProvider) SignalFailure(err error) bool {
	return false
}
func (sp *StandardProvider) SignCSR(tpl *x509.CertificateRequest) ([]byte, error) {
	return x509.CreateCertificateRequest(rand.Reader, tpl, sp.internal.priv)
}