mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-03 19:17:29 -05:00 
			
		
		
		
	All code relating to a caddytls.Config and setting it up from the Caddyfile is still intact; only the certificate management-related code was removed into a separate package. I don't expect this to build in CI successfully; updating dependencies and vendor is coming next. I've also removed the ad-hoc, half-baked storage plugins that we need to finish making first-class Caddy plugins (they were never documented anyway). The new certmagic package has a much better storage interface, and we can finally move toward making a new storage plugin type, but it shouldn't be configurable in the Caddyfile, I think, since it doesn't make sense for a Caddy instance to use more than one storage config... We also have the option of eliminating DNS provider plugins and just shipping all of lego's DNS providers by using a lego package (the caddytls/setup.go file has a comment describing how) -- but it doubles Caddy's binary size by 100% from about 19 MB to around 40 MB...!
		
			
				
	
	
		
			107 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package caddytls
 | 
						|
 | 
						|
import (
 | 
						|
	"crypto/ecdsa"
 | 
						|
	"crypto/elliptic"
 | 
						|
	"crypto/rand"
 | 
						|
	"crypto/rsa"
 | 
						|
	"crypto/tls"
 | 
						|
	"crypto/x509"
 | 
						|
	"crypto/x509/pkix"
 | 
						|
	"fmt"
 | 
						|
	"math/big"
 | 
						|
	"net"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/xenolf/lego/certcrypto"
 | 
						|
)
 | 
						|
 | 
						|
// newSelfSignedCertificate returns a new self-signed certificate.
 | 
						|
func newSelfSignedCertificate(ssconfig selfSignedConfig) (tls.Certificate, error) {
 | 
						|
	// start by generating private key
 | 
						|
	var privKey interface{}
 | 
						|
	var err error
 | 
						|
	switch ssconfig.KeyType {
 | 
						|
	case "", certcrypto.EC256:
 | 
						|
		privKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 | 
						|
	case certcrypto.EC384:
 | 
						|
		privKey, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
 | 
						|
	case certcrypto.RSA2048:
 | 
						|
		privKey, err = rsa.GenerateKey(rand.Reader, 2048)
 | 
						|
	case certcrypto.RSA4096:
 | 
						|
		privKey, err = rsa.GenerateKey(rand.Reader, 4096)
 | 
						|
	case certcrypto.RSA8192:
 | 
						|
		privKey, err = rsa.GenerateKey(rand.Reader, 8192)
 | 
						|
	default:
 | 
						|
		return tls.Certificate{}, fmt.Errorf("cannot generate private key; unknown key type %v", ssconfig.KeyType)
 | 
						|
	}
 | 
						|
	if err != nil {
 | 
						|
		return tls.Certificate{}, fmt.Errorf("failed to generate private key: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	// create certificate structure with proper values
 | 
						|
	notBefore := time.Now()
 | 
						|
	notAfter := ssconfig.Expire
 | 
						|
	if notAfter.IsZero() || notAfter.Before(notBefore) {
 | 
						|
		notAfter = notBefore.Add(24 * time.Hour * 7)
 | 
						|
	}
 | 
						|
	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
 | 
						|
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
 | 
						|
	if err != nil {
 | 
						|
		return tls.Certificate{}, fmt.Errorf("failed to generate serial number: %v", err)
 | 
						|
	}
 | 
						|
	cert := &x509.Certificate{
 | 
						|
		SerialNumber: serialNumber,
 | 
						|
		Subject:      pkix.Name{Organization: []string{"Caddy Self-Signed"}},
 | 
						|
		NotBefore:    notBefore,
 | 
						|
		NotAfter:     notAfter,
 | 
						|
		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
 | 
						|
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
 | 
						|
	}
 | 
						|
	if len(ssconfig.SAN) == 0 {
 | 
						|
		ssconfig.SAN = []string{""}
 | 
						|
	}
 | 
						|
	var names []string
 | 
						|
	for _, san := range ssconfig.SAN {
 | 
						|
		if ip := net.ParseIP(san); ip != nil {
 | 
						|
			names = append(names, strings.ToLower(ip.String()))
 | 
						|
			cert.IPAddresses = append(cert.IPAddresses, ip)
 | 
						|
		} else {
 | 
						|
			names = append(names, strings.ToLower(san))
 | 
						|
			cert.DNSNames = append(cert.DNSNames, strings.ToLower(san))
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// generate the associated public key
 | 
						|
	publicKey := func(privKey interface{}) interface{} {
 | 
						|
		switch k := privKey.(type) {
 | 
						|
		case *rsa.PrivateKey:
 | 
						|
			return &k.PublicKey
 | 
						|
		case *ecdsa.PrivateKey:
 | 
						|
			return &k.PublicKey
 | 
						|
		default:
 | 
						|
			return fmt.Errorf("unknown key type")
 | 
						|
		}
 | 
						|
	}
 | 
						|
	derBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, publicKey(privKey), privKey)
 | 
						|
	if err != nil {
 | 
						|
		return tls.Certificate{}, fmt.Errorf("could not create certificate: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	chain := [][]byte{derBytes}
 | 
						|
 | 
						|
	return tls.Certificate{
 | 
						|
		Certificate: chain,
 | 
						|
		PrivateKey:  privKey,
 | 
						|
		Leaf:        cert,
 | 
						|
	}, nil
 | 
						|
}
 | 
						|
 | 
						|
// selfSignedConfig configures a self-signed certificate.
 | 
						|
type selfSignedConfig struct {
 | 
						|
	SAN     []string
 | 
						|
	KeyType certcrypto.KeyType
 | 
						|
	Expire  time.Time
 | 
						|
}
 |