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 (#318)
* 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
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user