diff --git a/internal/pki/certs.go b/internal/pki/certs.go index 357b41b..724f904 100644 --- a/internal/pki/certs.go +++ b/internal/pki/certs.go @@ -12,157 +12,6 @@ import ( "time" ) -// GenerateCertificateRequest generates a new RSA key pair and a Certificate Signing Request (CSR). -// It saves the private key and CSR to the specified paths. -func GenerateCertificateRequest(commonName string, keyOutPath, csrOutPath string) error { - // Generate RSA key - key, err := rsa.GenerateKey(rand.Reader, DefaultRSAKeySize) - if err != nil { - return fmt.Errorf("failed to generate key: %w", err) - } - - // Create CSR template - template := x509.CertificateRequest{ - Subject: pkix.Name{ - CommonName: commonName, - Organization: []string{"KAT System"}, - }, - DNSNames: []string{commonName}, - } - - // Add IP addresses if commonName is an IP - if ip := net.ParseIP(commonName); ip != nil { - template.IPAddresses = []net.IP{ip} - } - - // Create CSR - csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &template, key) - if err != nil { - return fmt.Errorf("failed to create CSR: %w", err) - } - - // Save private key - keyOut, err := os.OpenFile(keyOutPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - return fmt.Errorf("failed to open key file for writing: %w", err) - } - defer keyOut.Close() - - err = pem.Encode(keyOut, &pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: x509.MarshalPKCS1PrivateKey(key), - }) - if err != nil { - return fmt.Errorf("failed to write key to file: %w", err) - } - - // Save CSR - csrOut, err := os.OpenFile(csrOutPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return fmt.Errorf("failed to open CSR file for writing: %w", err) - } - defer csrOut.Close() - - err = pem.Encode(csrOut, &pem.Block{ - Type: "CERTIFICATE REQUEST", - Bytes: csrBytes, - }) - if err != nil { - return fmt.Errorf("failed to write CSR to file: %w", err) - } - - return nil -} - -// SignCertificateRequest signs a CSR using the CA key and certificate. -// It loads the CA key and certificate from the specified paths, -// parses the CSR data, and issues a signed certificate. -func SignCertificateRequest(caKeyPath, caCertPath string, csrData []byte, certOutPath string, durationDays int) error { - // Load CA private key - caKey, err := LoadCAPrivateKey(caKeyPath) - if err != nil { - return err - } - - // Load CA certificate - caCert, err := LoadCACertificate(caCertPath) - if err != nil { - return err - } - - // Parse CSR - block, _ := pem.Decode(csrData) - if block == nil || block.Type != "CERTIFICATE REQUEST" { - return fmt.Errorf("failed to decode PEM block containing CSR") - } - - csr, err := x509.ParseCertificateRequest(block.Bytes) - if err != nil { - return fmt.Errorf("failed to parse CSR: %w", err) - } - - // Verify CSR signature - if err := csr.CheckSignature(); err != nil { - return fmt.Errorf("CSR signature verification failed: %w", err) - } - - // Generate serial number - serialNumber, err := generateSerialNumber() - if err != nil { - return fmt.Errorf("failed to generate serial number: %w", err) - } - - // Set certificate validity period - if durationDays <= 0 { - durationDays = DefaultCertValidityDays - } - notBefore := time.Now() - notAfter := notBefore.Add(time.Duration(durationDays) * 24 * time.Hour) - - // Create certificate template - template := x509.Certificate{ - SerialNumber: serialNumber, - Subject: csr.Subject, - NotBefore: notBefore, - NotAfter: notAfter, - KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, - BasicConstraintsValid: true, - IsCA: false, - DNSNames: csr.DNSNames, - IPAddresses: csr.IPAddresses, - } - - // Create certificate - derBytes, err := x509.CreateCertificate( - rand.Reader, - &template, - caCert, - csr.PublicKey, - caKey, - ) - if err != nil { - return fmt.Errorf("failed to create certificate: %w", err) - } - - // Save certificate - certOut, err := os.OpenFile(certOutPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return fmt.Errorf("failed to open certificate file for writing: %w", err) - } - defer certOut.Close() - - err = pem.Encode(certOut, &pem.Block{ - Type: "CERTIFICATE", - Bytes: derBytes, - }) - if err != nil { - return fmt.Errorf("failed to write certificate to file: %w", err) - } - - return nil -} - // ParseCSRFromBytes parses a PEM-encoded CSR from bytes func ParseCSRFromBytes(csrData []byte) (*x509.CertificateRequest, error) { block, _ := pem.Decode(csrData)