63 lines
2.1 KiB
C#
63 lines
2.1 KiB
C#
using System.Security.Cryptography;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
|
|
namespace Tiku.Infrastructure.Security;
|
|
|
|
public sealed class DataProtectionKeyRingOptions
|
|
{
|
|
public const string SectionName = "Security:DataProtection";
|
|
|
|
public string ApplicationName { get; set; } = "Tiku.Api";
|
|
public string CertificatePath { get; set; } = string.Empty;
|
|
public string CertificatePassword { get; set; } = string.Empty;
|
|
|
|
public static bool BeValid(DataProtectionKeyRingOptions options, bool requireCertificate)
|
|
{
|
|
return !string.IsNullOrWhiteSpace(options.ApplicationName) &&
|
|
(!requireCertificate || !string.IsNullOrWhiteSpace(options.CertificatePath));
|
|
}
|
|
|
|
public X509Certificate2? LoadCertificate(bool requireCertificate)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(CertificatePath))
|
|
{
|
|
if (requireCertificate)
|
|
{
|
|
throw new InvalidOperationException(
|
|
"Data Protection certificate is required outside Development. " +
|
|
"Configure Security:DataProtection:CertificatePath or " +
|
|
"TIKU_DATA_PROTECTION_CERTIFICATE_PATH.");
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
var certificate = X509CertificateLoader.LoadPkcs12FromFile(
|
|
Path.GetFullPath(CertificatePath.Trim()),
|
|
CertificatePassword,
|
|
X509KeyStorageFlags.DefaultKeySet);
|
|
if (!certificate.HasPrivateKey)
|
|
{
|
|
certificate.Dispose();
|
|
throw new InvalidOperationException(
|
|
"Data Protection certificate must contain a private key.");
|
|
}
|
|
|
|
return certificate;
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
throw;
|
|
}
|
|
catch (Exception exception) when (
|
|
exception is CryptographicException or IOException or UnauthorizedAccessException)
|
|
{
|
|
throw new InvalidOperationException(
|
|
"Data Protection certificate could not be loaded from the configured PKCS#12 file.",
|
|
exception);
|
|
}
|
|
}
|
|
}
|