using DigitalData.Core.Abstractions.Security; using System.Collections.Concurrent; using System.Security.Cryptography; namespace DigitalData.Core.Security.Extensions { public static class RSAExtensions { public static RSA ToRSA(this string pem) { var rsa = RSA.Create(); rsa.ImportFromPem(pem); return rsa; } private static string CreatePath(string filename, string? directory = null) { directory ??= Environment.CurrentDirectory; if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } return Path.Combine(directory, $"{filename}.pem"); } private static readonly ConcurrentDictionary FileLocks = new(); public static void SavePem(this IRSACryptographer decryptor, string key, string? directory = null) { var filePath = CreatePath(filename: key, directory : directory); var fileLock = FileLocks.GetOrAdd(filePath, _ => new (1, 1)); fileLock.Wait(); try { File.WriteAllText(filePath, decryptor.Pem); } finally { fileLock.Release(); } } public static async Task SavePemAsync(this IRSACryptographer decryptor, string key, string? directory = null) { var filePath = CreatePath(filename: key, directory: directory); var fileLock = FileLocks.GetOrAdd(filePath, _ => new (1, 1)); await fileLock.WaitAsync(); try { await File.WriteAllTextAsync(filePath, decryptor.Pem); } finally { fileLock.Release(); } } } }