104 lines
4.8 KiB
C#
104 lines
4.8 KiB
C#
using DigitalData.Core.Security.RSAKey;
|
|
|
|
namespace DigitalData.Core.Security.Config
|
|
{
|
|
public class CryptoFactoryParams : RSAFactoryParams
|
|
{
|
|
public string PemDirectory { get; init; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Represents the separator used to concatenate the components of a file-related token string.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The resulting file-related token string is constructed as follows:
|
|
/// <c>string.Join(FileNameSeparator, Issuer, Audience, Secret_version)</c>.
|
|
/// If <c>Secret_version</c> is not null, it will be included in the concatenation.
|
|
/// </remarks>
|
|
/// <example>
|
|
/// For example, if <c>FileNameSeparator = "_-_"</c>, the output might look like:
|
|
/// <c>"Issuer_-_Audience_-_Secret_version"</c>.
|
|
/// </example>
|
|
public string FileNameSeparator { get; init; } = "_-_";
|
|
|
|
public string FileExtension { get; init; } = "pem";
|
|
|
|
/// <summary>
|
|
///This is the subtext of the pem file name. For the file to be automatically renewed, the name must be assigned to change periodically. For example, by default MM/2 will be refreshed every 2 months.
|
|
/// <br />
|
|
/// - <see cref="StringExtensions.ToTag(DateTime, string)" /> is used when converting to tag.
|
|
/// <br />
|
|
/// - If the format contains the symbol “//”, the method divides the numeric value obtained from the left side of the format
|
|
/// by one minus the numeric value obtained from the right side of the format string and adds one. For instance:
|
|
/// <br />
|
|
/// - If the date is 02.03.2024 and the format is "MM//2", it extracts the month (02), subtracts one (3), divides it by 2,
|
|
/// rounds down the outgoing number (1), adds one to the number (resulting in 2).
|
|
/// <br />
|
|
/// - If the format does not contain "//", the method uses the default <see cref="DateTime.ToString"/> format.
|
|
/// <br />
|
|
/// This method provides a way to format the date based on typical or customized rules, including mathematical operations like division.
|
|
/// </summary>
|
|
public string DateTagFormat { get; init; } = "MM//2";
|
|
|
|
public IEnumerable<RSADecryptor> Decryptors { get; init; } = new List<RSADecryptor>();
|
|
|
|
public IEnumerable<RSATokenDescriptor> TokenDescriptors { get; init; } = new List<RSATokenDescriptor>();
|
|
|
|
public RSADecryptor? VaultDecryptor { get; init; }
|
|
|
|
public CryptoFactoryParams()
|
|
{
|
|
// init decryptors
|
|
AfterCreate += () =>
|
|
{
|
|
// Create root folder if it does not exist
|
|
if (!Directory.Exists(PemDirectory))
|
|
Directory.CreateDirectory(PemDirectory);
|
|
|
|
var privateKeys = new List<RSAPrivateKey>();
|
|
privateKeys.AddRange(Decryptors);
|
|
privateKeys.AddRange(TokenDescriptors);
|
|
if (VaultDecryptor is not null)
|
|
privateKeys.Add(VaultDecryptor);
|
|
|
|
foreach (var privateKey in privateKeys)
|
|
{
|
|
// set default path
|
|
if (privateKey.IsPemNull)
|
|
{
|
|
// file name
|
|
var file_name_params = new List<object>();
|
|
|
|
if (privateKey.Id is not null)
|
|
file_name_params.Add(privateKey.Id);
|
|
else if (privateKey is RSATokenDescriptor descriptor)
|
|
file_name_params.Add(descriptor.Issuer);
|
|
|
|
file_name_params.Add(KeySizeInBits);
|
|
file_name_params.Add(DateTime.Now.ToTag(DateTagFormat));
|
|
|
|
if (privateKey.IsEncrypted)
|
|
file_name_params.Add(Secrets.Version);
|
|
|
|
var file_name = $"{string.Join(FileNameSeparator, file_name_params)}.{FileExtension}";
|
|
|
|
var path = Path.Combine(PemDirectory, file_name);
|
|
|
|
if (File.Exists(path))
|
|
privateKey.SetPem(File.ReadAllText(path));
|
|
else
|
|
{
|
|
var pem = privateKey.IsEncrypted
|
|
? Instance.RSAFactory.CreateEncryptedPrivateKeyPem(pbeParameters: PbeParameters, keySizeInBits: KeySizeInBits, password: Secrets.PBE_PASSWORD)
|
|
: Instance.RSAFactory.CreatePrivateKeyPem(keySizeInBits: KeySizeInBits);
|
|
|
|
privateKey.SetPem(pem);
|
|
|
|
// Save file in background
|
|
Task.Run(async () => await File.WriteAllTextAsync(path: path, pem));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|
|
} |