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"`
|
PrivateKeys string `hcl:"private_keys"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type _CAConfig struct {
|
type CAConfig struct {
|
||||||
Label string `hcl:",label"`
|
Label string `hcl:",label"`
|
||||||
Name string `hcl:"name"`
|
Name string `hcl:"name"`
|
||||||
Country string `hcl:"country"`
|
Country string `hcl:"country"`
|
||||||
@@ -41,12 +41,12 @@ type _CAConfig struct {
|
|||||||
Paths Paths `hcl:"paths,block"`
|
Paths Paths `hcl:"paths,block"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *_CAConfig) GetStateFileName() string {
|
func (c *CAConfig) GetStateFileName() string {
|
||||||
return c.Label + "_state.json"
|
return c.Label + "_state.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
type Configuration struct {
|
type Configuration struct {
|
||||||
Current _CAConfig `hcl:"ca,block"`
|
CA CAConfig `hcl:"ca,block"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CertificateDefinition struct {
|
type CertificateDefinition struct {
|
||||||
@@ -142,19 +142,19 @@ func (c *Certificates) LoadFromFile(path string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Global CA configuration and state variables
|
// Global CA configuration and state variables
|
||||||
var CAConfigPath string
|
var caConfigPath string
|
||||||
var CAState *_CAState
|
var caState *CAState
|
||||||
var CAConfig *_CAConfig
|
var caConfig *CAConfig
|
||||||
var CAKey *rsa.PrivateKey
|
var caKey *rsa.PrivateKey
|
||||||
var CACert *x509.Certificate
|
var caCert *x509.Certificate
|
||||||
|
|
||||||
// LoadCAConfig parses and validates the CA config from the given path and stores it in the CAConfig global variable
|
// LoadCAConfig parses and validates the CA config from the given path and stores it in the CAConfig global variable
|
||||||
func LoadCAConfig() error {
|
func LoadCAConfig() error {
|
||||||
if verbose {
|
if verbose {
|
||||||
fmt.Printf("Loading CA config from \"%s\"", CAConfigPath)
|
fmt.Printf("Loading CA config from \"%s\"", caConfigPath)
|
||||||
}
|
}
|
||||||
parser := hclparse.NewParser()
|
parser := hclparse.NewParser()
|
||||||
file, diags := parser.ParseHCLFile(CAConfigPath)
|
file, diags := parser.ParseHCLFile(caConfigPath)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return fmt.Errorf("failed to parse HCL: %s", diags.Error())
|
return fmt.Errorf("failed to parse HCL: %s", diags.Error())
|
||||||
}
|
}
|
||||||
@@ -163,16 +163,16 @@ func LoadCAConfig() error {
|
|||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return fmt.Errorf("failed to decode HCL: %s", diags.Error())
|
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")
|
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\" {...})")
|
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
|
return err
|
||||||
}
|
}
|
||||||
CAConfig = &config.Current
|
caConfig = &config.CA
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,8 +186,8 @@ func LoadCA() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load CA key and certificate
|
// Load CA key and certificate
|
||||||
caCertPath := filepath.Join(CAConfig.Paths.Certificates, "ca_cert.pem")
|
caCertPath := filepath.Join(caConfig.Paths.Certificates, "ca_cert.pem")
|
||||||
caKeyPath := filepath.Join(CAConfig.Paths.PrivateKeys, "ca_key.pem")
|
caKeyPath := filepath.Join(caConfig.Paths.PrivateKeys, "ca_key.pem")
|
||||||
|
|
||||||
caCertPEM, err := os.ReadFile(caCertPath)
|
caCertPEM, err := os.ReadFile(caCertPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -202,7 +202,7 @@ func LoadCA() error {
|
|||||||
if caCertBlock == nil {
|
if caCertBlock == nil {
|
||||||
return fmt.Errorf("failed to parse CA certificate PEM")
|
return fmt.Errorf("failed to parse CA certificate PEM")
|
||||||
}
|
}
|
||||||
CACert, err = x509.ParseCertificate(caCertBlock.Bytes)
|
caCert, err = x509.ParseCertificate(caCertBlock.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse CA certificate: %v", err)
|
return fmt.Errorf("failed to parse CA certificate: %v", err)
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ func LoadCA() error {
|
|||||||
if caKeyBlock == nil {
|
if caKeyBlock == nil {
|
||||||
return fmt.Errorf("failed to parse CA key PEM")
|
return fmt.Errorf("failed to parse CA key PEM")
|
||||||
}
|
}
|
||||||
CAKey, err = x509.ParsePKCS1PrivateKey(caKeyBlock.Bytes)
|
caKey, err = x509.ParsePKCS1PrivateKey(caKeyBlock.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse CA private key: %v", err)
|
return fmt.Errorf("failed to parse CA private key: %v", err)
|
||||||
}
|
}
|
||||||
@@ -299,7 +299,7 @@ func (p *Paths) Validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *_CAConfig) Validate() error {
|
func (c *CAConfig) Validate() error {
|
||||||
if c.Name == "" {
|
if c.Name == "" {
|
||||||
return fmt.Errorf("CA 'name' is required")
|
return fmt.Errorf("CA 'name' is required")
|
||||||
}
|
}
|
||||||
@@ -333,28 +333,28 @@ func InitCA() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create certificates directory with 0755, private keys with 0700
|
// Create certificates directory with 0755, private keys with 0700
|
||||||
if CAConfig.Paths.Certificates != "" {
|
if caConfig.Paths.Certificates != "" {
|
||||||
if err := os.MkdirAll(CAConfig.Paths.Certificates, 0755); err != nil {
|
if err := os.MkdirAll(caConfig.Paths.Certificates, 0755); err != nil {
|
||||||
fmt.Printf("Error creating certificates directory '%s': %v\n", CAConfig.Paths.Certificates, err)
|
fmt.Printf("Error creating certificates directory '%s': %v\n", caConfig.Paths.Certificates, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if CAConfig.Paths.PrivateKeys != "" {
|
if caConfig.Paths.PrivateKeys != "" {
|
||||||
if err := os.MkdirAll(CAConfig.Paths.PrivateKeys, 0700); err != nil {
|
if err := os.MkdirAll(caConfig.Paths.PrivateKeys, 0700); err != nil {
|
||||||
fmt.Printf("Error creating private keys directory '%s': %v\n", CAConfig.Paths.PrivateKeys, err)
|
fmt.Printf("Error creating private keys directory '%s': %v\n", caConfig.Paths.PrivateKeys, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize CAState empty state with serial starting from 1
|
// Initialize CAState empty state with serial starting from 1
|
||||||
CAState = &_CAState{
|
caState = &CAState{
|
||||||
Serial: 1, // Start serial from 1
|
Serial: 1, // Start serial from 1
|
||||||
CreatedAt: time.Now().UTC().Format(time.RFC3339),
|
CreatedAt: time.Now().UTC().Format(time.RFC3339),
|
||||||
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
||||||
Certificates: []CertificateRecord{},
|
Certificates: []CertificateRecord{},
|
||||||
}
|
}
|
||||||
|
|
||||||
keySize := CAConfig.KeySize
|
keySize := caConfig.KeySize
|
||||||
if keySize == 0 {
|
if keySize == 0 {
|
||||||
keySize = 4096
|
keySize = 4096
|
||||||
}
|
}
|
||||||
@@ -368,28 +368,28 @@ func InitCA() error {
|
|||||||
return fmt.Errorf("failed to generate serial number: %v", err)
|
return fmt.Errorf("failed to generate serial number: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if CAConfig.Validity == "" {
|
if caConfig.Validity == "" {
|
||||||
CAConfig.Validity = "5y" // Use default validity of 5 years
|
caConfig.Validity = "5y" // Use default validity of 5 years
|
||||||
}
|
}
|
||||||
|
|
||||||
validity, err := parseValidity(CAConfig.Validity)
|
validity, err := parseValidity(caConfig.Validity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
// Store CA certificate creation time
|
// Store CA certificate creation time
|
||||||
CAState.CreatedAt = now.UTC().Format(time.RFC3339)
|
caState.CreatedAt = now.UTC().Format(time.RFC3339)
|
||||||
|
|
||||||
tmpl := x509.Certificate{
|
tmpl := x509.Certificate{
|
||||||
SerialNumber: serialNumber,
|
SerialNumber: serialNumber,
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
Country: []string{CAConfig.Country},
|
Country: []string{caConfig.Country},
|
||||||
Organization: []string{CAConfig.Organization},
|
Organization: []string{caConfig.Organization},
|
||||||
OrganizationalUnit: optionalSlice(CAConfig.OrganizationalUnit),
|
OrganizationalUnit: optionalSlice(caConfig.OrganizationalUnit),
|
||||||
Locality: optionalSlice(CAConfig.Locality),
|
Locality: optionalSlice(caConfig.Locality),
|
||||||
Province: optionalSlice(CAConfig.Province),
|
Province: optionalSlice(caConfig.Province),
|
||||||
CommonName: CAConfig.Name,
|
CommonName: caConfig.Name,
|
||||||
},
|
},
|
||||||
NotBefore: now,
|
NotBefore: now,
|
||||||
NotAfter: now.Add(validity),
|
NotAfter: now.Add(validity),
|
||||||
@@ -398,10 +398,10 @@ func InitCA() error {
|
|||||||
IsCA: true,
|
IsCA: true,
|
||||||
}
|
}
|
||||||
// Add email if present
|
// Add email if present
|
||||||
if CAConfig.Email != "" {
|
if caConfig.Email != "" {
|
||||||
tmpl.Subject.ExtraNames = append(tmpl.Subject.ExtraNames, pkix.AttributeTypeAndValue{
|
tmpl.Subject.ExtraNames = append(tmpl.Subject.ExtraNames, pkix.AttributeTypeAndValue{
|
||||||
Type: []int{1, 2, 840, 113549, 1, 9, 1}, // emailAddress OID
|
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)
|
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})
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
|
||||||
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
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)
|
fmt.Println("Error saving CA certificate:", err)
|
||||||
return 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)
|
fmt.Println("Error saving CA key:", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// set last updated time in the CAState
|
// 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
|
// Save the state
|
||||||
|
|
||||||
err = SaveCAState()
|
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")
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create certificate: %v", err)
|
return fmt.Errorf("failed to create certificate: %v", err)
|
||||||
}
|
}
|
||||||
@@ -536,8 +536,8 @@ func issueSingleCertificate(def CertificateDefinition) error {
|
|||||||
if basename == "" {
|
if basename == "" {
|
||||||
basename = def.Subject
|
basename = def.Subject
|
||||||
}
|
}
|
||||||
certFile := filepath.Join(CAConfig.Paths.Certificates, basename+".crt.pem")
|
certFile := filepath.Join(caConfig.Paths.Certificates, basename+".crt.pem")
|
||||||
keyFile := filepath.Join(CAConfig.Paths.PrivateKeys, basename+".key.pem")
|
keyFile := filepath.Join(caConfig.Paths.PrivateKeys, basename+".key.pem")
|
||||||
if err := SavePEM(certFile, certPEM, false); err != nil {
|
if err := SavePEM(certFile, certPEM, false); err != nil {
|
||||||
return fmt.Errorf("error saving certificate: %v", err)
|
return fmt.Errorf("error saving certificate: %v", err)
|
||||||
}
|
}
|
||||||
@@ -560,8 +560,8 @@ Certificate:
|
|||||||
def.SAN,
|
def.SAN,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CAState.UpdateCAStateAfterIssue(
|
caState.UpdateCAStateAfterIssue(
|
||||||
CAConfig.SerialType,
|
caConfig.SerialType,
|
||||||
basename,
|
basename,
|
||||||
serialNumber,
|
serialNumber,
|
||||||
validityDur,
|
validityDur,
|
||||||
|
34
certdb.go
34
certdb.go
@@ -14,8 +14,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// _CAState represents the persisted CA state in JSON
|
// CAState represents the persisted CA state in JSON
|
||||||
type _CAState struct {
|
type CAState struct {
|
||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt string `json:"createdAt"`
|
||||||
UpdatedAt string `json:"updatedAt"`
|
UpdatedAt string `json:"updatedAt"`
|
||||||
Serial int `json:"serial,omitempty"`
|
Serial int `json:"serial,omitempty"`
|
||||||
@@ -34,7 +34,7 @@ type CertificateRecord struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caStatePath() string {
|
func caStatePath() string {
|
||||||
return filepath.Join(filepath.Dir(CAConfigPath), CAConfig.GetStateFileName())
|
return filepath.Join(filepath.Dir(caConfigPath), caConfig.GetStateFileName())
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadCAState loads the CA state from a JSON file
|
// LoadCAState loads the CA state from a JSON file
|
||||||
@@ -46,8 +46,8 @@ func LoadCAState() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
CAState = &_CAState{}
|
caState = &CAState{}
|
||||||
if err := json.NewDecoder(f).Decode(CAState); err != nil {
|
if err := json.NewDecoder(f).Decode(caState); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -55,7 +55,7 @@ func LoadCAState() error {
|
|||||||
|
|
||||||
// SaveCAState saves the CA state to a JSON file
|
// SaveCAState saves the CA state to a JSON file
|
||||||
func SaveCAState() error {
|
func SaveCAState() error {
|
||||||
CAState.UpdatedAt = time.Now().UTC().Format(time.RFC3339)
|
caState.UpdatedAt = time.Now().UTC().Format(time.RFC3339)
|
||||||
f, err := os.Create(caStatePath())
|
f, err := os.Create(caStatePath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -63,11 +63,11 @@ func SaveCAState() error {
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
enc := json.NewEncoder(f)
|
enc := json.NewEncoder(f)
|
||||||
enc.SetIndent("", " ")
|
enc.SetIndent("", " ")
|
||||||
return enc.Encode(CAState)
|
return enc.Encode(caState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCAStateAfterIssue updates the CA state JSON after issuing a certificate
|
// UpdateCAStateAfterIssue updates the CA state JSON after issuing a certificate
|
||||||
func (s *_CAState) UpdateCAStateAfterIssue(serialType, basename string, serialNumber any, validity time.Duration) error {
|
func (s *CAState) UpdateCAStateAfterIssue(serialType, basename string, serialNumber any, validity time.Duration) error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in UpdateCAStateAfterIssue. This indicates a programming error.\n")
|
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in UpdateCAStateAfterIssue. This indicates a programming error.\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -77,8 +77,8 @@ func (s *_CAState) UpdateCAStateAfterIssue(serialType, basename string, serialNu
|
|||||||
serialStr := ""
|
serialStr := ""
|
||||||
switch serialType {
|
switch serialType {
|
||||||
case "sequential":
|
case "sequential":
|
||||||
serialStr = fmt.Sprintf("%d", CAState.Serial)
|
serialStr = fmt.Sprintf("%d", caState.Serial)
|
||||||
CAState.Serial++
|
caState.Serial++
|
||||||
case "random":
|
case "random":
|
||||||
serialStr = fmt.Sprintf("%x", serialNumber)
|
serialStr = fmt.Sprintf("%x", serialNumber)
|
||||||
default:
|
default:
|
||||||
@@ -88,7 +88,7 @@ func (s *_CAState) UpdateCAStateAfterIssue(serialType, basename string, serialNu
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *_CAState) AddCertificate(name, issued, expires, serial string) {
|
func (s *CAState) AddCertificate(name, issued, expires, serial string) {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in AddCertificate. This indicates a programming error.\n")
|
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in AddCertificate. This indicates a programming error.\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -103,7 +103,7 @@ func (s *_CAState) AddCertificate(name, issued, expires, serial string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RevokeCertificate revokes a certificate by serial number and reason code, updates state, and saves to disk
|
// RevokeCertificate revokes a certificate by serial number and reason code, updates state, and saves to disk
|
||||||
func (s *_CAState) RevokeCertificate(serial string, reason int) error {
|
func (s *CAState) RevokeCertificate(serial string, reason int) error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in RevokeCertificate. This indicates a programming error.\n")
|
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in RevokeCertificate. This indicates a programming error.\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -129,11 +129,11 @@ func (s *_CAState) RevokeCertificate(serial string, reason int) error {
|
|||||||
|
|
||||||
// GenerateCRL generates a CRL file from revoked certificates and writes it to the given path
|
// GenerateCRL generates a CRL file from revoked certificates and writes it to the given path
|
||||||
// validityDays defines the number of days for which the CRL is valid (NextUpdate - ThisUpdate)
|
// validityDays defines the number of days for which the CRL is valid (NextUpdate - ThisUpdate)
|
||||||
func (s *_CAState) GenerateCRL(crlPath string, validityDays int) error {
|
func (s *CAState) GenerateCRL(crlPath string, validityDays int) error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return fmt.Errorf("CAState is nil in GenerateCRL")
|
return fmt.Errorf("CAState is nil in GenerateCRL")
|
||||||
}
|
}
|
||||||
if CACert == nil || CAKey == nil {
|
if caCert == nil || caKey == nil {
|
||||||
return fmt.Errorf("CA certificate or key not loaded")
|
return fmt.Errorf("CA certificate or key not loaded")
|
||||||
}
|
}
|
||||||
var revokedCerts []pkix.RevokedCertificate
|
var revokedCerts []pkix.RevokedCertificate
|
||||||
@@ -162,14 +162,14 @@ func (s *_CAState) GenerateCRL(crlPath string, validityDays int) error {
|
|||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
nextUpdate := now.Add(time.Duration(validityDays) * 24 * time.Hour) // validityDays * 24 * 60 * 60 * 1000 milliseconds
|
nextUpdate := now.Add(time.Duration(validityDays) * 24 * time.Hour) // validityDays * 24 * 60 * 60 * 1000 milliseconds
|
||||||
template := &x509.RevocationList{
|
template := &x509.RevocationList{
|
||||||
SignatureAlgorithm: CACert.SignatureAlgorithm,
|
SignatureAlgorithm: caCert.SignatureAlgorithm,
|
||||||
RevokedCertificates: revokedCerts,
|
RevokedCertificates: revokedCerts,
|
||||||
Number: big.NewInt(int64(s.CRLNumber + 1)),
|
Number: big.NewInt(int64(s.CRLNumber + 1)),
|
||||||
ThisUpdate: now,
|
ThisUpdate: now,
|
||||||
NextUpdate: nextUpdate,
|
NextUpdate: nextUpdate,
|
||||||
Issuer: CACert.Subject,
|
Issuer: caCert.Subject,
|
||||||
}
|
}
|
||||||
crlBytes, err := x509.CreateRevocationList(nil, template, CACert, CAKey)
|
crlBytes, err := x509.CreateRevocationList(nil, template, caCert, caKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create CRL: %v", err)
|
return fmt.Errorf("failed to create CRL: %v", err)
|
||||||
}
|
}
|
||||||
|
8
main.go
8
main.go
@@ -48,7 +48,7 @@ func main() {
|
|||||||
rootCmd.PersistentFlags().BoolVar(&overwrite, "overwrite", false, "Allow overwriting existing files")
|
rootCmd.PersistentFlags().BoolVar(&overwrite, "overwrite", false, "Allow overwriting existing files")
|
||||||
rootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Print detailed information about each processed certificate")
|
rootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Print detailed information about each processed certificate")
|
||||||
rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "Validate and show what would be created, but do not write files (batch mode)")
|
rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "Validate and show what would be created, but do not write files (batch mode)")
|
||||||
rootCmd.PersistentFlags().StringVar(&CAConfigPath, "config-path", "ca_config.hcl", "Path to CA configuration file")
|
rootCmd.PersistentFlags().StringVar(&caConfigPath, "config-path", "ca_config.hcl", "Path to CA configuration file")
|
||||||
|
|
||||||
// lab-ca initca command
|
// lab-ca initca command
|
||||||
var initCmd = &cobra.Command{
|
var initCmd = &cobra.Command{
|
||||||
@@ -124,7 +124,7 @@ func main() {
|
|||||||
serial := ""
|
serial := ""
|
||||||
if revokeName != "" {
|
if revokeName != "" {
|
||||||
found := false
|
found := false
|
||||||
for _, rec := range CAState.Certificates {
|
for _, rec := range caState.Certificates {
|
||||||
if rec.Name == revokeName {
|
if rec.Name == revokeName {
|
||||||
serial = rec.Serial
|
serial = rec.Serial
|
||||||
found = true
|
found = true
|
||||||
@@ -157,7 +157,7 @@ func main() {
|
|||||||
fmt.Println()
|
fmt.Println()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if err := CAState.RevokeCertificate(serial, reasonCode); err != nil {
|
if err := caState.RevokeCertificate(serial, reasonCode); err != nil {
|
||||||
fmt.Printf("ERROR: %v\n", err)
|
fmt.Printf("ERROR: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ func main() {
|
|||||||
if crlValidityDays <= 0 {
|
if crlValidityDays <= 0 {
|
||||||
crlValidityDays = 30 // default to 30 days
|
crlValidityDays = 30 // default to 30 days
|
||||||
}
|
}
|
||||||
err := CAState.GenerateCRL(crlFile, crlValidityDays)
|
err := caState.GenerateCRL(crlFile, crlValidityDays)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR generating CRL: %v\n", err)
|
fmt.Printf("ERROR generating CRL: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
Reference in New Issue
Block a user