summaryrefslogtreecommitdiff
path: root/modules/caddytls
diff options
context:
space:
mode:
authorMatt Holt <mholt@users.noreply.github.com>2019-08-21 11:28:03 -0600
committerGitHub <noreply@github.com>2019-08-21 11:28:03 -0600
commit0544f0266a11874efb305a46db762248e64bc62d (patch)
tree3e75e6f59047bb967c52915e1e75aee6ad67c0ea /modules/caddytls
parent42f75a4ca94ef3fb5e15a74e5dc9ef8b4f1f0b39 (diff)
parentb2aa679c33f63ebec5bc1a21bca01f345dffebdd (diff)
Merge pull request #2699 from caddyserver/cfadapter
v2: Implement config adapters and WIP Caddyfile adapter
Diffstat (limited to 'modules/caddytls')
-rw-r--r--modules/caddytls/acmemanager.go19
-rw-r--r--modules/caddytls/connpolicy.go8
-rw-r--r--modules/caddytls/fileloader.go21
-rw-r--r--modules/caddytls/folderloader.go21
-rw-r--r--modules/caddytls/matchers.go13
-rw-r--r--modules/caddytls/sessiontickets.go2
-rw-r--r--modules/caddytls/standardstek/stek.go13
-rw-r--r--modules/caddytls/tls.go52
-rw-r--r--modules/caddytls/values.go36
9 files changed, 114 insertions, 71 deletions
diff --git a/modules/caddytls/acmemanager.go b/modules/caddytls/acmemanager.go
index 578cdb3..36f1c21 100644
--- a/modules/caddytls/acmemanager.go
+++ b/modules/caddytls/acmemanager.go
@@ -28,10 +28,7 @@ import (
)
func init() {
- caddy.RegisterModule(caddy.Module{
- Name: "tls.management.acme",
- New: func() interface{} { return new(ACMEManagerMaker) },
- })
+ caddy.RegisterModule(ACMEManagerMaker{})
}
// ACMEManagerMaker makes an ACME manager
@@ -57,9 +54,17 @@ type ACMEManagerMaker struct {
keyType certcrypto.KeyType
}
-// newManager is a no-op to satisfy the ManagerMaker interface,
+// CaddyModule returns the Caddy module information.
+func (ACMEManagerMaker) CaddyModule() caddy.ModuleInfo {
+ return caddy.ModuleInfo{
+ Name: "tls.management.acme",
+ New: func() caddy.Module { return new(ACMEManagerMaker) },
+ }
+}
+
+// NewManager is a no-op to satisfy the ManagerMaker interface,
// because this manager type is a special case.
-func (m *ACMEManagerMaker) newManager(interactive bool) (certmagic.Manager, error) {
+func (m ACMEManagerMaker) NewManager(interactive bool) (certmagic.Manager, error) {
return nil, nil
}
@@ -203,4 +208,4 @@ func onDemandAskRequest(ask string, name string) error {
}
// Interface guard
-var _ managerMaker = (*ACMEManagerMaker)(nil)
+var _ ManagerMaker = (*ACMEManagerMaker)(nil)
diff --git a/modules/caddytls/connpolicy.go b/modules/caddytls/connpolicy.go
index 8cb6ffe..e061281 100644
--- a/modules/caddytls/connpolicy.go
+++ b/modules/caddytls/connpolicy.go
@@ -172,7 +172,7 @@ func (p *ConnectionPolicy) buildStandardTLSConfig(ctx caddy.Context) error {
// add all the cipher suites in order, without duplicates
cipherSuitesAdded := make(map[uint16]struct{})
for _, csName := range p.CipherSuites {
- csID := supportedCipherSuites[csName]
+ csID := SupportedCipherSuites[csName]
if _, ok := cipherSuitesAdded[csID]; !ok {
cipherSuitesAdded[csID] = struct{}{}
cfg.CipherSuites = append(cfg.CipherSuites, csID)
@@ -182,7 +182,7 @@ func (p *ConnectionPolicy) buildStandardTLSConfig(ctx caddy.Context) error {
// add all the curve preferences in order, without duplicates
curvesAdded := make(map[tls.CurveID]struct{})
for _, curveName := range p.Curves {
- curveID := supportedCurves[curveName]
+ curveID := SupportedCurves[curveName]
if _, ok := curvesAdded[curveID]; !ok {
curvesAdded[curveID] = struct{}{}
cfg.CurvePreferences = append(cfg.CurvePreferences, curveID)
@@ -203,10 +203,10 @@ func (p *ConnectionPolicy) buildStandardTLSConfig(ctx caddy.Context) error {
// min and max protocol versions
if p.ProtocolMin != "" {
- cfg.MinVersion = supportedProtocols[p.ProtocolMin]
+ cfg.MinVersion = SupportedProtocols[p.ProtocolMin]
}
if p.ProtocolMax != "" {
- cfg.MaxVersion = supportedProtocols[p.ProtocolMax]
+ cfg.MaxVersion = SupportedProtocols[p.ProtocolMax]
}
if p.ProtocolMin > p.ProtocolMax {
return fmt.Errorf("protocol min (%x) cannot be greater than protocol max (%x)", p.ProtocolMin, p.ProtocolMax)
diff --git a/modules/caddytls/fileloader.go b/modules/caddytls/fileloader.go
index 5f277c8..b2cc132 100644
--- a/modules/caddytls/fileloader.go
+++ b/modules/caddytls/fileloader.go
@@ -23,14 +23,19 @@ import (
)
func init() {
- caddy.RegisterModule(caddy.Module{
- Name: "tls.certificates.load_files",
- New: func() interface{} { return fileLoader{} },
- })
+ caddy.RegisterModule(FileLoader{})
}
-// fileLoader loads certificates and their associated keys from disk.
-type fileLoader []CertKeyFilePair
+// FileLoader loads certificates and their associated keys from disk.
+type FileLoader []CertKeyFilePair
+
+// CaddyModule returns the Caddy module information.
+func (FileLoader) CaddyModule() caddy.ModuleInfo {
+ return caddy.ModuleInfo{
+ Name: "tls.certificates.load_files",
+ New: func() caddy.Module { return new(FileLoader) },
+ }
+}
// CertKeyFilePair pairs certificate and key file names along with their
// encoding format so that they can be loaded from disk.
@@ -42,7 +47,7 @@ type CertKeyFilePair struct {
}
// LoadCertificates returns the certificates to be loaded by fl.
-func (fl fileLoader) LoadCertificates() ([]Certificate, error) {
+func (fl FileLoader) LoadCertificates() ([]Certificate, error) {
var certs []Certificate
for _, pair := range fl {
certData, err := ioutil.ReadFile(pair.Certificate)
@@ -73,4 +78,4 @@ func (fl fileLoader) LoadCertificates() ([]Certificate, error) {
}
// Interface guard
-var _ CertificateLoader = (fileLoader)(nil)
+var _ CertificateLoader = (FileLoader)(nil)
diff --git a/modules/caddytls/folderloader.go b/modules/caddytls/folderloader.go
index 24a7fbb..da1dff0 100644
--- a/modules/caddytls/folderloader.go
+++ b/modules/caddytls/folderloader.go
@@ -28,22 +28,27 @@ import (
)
func init() {
- caddy.RegisterModule(caddy.Module{
- Name: "tls.certificates.load_folders",
- New: func() interface{} { return folderLoader{} },
- })
+ caddy.RegisterModule(FolderLoader{})
}
-// folderLoader loads certificates and their associated keys from disk
+// FolderLoader loads certificates and their associated keys from disk
// by recursively walking the specified directories, looking for PEM
// files which contain both a certificate and a key.
-type folderLoader []string
+type FolderLoader []string
+
+// CaddyModule returns the Caddy module information.
+func (FolderLoader) CaddyModule() caddy.ModuleInfo {
+ return caddy.ModuleInfo{
+ Name: "tls.certificates.load_folders",
+ New: func() caddy.Module { return new(FolderLoader) },
+ }
+}
// LoadCertificates loads all the certificates+keys in the directories
// listed in fl from all files ending with .pem. This method of loading
// certificates expects the certificate and key to be bundled into the
// same file.
-func (fl folderLoader) LoadCertificates() ([]Certificate, error) {
+func (fl FolderLoader) LoadCertificates() ([]Certificate, error) {
var certs []Certificate
for _, dir := range fl {
err := filepath.Walk(dir, func(fpath string, info os.FileInfo, err error) error {
@@ -135,4 +140,4 @@ func x509CertFromCertAndKeyPEMFile(fpath string) (tls.Certificate, error) {
return cert, nil
}
-var _ CertificateLoader = (folderLoader)(nil)
+var _ CertificateLoader = (FolderLoader)(nil)
diff --git a/modules/caddytls/matchers.go b/modules/caddytls/matchers.go
index ee146d4..47fb296 100644
--- a/modules/caddytls/matchers.go
+++ b/modules/caddytls/matchers.go
@@ -20,14 +20,19 @@ import (
"github.com/caddyserver/caddy/v2"
)
+func init() {
+ caddy.RegisterModule(MatchServerName{})
+}
+
// MatchServerName matches based on SNI.
type MatchServerName []string
-func init() {
- caddy.RegisterModule(caddy.Module{
+// CaddyModule returns the Caddy module information.
+func (MatchServerName) CaddyModule() caddy.ModuleInfo {
+ return caddy.ModuleInfo{
Name: "tls.handshake_match.sni",
- New: func() interface{} { return MatchServerName{} },
- })
+ New: func() caddy.Module { return new(MatchServerName) },
+ }
}
// Match matches hello based on SNI.
diff --git a/modules/caddytls/sessiontickets.go b/modules/caddytls/sessiontickets.go
index c47f823..2eb0773 100644
--- a/modules/caddytls/sessiontickets.go
+++ b/modules/caddytls/sessiontickets.go
@@ -29,7 +29,7 @@ import (
// SessionTicketService configures and manages TLS session tickets.
type SessionTicketService struct {
KeySource json.RawMessage `json:"key_source,omitempty"`
- RotationInterval caddy.Duration `json:"rotation_interval,omitempty"`
+ RotationInterval caddy.Duration `json:"rotation_interval,omitempty"`
MaxKeys int `json:"max_keys,omitempty"`
DisableRotation bool `json:"disable_rotation,omitempty"`
Disabled bool `json:"disabled,omitempty"`
diff --git a/modules/caddytls/standardstek/stek.go b/modules/caddytls/standardstek/stek.go
index 6a4b1c8..6d10c76 100644
--- a/modules/caddytls/standardstek/stek.go
+++ b/modules/caddytls/standardstek/stek.go
@@ -24,10 +24,7 @@ import (
)
func init() {
- caddy.RegisterModule(caddy.Module{
- Name: "tls.stek.standard",
- New: func() interface{} { return new(standardSTEKProvider) },
- })
+ caddy.RegisterModule(standardSTEKProvider{})
}
type standardSTEKProvider struct {
@@ -35,6 +32,14 @@ type standardSTEKProvider struct {
timer *time.Timer
}
+// CaddyModule returns the Caddy module information.
+func (standardSTEKProvider) CaddyModule() caddy.ModuleInfo {
+ return caddy.ModuleInfo{
+ Name: "tls.stek.standard",
+ New: func() caddy.Module { return new(standardSTEKProvider) },
+ }
+}
+
// Initialize sets the configuration for s and returns the starting keys.
func (s *standardSTEKProvider) Initialize(config *caddytls.SessionTicketService) ([][32]byte, error) {
// keep a reference to the config; we'll need it when rotating keys
diff --git a/modules/caddytls/tls.go b/modules/caddytls/tls.go
index e70fbd1..88b7790 100644
--- a/modules/caddytls/tls.go
+++ b/modules/caddytls/tls.go
@@ -30,10 +30,7 @@ import (
)
func init() {
- caddy.RegisterModule(caddy.Module{
- Name: "tls",
- New: func() interface{} { return new(TLS) },
- })
+ caddy.RegisterModule(TLS{})
// opt-in TLS 1.3 for Go1.12
// TODO: remove this line when Go1.13 is released.
@@ -45,14 +42,22 @@ func init() {
// TLS represents a process-wide TLS configuration.
type TLS struct {
Certificates map[string]json.RawMessage `json:"certificates,omitempty"`
- Automation AutomationConfig `json:"automation,omitempty"`
- SessionTickets SessionTicketService `json:"session_tickets,omitempty"`
+ Automation AutomationConfig `json:"automation"`
+ SessionTickets SessionTicketService `json:"session_tickets"`
certificateLoaders []CertificateLoader
certCache *certmagic.Cache
ctx caddy.Context
}
+// CaddyModule returns the Caddy module information.
+func (TLS) CaddyModule() caddy.ModuleInfo {
+ return caddy.ModuleInfo{
+ Name: "tls",
+ New: func() caddy.Module { return new(TLS) },
+ }
+}
+
// Provision sets up the configuration for the TLS app.
func (t *TLS) Provision(ctx caddy.Context) error {
t.ctx = ctx
@@ -73,7 +78,7 @@ func (t *TLS) Provision(ctx caddy.Context) error {
if err != nil {
return fmt.Errorf("loading TLS automation management module: %s", err)
}
- t.Automation.Policies[i].Management = val.(managerMaker)
+ t.Automation.Policies[i].Management = val.(ManagerMaker)
t.Automation.Policies[i].ManagementRaw = nil // allow GC to deallocate - TODO: Does this help?
}
@@ -105,16 +110,12 @@ func (t *TLS) Provision(ctx caddy.Context) error {
onDemandRateLimiter.SetLimit(0)
}
- return nil
-}
-
-// Start activates the TLS module.
-func (t *TLS) Start() error {
+ // load manual/static (unmanaged) certificates - we do this in
+ // provision so that other apps (such as http) can know which
+ // certificates have been manually loaded
magic := certmagic.New(t.certCache, certmagic.Config{
- Storage: t.ctx.Storage(),
+ Storage: ctx.Storage(),
})
-
- // load manual/static (unmanaged) certificates
for _, loader := range t.certificateLoaders {
certs, err := loader.LoadCertificates()
if err != nil {
@@ -128,6 +129,11 @@ func (t *TLS) Start() error {
}
}
+ return nil
+}
+
+// Start activates the TLS module.
+func (t *TLS) Start() error {
// load automated (managed) certificates
if automatedRawMsg, ok := t.Certificates[automateKey]; ok {
var names []string
@@ -204,6 +210,12 @@ func (t *TLS) getAutomationPolicyForName(name string) AutomationPolicy {
return AutomationPolicy{Management: mgmt}
}
+// CertificatesWithSAN returns the list of all certificates
+// in the cache the match the given SAN value.
+func (t *TLS) CertificatesWithSAN(san string) []certmagic.Certificate {
+ return t.certCache.CertificatesWithSAN(san)
+}
+
// CertificateLoader is a type that can load certificates.
// Certificates can optionally be associated with tags.
type CertificateLoader interface {
@@ -230,7 +242,7 @@ type AutomationPolicy struct {
Hosts []string `json:"hosts,omitempty"`
ManagementRaw json.RawMessage `json:"management,omitempty"`
- Management managerMaker `json:"-"`
+ Management ManagerMaker `json:"-"`
}
// makeCertMagicConfig converts ap into a CertMagic config. Passing onDemand
@@ -245,7 +257,7 @@ func (ap AutomationPolicy) makeCertMagicConfig(ctx caddy.Context) certmagic.Conf
}
return certmagic.Config{
- NewManager: ap.Management.newManager,
+ NewManager: ap.Management.NewManager,
}
}
@@ -283,9 +295,9 @@ type RateLimit struct {
Burst int `json:"burst,omitempty"`
}
-// managerMaker makes a certificate manager.
-type managerMaker interface {
- newManager(interactive bool) (certmagic.Manager, error)
+// ManagerMaker makes a certificate manager.
+type ManagerMaker interface {
+ NewManager(interactive bool) (certmagic.Manager, error)
}
// These perpetual values are used for on-demand TLS.
diff --git a/modules/caddytls/values.go b/modules/caddytls/values.go
index 0c62058..b10fe22 100644
--- a/modules/caddytls/values.go
+++ b/modules/caddytls/values.go
@@ -22,12 +22,16 @@ import (
"github.com/klauspost/cpuid"
)
-// supportedCipherSuites is the unordered map of cipher suite
+// SupportedCipherSuites is the unordered map of cipher suite
// string names to their definition in crypto/tls. All values
// should be IANA-reserved names. See
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
+// Two of the cipher suite constants in the standard lib do not use the
+// full IANA name, but we do; see:
+// https://github.com/golang/go/issues/32061 and
+// https://github.com/golang/go/issues/30325#issuecomment-512862374.
// TODO: might not be needed much longer: https://github.com/golang/go/issues/30325
-var supportedCipherSuites = map[string]uint16{
+var SupportedCipherSuites = map[string]uint16{
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
@@ -84,22 +88,24 @@ func getOptimalDefaultCipherSuites() []uint16 {
return defaultCipherSuitesWithoutAESNI
}
-// supportedCurves is the unordered map of supported curves.
+// SupportedCurves is the unordered map of supported curves.
// https://golang.org/pkg/crypto/tls/#CurveID
-var supportedCurves = map[string]tls.CurveID{
- "X25519": tls.X25519,
- "P256": tls.CurveP256,
- "P384": tls.CurveP384,
- "P521": tls.CurveP521,
+var SupportedCurves = map[string]tls.CurveID{
+ // TODO: Use IANA names, probably? see https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
+ // All named crypto/elliptic curves have secpXXXr1 IANA names.
+ "x25519": tls.X25519, // x25519, 29
+ "p256": tls.CurveP256, // secp256r1, 23
+ "p384": tls.CurveP384, // secp384r1, 24
+ "p521": tls.CurveP521, // secp521r1, 25
}
// supportedCertKeyTypes is all the key types that are supported
// for certificates that are obtained through ACME.
var supportedCertKeyTypes = map[string]certcrypto.KeyType{
- "RSA2048": certcrypto.RSA2048,
- "RSA4096": certcrypto.RSA4096,
- "P256": certcrypto.EC256,
- "P384": certcrypto.EC384,
+ "rsa_2048": certcrypto.RSA2048,
+ "rsa_4096": certcrypto.RSA4096,
+ "ec_p256": certcrypto.EC256,
+ "ec_p384": certcrypto.EC384,
}
// defaultCurves is the list of only the curves we want to use
@@ -115,9 +121,9 @@ var defaultCurves = []tls.CurveID{
tls.CurveP256,
}
-// supportedProtocols is a map of supported protocols.
-// HTTP/2 only supports TLS 1.2 and higher.
-var supportedProtocols = map[string]uint16{
+// SupportedProtocols is a map of supported protocols.
+// Note that HTTP/2 only supports TLS 1.2 and higher.
+var SupportedProtocols = map[string]uint16{
"tls1.0": tls.VersionTLS10,
"tls1.1": tls.VersionTLS11,
"tls1.2": tls.VersionTLS12,