diff --git a/backend/internal/api/handlers/certificate_handler.go b/backend/internal/api/handlers/certificate_handler.go index a1ffa34e..b9d8e7f3 100644 --- a/backend/internal/api/handlers/certificate_handler.go +++ b/backend/internal/api/handlers/certificate_handler.go @@ -360,7 +360,7 @@ func (h *CertificateHandler) Export(c *gin.Context) { } } - data, filename, err := h.service.ExportCertificate(certUUID, req.Format, req.IncludeKey) + data, filename, err := h.service.ExportCertificate(certUUID, req.Format, req.IncludeKey, req.PFXPassword) if err != nil { if err == services.ErrCertNotFound { c.JSON(http.StatusNotFound, gin.H{"error": "certificate not found"}) diff --git a/backend/internal/services/certificate_service.go b/backend/internal/services/certificate_service.go index b96f1c28..d1646e72 100644 --- a/backend/internal/services/certificate_service.go +++ b/backend/internal/services/certificate_service.go @@ -708,7 +708,7 @@ func (s *CertificateService) DeleteCertificate(certUUID string) error { // ExportCertificate exports a certificate in the requested format. // Returns the file data, suggested filename, and any error. -func (s *CertificateService) ExportCertificate(certUUID string, format string, includeKey bool) ([]byte, string, error) { +func (s *CertificateService) ExportCertificate(certUUID string, format string, includeKey bool, pfxPassword string) ([]byte, string, error) { var cert models.SSLCertificate if err := s.db.Where("uuid = ?", certUUID).First(&cert).Error; err != nil { if err == gorm.ErrRecordNotFound { @@ -752,7 +752,7 @@ func (s *CertificateService) ExportCertificate(certUUID string, format string, i if err != nil { return nil, "", fmt.Errorf("failed to decrypt private key for PFX: %w", err) } - pfxData, err := ConvertPEMToPFX(cert.Certificate, keyPEM, cert.CertificateChain, "") + pfxData, err := ConvertPEMToPFX(cert.Certificate, keyPEM, cert.CertificateChain, pfxPassword) if err != nil { return nil, "", fmt.Errorf("failed to create PFX: %w", err) } diff --git a/backend/internal/services/certificate_service_coverage_test.go b/backend/internal/services/certificate_service_coverage_test.go index 22c02937..86d3547e 100644 --- a/backend/internal/services/certificate_service_coverage_test.go +++ b/backend/internal/services/certificate_service_coverage_test.go @@ -311,19 +311,19 @@ func TestCertificateService_ExportCertificate(t *testing.T) { cert := seedCertWithKey(t, db, encSvc, "export-cert-1", "Export Cert", domain, expiry) t.Run("not found", func(t *testing.T) { - _, _, err := cs.ExportCertificate("nonexistent", "pem", false) + _, _, err := cs.ExportCertificate("nonexistent", "pem", false, "") assert.ErrorIs(t, err, ErrCertNotFound) }) t.Run("pem without key", func(t *testing.T) { - data, filename, err := cs.ExportCertificate(cert.UUID, "pem", false) + data, filename, err := cs.ExportCertificate(cert.UUID, "pem", false, "") require.NoError(t, err) assert.Equal(t, "Export Cert.pem", filename) assert.Contains(t, string(data), "BEGIN CERTIFICATE") }) t.Run("pem with key", func(t *testing.T) { - data, filename, err := cs.ExportCertificate(cert.UUID, "pem", true) + data, filename, err := cs.ExportCertificate(cert.UUID, "pem", true, "") require.NoError(t, err) assert.Equal(t, "Export Cert.pem", filename) assert.Contains(t, string(data), "BEGIN CERTIFICATE") @@ -331,28 +331,28 @@ func TestCertificateService_ExportCertificate(t *testing.T) { }) t.Run("der format", func(t *testing.T) { - data, filename, err := cs.ExportCertificate(cert.UUID, "der", false) + data, filename, err := cs.ExportCertificate(cert.UUID, "der", false, "") require.NoError(t, err) assert.Equal(t, "Export Cert.der", filename) assert.NotEmpty(t, data) }) t.Run("pfx format", func(t *testing.T) { - data, filename, err := cs.ExportCertificate(cert.UUID, "pfx", false) + data, filename, err := cs.ExportCertificate(cert.UUID, "pfx", false, "") require.NoError(t, err) assert.Equal(t, "Export Cert.pfx", filename) assert.NotEmpty(t, data) }) t.Run("unsupported format", func(t *testing.T) { - _, _, err := cs.ExportCertificate(cert.UUID, "jks", false) + _, _, err := cs.ExportCertificate(cert.UUID, "jks", false, "") assert.Error(t, err) assert.Contains(t, err.Error(), "unsupported export format") }) t.Run("empty name uses fallback", func(t *testing.T) { noNameCert := seedCertWithKey(t, db, encSvc, "export-noname", "", domain, expiry) - _, filename, err := cs.ExportCertificate(noNameCert.UUID, "pem", false) + _, filename, err := cs.ExportCertificate(noNameCert.UUID, "pem", false, "") require.NoError(t, err) assert.Equal(t, "certificate.pem", filename) })