package certmanager import ( "crypto" "crypto/tls" "crypto/x509" "fmt" "time" ) // Certificate represents a TLS certificate with its private key // Both certificate and private key are stored in PEM-encoded format type Certificate struct { // PEM encoded certificate Certificate []byte // PEM encoded private key PrivateKey []byte // Parsed X.509 certificate X509Cert *x509.Certificate // Parsed private key PrivKey crypto.PrivateKey } // CertificateCache defines the interface for certificate caching type CertificateCache interface { // Get retrieves a cached certificate for the given hostname Get(hostname string) (*Certificate, bool) // Set stores a certificate for the given hostname Set(hostname string, cert *Certificate) // Clear removes all cached certificates Clear() // Size returns the number of cached certificates Size() int } // CertificateManager handles TLS certificate lifecycle management type CertificateManager interface { // GetCA returns the Certificate Authority certificate and key GetCA() (*Certificate, error) // GenerateCertForHost creates a certificate for the given hostname // Uses caching to avoid regeneration of certificates // The certificate is signed by the CA and includes the hostname in the SAN GenerateCertForHost(hostname string) (*Certificate, error) // GetTLSConfig returns a tls.Config for the given hostname // This is a convenience method that generates/retrieves the certificate // and creates a tls.Config GetTLSConfig(hostname string) (*tls.Config, error) } // CertManagerConfig holds configuration for certificate generation type CertManagerConfig struct { // CAValidityDays specifies how many days the CA certificate is valid CAValidityDays int // HostCertValidityDays specifies how many days host certificates are valid HostCertValidityDays int // KeySize specifies the RSA key size in bits KeySize int } // DefaultCertManagerConfig returns a configuration with reasonable defaults func DefaultCertManagerConfig() CertManagerConfig { return CertManagerConfig{ CAValidityDays: 365, HostCertValidityDays: 1, KeySize: 2048, } } // SetDefaults sets reasonable defaults for zero values in the configuration func (c *CertManagerConfig) SetDefaults() { if c.CAValidityDays <= 0 { c.CAValidityDays = 365 } if c.HostCertValidityDays <= 0 { c.HostCertValidityDays = 1 } // Default to 2048 bits if key size is not set if c.KeySize == 0 { c.KeySize = 2048 } } // Validate checks if the configuration is valid after defaults have been set func (c *CertManagerConfig) Validate() error { if c.CAValidityDays <= 0 { return fmt.Errorf("CA validity days must be greater than 0: %d", c.CAValidityDays) } if c.HostCertValidityDays <= 0 { return fmt.Errorf("host certificate validity days must be greater than 0: %d", c.HostCertValidityDays) } if c.KeySize < 2048 { return fmt.Errorf("key size must be at least 2048 bits: %d", c.KeySize) } return nil } // IsExpired checks if a certificate is expired or will expire within the given threshold func (c *Certificate) IsExpired(threshold time.Duration) bool { if c.X509Cert == nil { return true } expiryTime := c.X509Cert.NotAfter return time.Until(expiryTime) < threshold }