mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
121 lines
3.2 KiB
Go
121 lines
3.2 KiB
Go
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
|
|
}
|