More renames.
This commit is contained in:
94
ca.go
94
ca.go
@@ -26,7 +26,7 @@ type Paths struct {
|
||||
PrivateKeys string `hcl:"private_keys"`
|
||||
}
|
||||
|
||||
type _CAConfig struct {
|
||||
type CAConfig struct {
|
||||
Label string `hcl:",label"`
|
||||
Name string `hcl:"name"`
|
||||
Country string `hcl:"country"`
|
||||
@@ -41,12 +41,12 @@ type _CAConfig struct {
|
||||
Paths Paths `hcl:"paths,block"`
|
||||
}
|
||||
|
||||
func (c *_CAConfig) GetStateFileName() string {
|
||||
func (c *CAConfig) GetStateFileName() string {
|
||||
return c.Label + "_state.json"
|
||||
}
|
||||
|
||||
type Configuration struct {
|
||||
Current _CAConfig `hcl:"ca,block"`
|
||||
CA CAConfig `hcl:"ca,block"`
|
||||
}
|
||||
|
||||
type CertificateDefinition struct {
|
||||
@@ -142,19 +142,19 @@ func (c *Certificates) LoadFromFile(path string) error {
|
||||
}
|
||||
|
||||
// Global CA configuration and state variables
|
||||
var CAConfigPath string
|
||||
var CAState *_CAState
|
||||
var CAConfig *_CAConfig
|
||||
var CAKey *rsa.PrivateKey
|
||||
var CACert *x509.Certificate
|
||||
var caConfigPath string
|
||||
var caState *CAState
|
||||
var caConfig *CAConfig
|
||||
var caKey *rsa.PrivateKey
|
||||
var caCert *x509.Certificate
|
||||
|
||||
// LoadCAConfig parses and validates the CA config from the given path and stores it in the CAConfig global variable
|
||||
func LoadCAConfig() error {
|
||||
if verbose {
|
||||
fmt.Printf("Loading CA config from \"%s\"", CAConfigPath)
|
||||
fmt.Printf("Loading CA config from \"%s\"", caConfigPath)
|
||||
}
|
||||
parser := hclparse.NewParser()
|
||||
file, diags := parser.ParseHCLFile(CAConfigPath)
|
||||
file, diags := parser.ParseHCLFile(caConfigPath)
|
||||
if diags.HasErrors() {
|
||||
return fmt.Errorf("failed to parse HCL: %s", diags.Error())
|
||||
}
|
||||
@@ -163,16 +163,16 @@ func LoadCAConfig() error {
|
||||
if diags.HasErrors() {
|
||||
return fmt.Errorf("failed to decode HCL: %s", diags.Error())
|
||||
}
|
||||
if (_CAConfig{}) == config.Current {
|
||||
if (CAConfig{}) == config.CA {
|
||||
return fmt.Errorf("no 'ca' block found in config file")
|
||||
}
|
||||
if config.Current.Label == "" {
|
||||
if config.CA.Label == "" {
|
||||
return fmt.Errorf("the 'ca' block must have a label (e.g., ca \"mylabel\" {...})")
|
||||
}
|
||||
if err := config.Current.Validate(); err != nil {
|
||||
if err := config.CA.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
CAConfig = &config.Current
|
||||
caConfig = &config.CA
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -186,8 +186,8 @@ func LoadCA() error {
|
||||
}
|
||||
|
||||
// Load CA key and certificate
|
||||
caCertPath := filepath.Join(CAConfig.Paths.Certificates, "ca_cert.pem")
|
||||
caKeyPath := filepath.Join(CAConfig.Paths.PrivateKeys, "ca_key.pem")
|
||||
caCertPath := filepath.Join(caConfig.Paths.Certificates, "ca_cert.pem")
|
||||
caKeyPath := filepath.Join(caConfig.Paths.PrivateKeys, "ca_key.pem")
|
||||
|
||||
caCertPEM, err := os.ReadFile(caCertPath)
|
||||
if err != nil {
|
||||
@@ -202,7 +202,7 @@ func LoadCA() error {
|
||||
if caCertBlock == nil {
|
||||
return fmt.Errorf("failed to parse CA certificate PEM")
|
||||
}
|
||||
CACert, err = x509.ParseCertificate(caCertBlock.Bytes)
|
||||
caCert, err = x509.ParseCertificate(caCertBlock.Bytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse CA certificate: %v", err)
|
||||
}
|
||||
@@ -210,7 +210,7 @@ func LoadCA() error {
|
||||
if caKeyBlock == nil {
|
||||
return fmt.Errorf("failed to parse CA key PEM")
|
||||
}
|
||||
CAKey, err = x509.ParsePKCS1PrivateKey(caKeyBlock.Bytes)
|
||||
caKey, err = x509.ParsePKCS1PrivateKey(caKeyBlock.Bytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse CA private key: %v", err)
|
||||
}
|
||||
@@ -299,7 +299,7 @@ func (p *Paths) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *_CAConfig) Validate() error {
|
||||
func (c *CAConfig) Validate() error {
|
||||
if c.Name == "" {
|
||||
return fmt.Errorf("CA 'name' is required")
|
||||
}
|
||||
@@ -333,28 +333,28 @@ func InitCA() error {
|
||||
}
|
||||
|
||||
// Create certificates directory with 0755, private keys with 0700
|
||||
if CAConfig.Paths.Certificates != "" {
|
||||
if err := os.MkdirAll(CAConfig.Paths.Certificates, 0755); err != nil {
|
||||
fmt.Printf("Error creating certificates directory '%s': %v\n", CAConfig.Paths.Certificates, err)
|
||||
if caConfig.Paths.Certificates != "" {
|
||||
if err := os.MkdirAll(caConfig.Paths.Certificates, 0755); err != nil {
|
||||
fmt.Printf("Error creating certificates directory '%s': %v\n", caConfig.Paths.Certificates, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
if CAConfig.Paths.PrivateKeys != "" {
|
||||
if err := os.MkdirAll(CAConfig.Paths.PrivateKeys, 0700); err != nil {
|
||||
fmt.Printf("Error creating private keys directory '%s': %v\n", CAConfig.Paths.PrivateKeys, err)
|
||||
if caConfig.Paths.PrivateKeys != "" {
|
||||
if err := os.MkdirAll(caConfig.Paths.PrivateKeys, 0700); err != nil {
|
||||
fmt.Printf("Error creating private keys directory '%s': %v\n", caConfig.Paths.PrivateKeys, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize CAState empty state with serial starting from 1
|
||||
CAState = &_CAState{
|
||||
caState = &CAState{
|
||||
Serial: 1, // Start serial from 1
|
||||
CreatedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
Certificates: []CertificateRecord{},
|
||||
}
|
||||
|
||||
keySize := CAConfig.KeySize
|
||||
keySize := caConfig.KeySize
|
||||
if keySize == 0 {
|
||||
keySize = 4096
|
||||
}
|
||||
@@ -368,28 +368,28 @@ func InitCA() error {
|
||||
return fmt.Errorf("failed to generate serial number: %v", err)
|
||||
}
|
||||
|
||||
if CAConfig.Validity == "" {
|
||||
CAConfig.Validity = "5y" // Use default validity of 5 years
|
||||
if caConfig.Validity == "" {
|
||||
caConfig.Validity = "5y" // Use default validity of 5 years
|
||||
}
|
||||
|
||||
validity, err := parseValidity(CAConfig.Validity)
|
||||
validity, err := parseValidity(caConfig.Validity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
// Store CA certificate creation time
|
||||
CAState.CreatedAt = now.UTC().Format(time.RFC3339)
|
||||
caState.CreatedAt = now.UTC().Format(time.RFC3339)
|
||||
|
||||
tmpl := x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
Country: []string{CAConfig.Country},
|
||||
Organization: []string{CAConfig.Organization},
|
||||
OrganizationalUnit: optionalSlice(CAConfig.OrganizationalUnit),
|
||||
Locality: optionalSlice(CAConfig.Locality),
|
||||
Province: optionalSlice(CAConfig.Province),
|
||||
CommonName: CAConfig.Name,
|
||||
Country: []string{caConfig.Country},
|
||||
Organization: []string{caConfig.Organization},
|
||||
OrganizationalUnit: optionalSlice(caConfig.OrganizationalUnit),
|
||||
Locality: optionalSlice(caConfig.Locality),
|
||||
Province: optionalSlice(caConfig.Province),
|
||||
CommonName: caConfig.Name,
|
||||
},
|
||||
NotBefore: now,
|
||||
NotAfter: now.Add(validity),
|
||||
@@ -398,10 +398,10 @@ func InitCA() error {
|
||||
IsCA: true,
|
||||
}
|
||||
// Add email if present
|
||||
if CAConfig.Email != "" {
|
||||
if caConfig.Email != "" {
|
||||
tmpl.Subject.ExtraNames = append(tmpl.Subject.ExtraNames, pkix.AttributeTypeAndValue{
|
||||
Type: []int{1, 2, 840, 113549, 1, 9, 1}, // emailAddress OID
|
||||
Value: CAConfig.Email,
|
||||
Value: caConfig.Email,
|
||||
})
|
||||
}
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv)
|
||||
@@ -411,17 +411,17 @@ func InitCA() error {
|
||||
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
|
||||
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||
|
||||
if err := SavePEM(filepath.Join(CAConfig.Paths.Certificates, "ca_cert.pem"), certPEM, false); err != nil {
|
||||
if err := SavePEM(filepath.Join(caConfig.Paths.Certificates, "ca_cert.pem"), certPEM, false); err != nil {
|
||||
fmt.Println("Error saving CA certificate:", err)
|
||||
return err
|
||||
}
|
||||
if err := SavePEM(filepath.Join(CAConfig.Paths.PrivateKeys, "ca_key.pem"), keyPEM, true); err != nil {
|
||||
if err := SavePEM(filepath.Join(caConfig.Paths.PrivateKeys, "ca_key.pem"), keyPEM, true); err != nil {
|
||||
fmt.Println("Error saving CA key:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// set last updated time in the CAState
|
||||
CAState.UpdatedAt = time.Now().UTC().Format(time.RFC3339)
|
||||
caState.UpdatedAt = time.Now().UTC().Format(time.RFC3339)
|
||||
// Save the state
|
||||
|
||||
err = SaveCAState()
|
||||
@@ -525,7 +525,7 @@ func issueSingleCertificate(def CertificateDefinition) error {
|
||||
return fmt.Errorf("unknown certificate type. Use one of: client, server, server-only, code-signing, email")
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, &certTmpl, CACert, &priv.PublicKey, CAKey)
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, &priv.PublicKey, caKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create certificate: %v", err)
|
||||
}
|
||||
@@ -536,8 +536,8 @@ func issueSingleCertificate(def CertificateDefinition) error {
|
||||
if basename == "" {
|
||||
basename = def.Subject
|
||||
}
|
||||
certFile := filepath.Join(CAConfig.Paths.Certificates, basename+".crt.pem")
|
||||
keyFile := filepath.Join(CAConfig.Paths.PrivateKeys, basename+".key.pem")
|
||||
certFile := filepath.Join(caConfig.Paths.Certificates, basename+".crt.pem")
|
||||
keyFile := filepath.Join(caConfig.Paths.PrivateKeys, basename+".key.pem")
|
||||
if err := SavePEM(certFile, certPEM, false); err != nil {
|
||||
return fmt.Errorf("error saving certificate: %v", err)
|
||||
}
|
||||
@@ -560,8 +560,8 @@ Certificate:
|
||||
def.SAN,
|
||||
)
|
||||
}
|
||||
CAState.UpdateCAStateAfterIssue(
|
||||
CAConfig.SerialType,
|
||||
caState.UpdateCAStateAfterIssue(
|
||||
caConfig.SerialType,
|
||||
basename,
|
||||
serialNumber,
|
||||
validityDur,
|
||||
|
Reference in New Issue
Block a user