mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
* feat: Add opt-in support for proxy CA cert installation * fix: Code review fixes * fix: Code review fixes * fix: Code review fixes * fix: Code review fixes * fix: Code review fixes * docs: Add limitation for MacOS MDM script
74 lines
2.3 KiB
Go
74 lines
2.3 KiB
Go
package certmanager
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
const (
|
|
caCertFileName = "ca-cert.pem"
|
|
caKeyFileName = "ca-key.pem"
|
|
)
|
|
|
|
func CACertPath(dir string) string { return filepath.Join(dir, caCertFileName) }
|
|
func CAKeyPath(dir string) string { return filepath.Join(dir, caKeyFileName) }
|
|
|
|
// PersistentCACertManagerConfig returns the config for the on-disk,
|
|
// system-trusted CA. The root is long-lived (10 years) because rotating an
|
|
// installed, trusted root is expensive; leaf certs remain short (1 day).
|
|
func PersistentCACertManagerConfig() CertManagerConfig {
|
|
c := DefaultCertManagerConfig()
|
|
c.CAValidityDays = 3650
|
|
return c
|
|
}
|
|
|
|
// SaveCA writes the CA certificate (0644) and private key (0600) to dir.
|
|
// Only the pure PMG CA is persisted — not the system-bundle-merged PEM.
|
|
func SaveCA(dir string, ca *Certificate) error {
|
|
if ca == nil {
|
|
return fmt.Errorf("ca certificate is nil")
|
|
}
|
|
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return fmt.Errorf("failed to create config dir %s: %w", dir, err)
|
|
}
|
|
|
|
if err := os.WriteFile(CACertPath(dir), ca.Certificate, 0o644); err != nil {
|
|
return fmt.Errorf("failed to write CA certificate: %w", err)
|
|
}
|
|
|
|
// Remove any pre-existing key first so the new file is created fresh with
|
|
// 0600. os.WriteFile preserves an existing file's mode, which could otherwise
|
|
// leave a group/world-readable private key behind on a --force re-install.
|
|
if err := os.Remove(CAKeyPath(dir)); err != nil && !os.IsNotExist(err) {
|
|
return fmt.Errorf("failed to reset CA private key file: %w", err)
|
|
}
|
|
if err := os.WriteFile(CAKeyPath(dir), ca.PrivateKey, 0o600); err != nil {
|
|
return fmt.Errorf("failed to write CA private key: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// LoadCA reads and parses the persisted CA from dir. When a file is missing
|
|
// the returned error wraps os.ErrNotExist so callers can use errors.Is.
|
|
func LoadCA(dir string) (*Certificate, error) {
|
|
certPEM, err := os.ReadFile(CACertPath(dir))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read CA certificate: %w", err)
|
|
}
|
|
|
|
keyPEM, err := os.ReadFile(CAKeyPath(dir))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read CA private key: %w", err)
|
|
}
|
|
|
|
parsed, err := parseCertificate(&Certificate{Certificate: certPEM, PrivateKey: keyPEM})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse persisted CA: %w", err)
|
|
}
|
|
|
|
return parsed, nil
|
|
}
|