From 80eb3e81e592ff7c9261e4e1cade5cc1ee0497ec Mon Sep 17 00:00:00 2001 From: Herman Slatman Date: Wed, 5 Nov 2025 00:58:00 +0100 Subject: [PATCH] Move intermediate lifetime configuration check In #7272 a check was changed to ensure that generated intermediate certificates would always use a lifetime that falls within the lifetime of the root. However, when a root and intermediate(s) are supplied, the configuration value was being used instead of the actual lifetimes of the certificates. The check was moved to only be performed when an intermediate is generated; not when loaded from disk. --- modules/caddypki/ca.go | 10 ++++++---- modules/caddytls/internalissuer_test.go | 8 ++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/modules/caddypki/ca.go b/modules/caddypki/ca.go index 48366f977..c778e0364 100644 --- a/modules/caddypki/ca.go +++ b/modules/caddypki/ca.go @@ -145,13 +145,15 @@ func (ca *CA) Provision(ctx caddy.Context, id string, log *zap.Logger) error { if err != nil { return err } - actualRootLifetime := time.Until(rootCert.NotAfter) - if time.Duration(ca.IntermediateLifetime) >= actualRootLifetime { - return fmt.Errorf("intermediate certificate lifetime must be less than actual root certificate lifetime (%s)", actualRootLifetime) - } + if ca.Intermediate != nil { interCertChain, interKey, err = ca.Intermediate.Load() } else { + actualRootLifetime := time.Until(rootCert.NotAfter) + if time.Duration(ca.IntermediateLifetime) >= actualRootLifetime { + return fmt.Errorf("intermediate certificate lifetime must be less than actual root certificate lifetime (%s)", actualRootLifetime) + } + interCertChain, interKey, err = ca.loadOrGenIntermediate(rootCert, rootKey) } if err != nil { diff --git a/modules/caddytls/internalissuer_test.go b/modules/caddytls/internalissuer_test.go index 5885c282d..d39d8373b 100644 --- a/modules/caddytls/internalissuer_test.go +++ b/modules/caddytls/internalissuer_test.go @@ -43,6 +43,8 @@ func TestInternalIssuer_Issue(t *testing.T) { Subject: pkix.Name{CommonName: "test-root"}, IsCA: true, MaxPathLen: 3, + NotAfter: time.Now().Add(7 * 24 * time.Hour), + NotBefore: time.Now().Add(-7 * 24 * time.Hour), } rootBytes, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, rootSigner.Public(), rootSigner) if err != nil { @@ -63,7 +65,8 @@ func TestInternalIssuer_Issue(t *testing.T) { Subject: pkix.Name{CommonName: "test-first-intermediate"}, IsCA: true, MaxPathLen: 2, - NotAfter: time.Now().Add(time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + NotBefore: time.Now().Add(-24 * time.Hour), }, root, firstIntermediateSigner.Public(), rootSigner) if err != nil { t.Fatalf("Creating intermediate certificate failed: %v", err) @@ -83,7 +86,8 @@ func TestInternalIssuer_Issue(t *testing.T) { Subject: pkix.Name{CommonName: "test-second-intermediate"}, IsCA: true, MaxPathLen: 2, - NotAfter: time.Now().Add(time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + NotBefore: time.Now().Add(-24 * time.Hour), }, firstIntermediate, secondIntermediateSigner.Public(), firstIntermediateSigner) if err != nil { t.Fatalf("Creating second intermediate certificate failed: %v", err)