func WithSubject(sub pkix.Name) WithOption {
	return func(p Profile) error {
		crt := p.Subject()
		crt.Subject = sub
		return nil
	}
}
WithSubject returns a Profile modifier that sets the Subject for a x509
Certificate.
package x509util
import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/pem"
	"math/big"
	"net"
	"net/url"
	"strings"
	"time"
	"github.com/pkg/errors"
	"github.com/smallstep/cli/crypto/keys"
	"github.com/smallstep/cli/crypto/pemutil"
	"github.com/smallstep/cli/utils"
)
var (
	oidExtSubjectKeyID          = asn1.ObjectIdentifier([]int{2, 5, 29, 14})
	oidExtKeyUsage              = asn1.ObjectIdentifier([]int{2, 5, 29, 15})
	oidExtExtendedKeyUsage      = asn1.ObjectIdentifier([]int{2, 5, 29, 37})
	oidExtAuthorityKeyID        = asn1.ObjectIdentifier([]int{2, 5, 29, 35})
	oidExtBasicConstraints      = asn1.ObjectIdentifier([]int{2, 5, 29, 19})
	oidExtSubjectAltName        = asn1.ObjectIdentifier([]int{2, 5, 29, 17})
	oidExtCertificatePolicies   = asn1.ObjectIdentifier([]int{2, 5, 29, 32})
	oidExtNameConstraints       = asn1.ObjectIdentifier([]int{2, 5, 29, 30})
	oidExtCRLDistributionPoints = asn1.ObjectIdentifier([]int{2, 5, 29, 31})
	oidExtAuthorityInfoAccess   = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 1, 1})
	oidStdExtHashMap            = map[string]struct{}{}
	emptyStruct                 struct{}
)
func init() {
	oidStdExtHashMap[oidExtSubjectKeyID.String()] = emptyStruct
	oidStdExtHashMap[oidExtKeyUsage.String()] = emptyStruct
	oidStdExtHashMap[oidExtExtendedKeyUsage.String()] = emptyStruct
	oidStdExtHashMap[oidExtAuthorityKeyID.String()] = emptyStruct
	oidStdExtHashMap[oidExtBasicConstraints.String()] = emptyStruct
	oidStdExtHashMap[oidExtSubjectAltName.String()] = emptyStruct
	oidStdExtHashMap[oidExtCertificatePolicies.String()] = emptyStruct
	oidStdExtHashMap[oidExtNameConstraints.String()] = emptyStruct
	oidStdExtHashMap[oidExtCRLDistributionPoints.String()] = emptyStruct
	oidStdExtHashMap[oidExtAuthorityInfoAccess.String()] = emptyStruct
}
var (
	DefaultCertValidity = 24 * time.Hour
	DefaultTLSMinVersion = TLSVersion(1.2)
	DefaultTLSMaxVersion = TLSVersion(1.2)
	DefaultTLSRenegotiation = false  
	DefaultTLSCipherSuites = CipherSuites{
		"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
		"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
	}
	ApprovedTLSCipherSuites = CipherSuites{
		"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
		"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
		"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
		"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
		"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
		"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
		"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
		"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
		"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
		"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
		"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
		"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
	}
	oidExtensionCTPoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3}
)
type Profile interface {
	Issuer() *x509.Certificate
	Subject() *x509.Certificate
	SubjectPrivateKey() interface{}
	SubjectPublicKey() interface{}
	SetIssuer(*x509.Certificate)
	SetSubject(*x509.Certificate)
	SetSubjectPrivateKey(interface{})
	SetSubjectPublicKey(interface{})
	SetIssuerPrivateKey(interface{})
	CreateCertificate() ([]byte, error)
	GenerateKeyPair(string, string, int) error
	DefaultDuration() time.Duration
	CreateWriteCertificate(crtOut, keyOut, pass string) ([]byte, error)
	AddExtension(pkix.Extension)
	RemoveExtension(asn1.ObjectIdentifier)
}
type base struct {
	iss     *x509.Certificate
	sub     *x509.Certificate
	ext     []pkix.Extension
	subPub  interface{}
	subPriv interface{}
	issPriv interface{}
}
type WithOption func(Profile) error
func GenerateKeyPair(kty, crv string, size int) WithOption {
	return func(p Profile) error {
		return p.GenerateKeyPair(kty, crv, size)
	}
}
func GenerateDefaultKeyPair(p Profile) error {
	pub, priv, err := keys.GenerateDefaultKeyPair()
	if err != nil {
		return err
	}
	p.SetSubjectPublicKey(pub)
	p.SetSubjectPrivateKey(priv)
	return nil
}
func WithPublicKey(pub interface{}) WithOption {
	return func(p Profile) error {
		p.SetSubjectPublicKey(pub)
		return nil
	}
}