big changes
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using ZA.CoreService.ESBCertificateManager.Models;
|
||||
using static ZA.CoreService.ESBCertificateManager.Models.RuntimeSettings;
|
||||
|
||||
namespace ZA.CoreService.ESBCertificateManager.Services;
|
||||
|
||||
public sealed class AlwaysEncryptedCertificateService
|
||||
{
|
||||
private readonly string _expectedThumbprint;
|
||||
private readonly StoreName _storeName;
|
||||
private readonly StoreLocation _storeLocation;
|
||||
|
||||
public AlwaysEncryptedCertificateService(
|
||||
AlwaysEncryptedSettings settings)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(
|
||||
settings.CertificateThumbprint))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"AlwaysEncrypted:CertificateThumbprint fehlt.");
|
||||
}
|
||||
|
||||
_expectedThumbprint = NormalizeThumbprint(
|
||||
settings.CertificateThumbprint);
|
||||
|
||||
if (!Enum.TryParse(
|
||||
settings.StoreName,
|
||||
ignoreCase: true,
|
||||
out _storeName))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Ungültiger Zertifikatsspeicher: '{settings.StoreName}'.");
|
||||
}
|
||||
|
||||
if (!Enum.TryParse(
|
||||
settings.StoreLocation,
|
||||
ignoreCase: true,
|
||||
out _storeLocation))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Ungültiger Zertifikatsspeicherort: " +
|
||||
$"'{settings.StoreLocation}'.");
|
||||
}
|
||||
}
|
||||
|
||||
public CertificateCheckResult CheckCertificate()
|
||||
{
|
||||
using X509Store store = new(
|
||||
_storeName,
|
||||
_storeLocation);
|
||||
|
||||
store.Open(OpenFlags.ReadOnly);
|
||||
|
||||
X509Certificate2? certificate = store.Certificates
|
||||
.Find(
|
||||
X509FindType.FindByThumbprint,
|
||||
_expectedThumbprint,
|
||||
validOnly: false)
|
||||
.OfType<X509Certificate2>()
|
||||
.FirstOrDefault();
|
||||
|
||||
if (certificate is null)
|
||||
{
|
||||
return new CertificateCheckResult(
|
||||
IsValid: false,
|
||||
Message:
|
||||
$"Das Always-Encrypted-Zertifikat wurde nicht gefunden. " +
|
||||
$"Speicher: {_storeLocation}\\{_storeName}, " +
|
||||
$"Thumbprint: {_expectedThumbprint}");
|
||||
}
|
||||
|
||||
if (!certificate.HasPrivateKey)
|
||||
{
|
||||
return new CertificateCheckResult(
|
||||
IsValid: false,
|
||||
Message:
|
||||
"Das Always-Encrypted-Zertifikat wurde gefunden, " +
|
||||
"besitzt aber keinen verfügbaren privaten Schlüssel.");
|
||||
}
|
||||
|
||||
return new CertificateCheckResult(
|
||||
IsValid: true,
|
||||
Message:
|
||||
"Always-Encrypted-Zertifikat und privater " +
|
||||
"Schlüssel sind verfügbar.");
|
||||
}
|
||||
|
||||
public void ImportPfx(
|
||||
string pfxFilePath,
|
||||
string pfxPassword)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(pfxFilePath))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Es wurde keine PFX-Datei ausgewählt.",
|
||||
nameof(pfxFilePath));
|
||||
}
|
||||
|
||||
if (!File.Exists(pfxFilePath))
|
||||
{
|
||||
throw new FileNotFoundException(
|
||||
"Die ausgewählte PFX-Datei wurde nicht gefunden.",
|
||||
pfxFilePath);
|
||||
}
|
||||
|
||||
X509KeyStorageFlags flags =
|
||||
X509KeyStorageFlags.UserKeySet
|
||||
| X509KeyStorageFlags.PersistKeySet;
|
||||
|
||||
using X509Certificate2 certificate = new(
|
||||
pfxFilePath,
|
||||
pfxPassword,
|
||||
flags);
|
||||
|
||||
string importedThumbprint =
|
||||
NormalizeThumbprint(certificate.Thumbprint);
|
||||
|
||||
if (!string.Equals(
|
||||
importedThumbprint,
|
||||
_expectedThumbprint,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Die ausgewählte PFX-Datei gehört nicht zum " +
|
||||
"erwarteten Always-Encrypted-Zertifikat.");
|
||||
}
|
||||
|
||||
if (!certificate.HasPrivateKey)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Die ausgewählte PFX-Datei enthält keinen privaten Schlüssel.");
|
||||
}
|
||||
|
||||
using X509Store store = new(
|
||||
_storeName,
|
||||
_storeLocation);
|
||||
|
||||
store.Open(OpenFlags.ReadWrite);
|
||||
store.Add(certificate);
|
||||
}
|
||||
|
||||
private static string NormalizeThumbprint(
|
||||
string thumbprint)
|
||||
{
|
||||
return thumbprint
|
||||
.Replace(" ", string.Empty)
|
||||
.Trim()
|
||||
.ToUpperInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed record CertificateCheckResult(
|
||||
bool IsValid,
|
||||
string Message);
|
||||
Reference in New Issue
Block a user