Reworked encryption to use less heap allocated buffers for secrets.

Also some work on plugin system.
This commit is contained in:
eelke 2026-08-18 07:40:24 +02:00
parent 8782ef39c6
commit 054754f553
42 changed files with 1452 additions and 242 deletions

View file

@ -0,0 +1,66 @@
using System.Security.Cryptography;
using IdentityShroud.Core.Contracts;
using IdentityShroud.Core.Security.Keys;
namespace IdentityShroud.Core.Model;
public sealed class DecryptedSigningKey : IDisposable
{
private readonly byte[] _keyData;
private readonly int _keyLength;
private bool _disposed;
public RealmSigningKeyId Id { get; }
public KeyType KeyType { get; }
public ReadOnlySpan<byte> KeyData => _disposed
? throw new ObjectDisposedException(nameof(DecryptedSigningKey))
: _keyData.AsSpan(0, _keyLength);
public DecryptedSigningKey(RealmSigningKey realmSigningKey, IDekEncryptionService encryptionService)
{
Id = realmSigningKey.Id;
KeyType = realmSigningKey.KeyType;
int keySize = encryptionService.GetDecryptedSize(realmSigningKey.Key);
_keyData = GC.AllocateArray<byte>(keySize, pinned: true);
_keyLength = keySize;
encryptionService.Decrypt(realmSigningKey.Key, _keyData);
}
public DecryptedSigningKey()
{
Id = RealmSigningKeyId.NewId();
KeyType = KeyType.RSA;
const int keySize = 2048;
using var rsa = RSA.Create();
rsa.KeySize = keySize;
int estimatedSize = EstimatePkcs8ExportSize(keySize);
Span<byte> temp = stackalloc byte[estimatedSize * 2];
try
{
if (!rsa.TryExportPkcs8PrivateKey(temp, out int bytesWritten))
throw new CryptographicException("Unable to export RSA private key.");
_keyData = GC.AllocateArray<byte>(bytesWritten, pinned: true);
_keyLength = bytesWritten;
temp[..bytesWritten].CopyTo(_keyData);
}
finally
{
CryptographicOperations.ZeroMemory(temp);
}
}
public void Dispose()
{
if (_disposed) return;
_disposed = true;
CryptographicOperations.ZeroMemory(_keyData);
}
// Note actual accurate coefficients would be *0.566 and +57.4
public static int EstimatePkcs8ExportSize(int keySizeBits)
=> ((keySizeBits * 6) / 10) + 150;
}