From b81ae38686fb9fb133a0308294b3dd898b769dac Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Thu, 6 Feb 2020 12:55:26 -0700 Subject: caddyfile: tls: Tag manual certificates (#2588) This ensure that if there are multiple certs that match a particular ServerName or other parameter, then specifically the one the user provided in the Caddyfile will be used. --- caddyconfig/httpcaddyfile/builtins.go | 14 +++++++++++++- modules/caddytls/certselection.go | 16 ++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go index 3fc78a1..7c56b04 100644 --- a/caddyconfig/httpcaddyfile/builtins.go +++ b/caddyconfig/httpcaddyfile/builtins.go @@ -127,11 +127,21 @@ func parseTLS(h Helper) ([]ConfigValue, error) { } mgr.Email = firstLine[0] case 2: + tag := fmt.Sprintf("cert%d", tagCounter) fileLoader = append(fileLoader, caddytls.CertKeyFilePair{ Certificate: firstLine[0], Key: firstLine[1], - // TODO: add tags, to ensure this certificate is always used for this server name + Tags: []string{tag}, }) + // tag this certificate so if multiple certs match, specifically + // this one that the user has provided will be used, see #2588: + // https://github.com/caddyserver/caddy/issues/2588 + tagCounter++ + certSelector := caddytls.CustomCertSelectionPolicy{Tag: tag} + if cp == nil { + cp = new(caddytls.ConnectionPolicy) + } + cp.CertSelection = caddyconfig.JSONModuleObject(certSelector, "policy", "custom", h.warnings) default: return nil, h.ArgErr() } @@ -382,3 +392,5 @@ func parseHandle(h Helper) (caddyhttp.MiddlewareHandler, error) { return nil, nil } + +var tagCounter = 0 diff --git a/modules/caddytls/certselection.go b/modules/caddytls/certselection.go index eb01605..10a3ee5 100644 --- a/modules/caddytls/certselection.go +++ b/modules/caddytls/certselection.go @@ -11,14 +11,14 @@ import ( ) func init() { - caddy.RegisterModule(Policy{}) + caddy.RegisterModule(CustomCertSelectionPolicy{}) } -// Policy represents a policy for selecting the certificate used to -// complete a handshake when there may be multiple options. All fields +// CertSelectionPolicy represents a policy for selecting the certificate used +// to complete a handshake when there may be multiple options. All fields // specified must match the candidate certificate for it to be chosen. // This was needed to solve https://github.com/caddyserver/caddy/issues/2588. -type Policy struct { +type CustomCertSelectionPolicy struct { SerialNumber *big.Int `json:"serial_number,omitempty"` SubjectOrganization string `json:"subject_organization,omitempty"` PublicKeyAlgorithm PublicKeyAlgorithm `json:"public_key_algorithm,omitempty"` @@ -26,15 +26,15 @@ type Policy struct { } // CaddyModule returns the Caddy module information. -func (Policy) CaddyModule() caddy.ModuleInfo { +func (CustomCertSelectionPolicy) CaddyModule() caddy.ModuleInfo { return caddy.ModuleInfo{ ID: "tls.certificate_selection.custom", - New: func() caddy.Module { return new(Policy) }, + New: func() caddy.Module { return new(CustomCertSelectionPolicy) }, } } // SelectCertificate implements certmagic.CertificateSelector. -func (p Policy) SelectCertificate(_ *tls.ClientHelloInfo, choices []certmagic.Certificate) (certmagic.Certificate, error) { +func (p CustomCertSelectionPolicy) SelectCertificate(_ *tls.ClientHelloInfo, choices []certmagic.Certificate) (certmagic.Certificate, error) { for _, cert := range choices { if p.SerialNumber != nil && cert.SerialNumber.Cmp(p.SerialNumber) != 0 { continue @@ -68,4 +68,4 @@ func (p Policy) SelectCertificate(_ *tls.ClientHelloInfo, choices []certmagic.Ce } // Interface guard -var _ certmagic.CertificateSelector = (*Policy)(nil) +var _ certmagic.CertificateSelector = (*CustomCertSelectionPolicy)(nil) -- cgit v1.2.3