mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-02-05 20:03:28 -05:00
98 lines
4.2 KiB
C#
98 lines
4.2 KiB
C#
//-----------------------------------------------------------------------
|
|
// <copyright file="DataProtectionExtensions.cs" company="aliasvault">
|
|
// Copyright (c) aliasvault. All rights reserved.
|
|
// Licensed under the AGPLv3 license. See LICENSE.md file in the project root for full license information.
|
|
// </copyright>
|
|
//-----------------------------------------------------------------------
|
|
|
|
namespace AliasVault.Cryptography.Server;
|
|
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using AliasServerDb;
|
|
using AliasVault.Shared.Server.Utilities;
|
|
using Microsoft.AspNetCore.DataProtection;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
/// <summary>
|
|
/// Helper utility to configure DataProtection for web projects.
|
|
/// </summary>
|
|
public static class DataProtectionExtensions
|
|
{
|
|
/// <summary>
|
|
/// Setup .NET DataProtection to use common AliasVault settings.
|
|
/// </summary>
|
|
/// <param name="services">Services.</param>
|
|
/// <param name="applicationName">Application name.</param>
|
|
/// <returns>IServiceCollection.</returns>
|
|
/// <exception cref="KeyNotFoundException">Thrown if environment variable is not set.</exception>
|
|
public static IServiceCollection AddAliasVaultDataProtection(
|
|
this IServiceCollection services,
|
|
string applicationName)
|
|
{
|
|
var dataProtectionBuilder = services.AddDataProtection()
|
|
.PersistKeysToDbContext<AliasServerDbContext>()
|
|
.SetApplicationName(applicationName);
|
|
|
|
if (SecretReader.IsRunningInContainer())
|
|
{
|
|
ConfigureContainerDataProtection(dataProtectionBuilder);
|
|
}
|
|
else
|
|
{
|
|
ConfigureDevelopmentDataProtection(dataProtectionBuilder, applicationName);
|
|
}
|
|
|
|
return services;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure data protection for container environments.
|
|
/// </summary>
|
|
/// <param name="dataProtectionBuilder">The data protection builder.</param>
|
|
private static void ConfigureContainerDataProtection(IDataProtectionBuilder dataProtectionBuilder)
|
|
{
|
|
// When running in containers, don't use certificate-based key protection due to Linux keystore limitations
|
|
// Keys are protected by database access controls, TLS, and container isolation
|
|
dataProtectionBuilder
|
|
.UseCryptographicAlgorithms(new Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration()
|
|
{
|
|
EncryptionAlgorithm = Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_256_CBC,
|
|
ValidationAlgorithm = Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm.HMACSHA256,
|
|
})
|
|
.SetDefaultKeyLifetime(TimeSpan.FromDays(90));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure data protection for development environments.
|
|
/// </summary>
|
|
/// <param name="dataProtectionBuilder">The data protection builder.</param>
|
|
/// <param name="applicationName">The application name.</param>
|
|
private static void ConfigureDevelopmentDataProtection(IDataProtectionBuilder dataProtectionBuilder, string applicationName)
|
|
{
|
|
// Not in container, get certificate password using SecretReader
|
|
var certPassword = SecretReader.GetDataProtectionCertPassword();
|
|
|
|
var certPath = $"../../certificates/app/{applicationName}.DataProtection.pfx";
|
|
if (certPassword == "Development")
|
|
{
|
|
certPath = Path.Combine(AppContext.BaseDirectory, $"{applicationName}.DataProtection.Development.pfx");
|
|
}
|
|
|
|
// Use certificate-based protection for development
|
|
var certificateFlags = X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable;
|
|
|
|
X509Certificate2 cert;
|
|
if (!File.Exists(certPath))
|
|
{
|
|
cert = CertificateGenerator.GeneratePfx($"{applicationName}.DataProtection", certPassword);
|
|
CertificateGenerator.SaveCertificateToFile(cert, certPassword, certPath);
|
|
}
|
|
else
|
|
{
|
|
cert = X509CertificateLoader.LoadPkcs12FromFile(certPath, certPassword, certificateFlags);
|
|
}
|
|
|
|
dataProtectionBuilder.ProtectKeysWithCertificate(cert);
|
|
}
|
|
}
|