60 lines
1.8 KiB
C#

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<string, SemaphoreSlim> 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();
}
}
}
}