Ctrl K
ComunidadGuías…

internal/server/certificate_storage_coverage_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// SPDX-License-Identifier: Apache-2.0

package server

import (
	"path/filepath"
	"strings"
	"testing"
	"time"
)

// Issue #153: when a Managed ACME definition lists both a wildcard and the
// apex, Caddy stores TWO separate certificates. findStorageCertificate used to
// return whichever merely expired latest, so the apex certificate — normally
// the newer one, because it was added later — was chosen and pushed to fleet
// targets. Every subdomain then failed TLS on the target.
//
// Selection must follow domain coverage, not expiry.
func TestFindStorageCertificatePrefersBroadestCoverage(t *testing.T) {
	dataDir := t.TempDir()
	root := filepath.Join(dataDir, "caddy", "certificates")
	roots := []string{dataDir}
	issuer := "acme-v02.api.letsencrypt.org-directory"
	domains := []string{"*.example.com", "example.com"}

	// The apex is obtained later, so it expires later. That must not win.
	writeStorageCertificate(t, root, issuer, "*.example.com", time.Now().Add(40*24*time.Hour))
	writeStorageCertificate(t, root, issuer, "example.com", time.Now().Add(80*24*time.Hour))

	found, err := findStorageCertificate(dataDir, domains, roots)
	if err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(found.CertPath, "wildcard_.example.com") {
		t.Fatalf("selected %s, want the wildcard certificate", found.CertPath)
	}

	// Order in the definition must not change the answer.
	found, err = findStorageCertificate(dataDir, []string{"example.com", "*.example.com"}, roots)
	if err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(found.CertPath, "wildcard_.example.com") {
		t.Fatalf("reversed domain order selected %s, want the wildcard", found.CertPath)
	}
}

// With equal coverage the newest certificate still wins, which is what the
// v2.42.0 export feature and renewal pickup rely on.
func TestFindStorageCertificateBreaksCoverageTiesByExpiry(t *testing.T) {
	dataDir := t.TempDir()
	root := filepath.Join(dataDir, "caddy", "certificates")
	roots := []string{dataDir}

	writeStorageCertificate(t, root, "acme.zerossl.com-v2-DV90", "*.example.com", time.Now().Add(20*24*time.Hour))
	writeStorageCertificate(t, root, "acme-v02.api.letsencrypt.org-directory", "*.example.com", time.Now().Add(80*24*time.Hour))

	found, err := findStorageCertificate(dataDir, []string{"*.example.com"}, roots)
	if err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(found.CertPath, "acme-v02.api.letsencrypt.org-directory") {
		t.Fatalf("selected %s, want the later-expiring issuer", found.CertPath)
	}
}

// A single stored certificate that covers every name is reported as complete,
// so callers can tell a full push from a partial one.
func TestFindStorageCertificateReportsFullCoverage(t *testing.T) {
	dataDir := t.TempDir()
	root := filepath.Join(dataDir, "caddy", "certificates")
	roots := []string{dataDir}

	writeStorageCertificate(t, root, "acme-v02.api.letsencrypt.org-directory", "*.example.com", time.Now().Add(60*24*time.Hour))

	found, err := findStorageCertificate(dataDir, []string{"*.example.com", "a.example.com"}, roots)
	if err != nil {
		t.Fatal(err)
	}
	// One wildcard certificate covers both the wildcard name and a subdomain.
	if len(found.Uncovered) != 0 {
		t.Fatalf("uncovered = %v, want none: a wildcard covers its subdomains", found.Uncovered)
	}
}

// When no single stored certificate covers every name, the gap is reported so
// the operator is told instead of being silently handed a partial certificate.
func TestFindStorageCertificateReportsUncoveredNames(t *testing.T) {
	dataDir := t.TempDir()
	root := filepath.Join(dataDir, "caddy", "certificates")
	roots := []string{dataDir}
	issuer := "acme-v02.api.letsencrypt.org-directory"

	writeStorageCertificate(t, root, issuer, "*.example.com", time.Now().Add(40*24*time.Hour))
	writeStorageCertificate(t, root, issuer, "example.com", time.Now().Add(80*24*time.Hour))

	found, err := findStorageCertificate(dataDir, []string{"*.example.com", "example.com"}, roots)
	if err != nil {
		t.Fatal(err)
	}
	// The wildcard wins on coverage, but it does not cover the apex: *.example.com
	// matches one label, never the bare domain.
	if len(found.Uncovered) != 1 || found.Uncovered[0] != "example.com" {
		t.Fatalf("uncovered = %v, want [example.com]", found.Uncovered)
	}
}