diff --git a/ZA.CoreService.ESBCertificateManager/Form1.cs b/ZA.CoreService.ESBCertificateManager/Form1.cs index 507b8c2..25f6c8f 100644 --- a/ZA.CoreService.ESBCertificateManager/Form1.cs +++ b/ZA.CoreService.ESBCertificateManager/Form1.cs @@ -47,6 +47,7 @@ namespace ZA.CoreService.ESBCertificateManager private LocalSetupSelection? _localSetupSelection; private CertificateInfo? _loadedCertificateInfo; + private string? _loadedCertificatePassword; private IReadOnlyList _loadedTargets = []; private bool _isOperationRunning; private CancellationTokenSource? _runCts; @@ -953,7 +954,9 @@ namespace ZA.CoreService.ESBCertificateManager return; } - CertificateInfo? certificateInfo = TryReadSelectedCertificate(selectedPath); + CertificateInfo? certificateInfo = TryReadSelectedCertificate( + selectedPath, + out string? certificatePassword); if (certificateInfo == null) { return; @@ -961,15 +964,26 @@ namespace ZA.CoreService.ESBCertificateManager txtCertificatePath.Text = selectedPath; _loadedCertificateInfo = certificateInfo; + _loadedCertificatePassword = certificatePassword; SetStatus($"Zertifikat ausgewählt: {Path.GetFileName(selectedPath)}", isError: false); DisplayCertificateInfo(certificateInfo); UpdateToNextStep(2); SetFileButtonState(fileLoaded: true); RefreshActionButtonStates(); + + // Zielpfade mit Quell-Kennwort erneut prüfen, damit Ablauf/Gültigkeit sichtbar wird + if (_loadedTargets.Count > 0) + { + _ = ProbeTargetCertificatesAsync(); + } } - private CertificateInfo? TryReadSelectedCertificate(string selectedPath) + private CertificateInfo? TryReadSelectedCertificate( + string selectedPath, + out string? certificatePassword) { + certificatePassword = null; + string extension = Path.GetExtension(selectedPath); bool needsPassword = extension.Equals(".pfx", StringComparison.OrdinalIgnoreCase) @@ -991,7 +1005,9 @@ namespace ZA.CoreService.ESBCertificateManager try { - return ReadCertificate(selectedPath, pfxPassword); + CertificateInfo info = ReadCertificate(selectedPath, pfxPassword); + certificatePassword = pfxPassword; + return info; } catch (CryptographicException) { @@ -1019,6 +1035,7 @@ namespace ZA.CoreService.ESBCertificateManager { txtCertificatePath.Text = string.Empty; _loadedCertificateInfo = null; + _loadedCertificatePassword = null; SetStatus("Keine Datei ausgewählt", isError: false); lblCertificateSubject.Text = "-"; @@ -1671,9 +1688,14 @@ namespace ZA.CoreService.ESBCertificateManager return merged; } - private async Task ProbeTargetCertificatesAsync() + private async Task ProbeTargetCertificatesAsync( + IReadOnlySet? preferLoadedCertificateForTargetIds = null) { CertificateProbeService probe = new(); + string? password = _loadedCertificatePassword; + Func? passwordPrompt = password is null + ? null + : () => password; foreach (DataGridViewRow row in dgvTargets.Rows) { @@ -1683,7 +1705,7 @@ namespace ZA.CoreService.ESBCertificateManager } CertificateProbeResult result = await Task.Run( - () => probe.Probe(target.FullTargetPath)); + () => probe.Probe(target.FullTargetPath, passwordPrompt)); if (IsDisposed || !dgvTargets.Columns.Contains("Expiry")) { @@ -1692,13 +1714,20 @@ namespace ZA.CoreService.ESBCertificateManager if (result.Success && result.Certificate is not null) { - string expiry = result.Certificate.ValidUntil - .ToLocalTime() - .ToString("dd.MM.yyyy"); + row.Cells["Expiry"].Value = FormatCertificateExpiryCell( + result.Certificate); + continue; + } - row.Cells["Expiry"].Value = result.Certificate.IsCurrentlyValid - ? $"gültig bis {expiry}" - : $"abgelaufen {expiry}"; + // Nach erfolgreichem Tausch: Quellzertifikat liegt am Ziel – + // Gültigkeit auch zeigen, falls Probe am Kennwort scheitert. + if (preferLoadedCertificateForTargetIds is not null + && preferLoadedCertificateForTargetIds.Contains(target.Id) + && _loadedCertificateInfo is not null + && result.FileExists) + { + row.Cells["Expiry"].Value = FormatCertificateExpiryCell( + _loadedCertificateInfo); continue; } @@ -1714,6 +1743,17 @@ namespace ZA.CoreService.ESBCertificateManager } } + private static string FormatCertificateExpiryCell(CertificateInfo certificate) + { + string expiry = certificate.ValidUntil + .ToLocalTime() + .ToString("dd.MM.yyyy"); + + return certificate.IsCurrentlyValid + ? $"gültig bis {expiry}" + : $"abgelaufen {expiry}"; + } + private List GetSelectedTargets() { List selected = []; @@ -2071,6 +2111,11 @@ namespace ZA.CoreService.ESBCertificateManager targetResult.StatusText); } + HashSet exchangedTargetIds = runResult.TargetResults + .Where(result => result.Success) + .Select(result => result.TargetId) + .ToHashSet(); + if (runResult.OverallSuccess) { SetStatus( @@ -2078,7 +2123,7 @@ namespace ZA.CoreService.ESBCertificateManager isError: false); UpdateToNextStep(4); - await ProbeTargetCertificatesAsync(); + await ProbeTargetCertificatesAsync(exchangedTargetIds); } else { @@ -2100,7 +2145,7 @@ namespace ZA.CoreService.ESBCertificateManager "Austausch fehlgeschlagen", details); - await ProbeTargetCertificatesAsync(); + await ProbeTargetCertificatesAsync(exchangedTargetIds); } } catch (OperationCanceledException)