using DigitalData.Core.Security.Config; using DigitalData.Core.Security.Extensions; using DigitalData.Core.Security.RSAKey.Auth; using DigitalData.Core.Security.RSAKey.Base; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace DigitalData.Core.Security.Services; public class PemFileInitalizer : BackgroundService { private readonly RSAParams _factoryParams; private readonly ILogger _logger; public PemFileInitalizer(IOptions factoryParamsOptions, ILogger logger) { _factoryParams = factoryParamsOptions.Value; _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { try { _logger.LogInformation("Pem file initalizer launched."); await InitPemFiles(stoppingToken); } catch(Exception ex) { _logger.LogError(ex, "Pem files cannot be initialized."); } } private async Task InitPemFiles(CancellationToken stoppingToken = default) { _logger.LogInformation("Initializing pem files. PemDirectory: {dir}", _factoryParams.PemDirectory); // Create root folder if it does not exist if (!Directory.Exists(_factoryParams.PemDirectory)) Directory.CreateDirectory(_factoryParams.PemDirectory); var privateKeys = new List(); privateKeys.AddRange(_factoryParams.Decryptors); privateKeys.AddRange(_factoryParams.TokenDescriptors); if (_factoryParams.VaultDecryptor is not null) privateKeys.Add(_factoryParams.VaultDecryptor); foreach (var privateKey in privateKeys) { // set default path if (privateKey.IsPemNull) { // file name var file_name_params = new List(); 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(_factoryParams.KeySizeInBits); file_name_params.Add(DateTime.Now.ToTag(_factoryParams.DateTagFormat)); if (privateKey.IsEncrypted) file_name_params.Add(Secrets.Version); var file_name = $"{string.Join(_factoryParams.FileNameSeparator, file_name_params)}.{_factoryParams.FileExtension}"; var path = Path.Combine(_factoryParams.PemDirectory, file_name); if (File.Exists(path)) privateKey.SetPem(File.ReadAllText(path)); else { var pem = privateKey.IsEncrypted ? RSAFactory.Static.CreateEncryptedPrivateKeyPem(pbeParameters: _factoryParams.PbeParameters, keySizeInBits: _factoryParams.KeySizeInBits, password: Secrets.PBE_PASSWORD) : RSAFactory.Static.CreatePrivateKeyPem(keySizeInBits: _factoryParams.KeySizeInBits); privateKey.SetPem(pem); // Save file in background await File.WriteAllTextAsync(path: path, pem, stoppingToken); } } } } }