Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions caddyconfig/httpcaddyfile/pkiapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/modules/caddypki"
"github.com/caddyserver/caddy/v2/modules/caddytls"
)

func init() {
Expand Down Expand Up @@ -260,5 +261,33 @@ func (st ServerType) buildPKIApp(
pkiApp.CAs[ca.ID] = ca
}

// an explicit site-level internal issuer creates its own CA
// regardless of `auto_https`, so make sure `skip_install_trust`
// is honored for it too; otherwise the CA is created later at
// runtime with trust installation left on
if skipInstallTrust {
for _, p := range pairings {
for _, sblock := range p.serverBlocks {
for _, issuerCfgValue := range sblock.pile["tls.cert_issuer"] {
internalIssuer, ok := issuerCfgValue.Value.(*caddytls.InternalIssuer)
if !ok {
continue
}
caID := internalIssuer.CA
if caID == "" {
caID = caddypki.DefaultCAID
}
if _, ok := pkiApp.CAs[caID]; ok {
continue
}
ca := new(caddypki.CA)
ca.ID = caID
ca.InstallTrust = &falseBool
pkiApp.CAs[ca.ID] = ca
}
}
}
}

return pkiApp, warnings, nil
}
90 changes: 90 additions & 0 deletions caddyconfig/httpcaddyfile/pkiapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,96 @@ func TestParsePKIApp_maintenanceIntervalAndRenewalWindowRatio(t *testing.T) {
}
}

// adaptedPKIConfig runs the given Caddyfile through the adapter and
// returns just the parts of the resulting JSON this test cares about:
// which CAs got a certificate_authorities entry, and whether install_trust
// was set to false for each.
func adaptedPKIConfig(t *testing.T, input string) map[string]struct {
InstallTrust *bool `json:"install_trust,omitempty"`
} {
t.Helper()

adapter := caddyfile.Adapter{ServerType: ServerType{}}
out, _, err := adapter.Adapt([]byte(input), nil)
if err != nil {
t.Fatalf("Adapt failed: %v", err)
}

var cfg struct {
Apps struct {
PKI struct {
CertificateAuthorities map[string]struct {
InstallTrust *bool `json:"install_trust,omitempty"`
} `json:"certificate_authorities,omitempty"`
} `json:"pki,omitempty"`
} `json:"apps"`
}
if err := json.Unmarshal(out, &cfg); err != nil {
t.Fatalf("unmarshal config: %v", err)
}
return cfg.Apps.PKI.CertificateAuthorities
}

func TestParsePKIApp_skipInstallTrustHonoredForInternalTLSDefaultCA(t *testing.T) {
input := `{
auto_https off
skip_install_trust
}
internal.example.com {
tls internal
}
`
cas := adaptedPKIConfig(t, input)

ca, ok := cas["local"]
if !ok {
t.Fatal("expected certificate_authorities.local to exist")
}
if ca.InstallTrust == nil || *ca.InstallTrust != false {
t.Errorf("install_trust = %v, want false", ca.InstallTrust)
}
}

func TestParsePKIApp_skipInstallTrustHonoredForInternalTLSCustomCA(t *testing.T) {
input := `{
auto_https off
skip_install_trust
}
internal.example.com {
tls {
issuer internal {
ca mycustomca
}
}
}
`
cas := adaptedPKIConfig(t, input)

ca, ok := cas["mycustomca"]
if !ok {
t.Fatal("expected certificate_authorities.mycustomca to exist")
}
if ca.InstallTrust == nil || *ca.InstallTrust != false {
t.Errorf("install_trust = %v, want false", ca.InstallTrust)
}
}

func TestParsePKIApp_noPKIAppWhenNoInternalIssuerConfigured(t *testing.T) {
input := `{
auto_https off
skip_install_trust
}
localhost:8080 {
respond "no tls internal used anywhere"
}
`
cas := adaptedPKIConfig(t, input)

if len(cas) != 0 {
t.Errorf("expected no certificate_authorities, got %v", cas)
}
}

func TestParsePKIApp_renewalWindowRatioInvalid(t *testing.T) {
input := `{
pki {
Expand Down