Pass Span instead of Memory

This commit is contained in:
eelke 2026-02-26 20:39:48 +01:00
parent 650fe99990
commit ccc00d8e80
10 changed files with 45 additions and 38 deletions

View file

@ -11,10 +11,7 @@ namespace IdentityShroud.Api.Tests.Mappers;
public class KeyServiceTests public class KeyServiceTests
{ {
private readonly IDekEncryptionService _dekEncryptionService = EncryptionServiceSubstitute.CreatePassthrough(); private readonly NullDekEncryptionService _dekEncryptionService = new();
//private readonly IDataEncryptionService _dataEncryptionService = Substitute.For<IDataEncryptionService>();
//private readonly IKeyProviderFactory _keyProviderFactory = Substitute.For<IKeyProviderFactory>();
[Fact] [Fact]
public void Test() public void Test()
@ -30,7 +27,7 @@ public class KeyServiceTests
{ {
Id = new("60bb79cf-4bac-4521-87f2-ac87cc15541f"), Id = new("60bb79cf-4bac-4521-87f2-ac87cc15541f"),
KeyType = "RSA", KeyType = "RSA",
Key = new(EncryptionServiceSubstitute.KeyId, rsa.ExportPkcs8PrivateKey()), Key = new(_dekEncryptionService.KeyId, rsa.ExportPkcs8PrivateKey()),
CreatedAt = DateTime.UtcNow, CreatedAt = DateTime.UtcNow,
Priority = 10, Priority = 10,
}; };

View file

@ -1,6 +1,5 @@
using IdentityShroud.Core.Contracts; using IdentityShroud.Core.Contracts;
using IdentityShroud.Core.Model; using IdentityShroud.Core.Model;
using IdentityShroud.Core.Security;
using IdentityShroud.Core.Services; using IdentityShroud.Core.Services;
using IdentityShroud.Core.Tests.Fixtures; using IdentityShroud.Core.Tests.Fixtures;
using IdentityShroud.TestUtils.Substitutes; using IdentityShroud.TestUtils.Substitutes;
@ -11,17 +10,13 @@ namespace IdentityShroud.Core.Tests.Services;
public class ClientServiceTests : IClassFixture<DbFixture> public class ClientServiceTests : IClassFixture<DbFixture>
{ {
private readonly DbFixture _dbFixture; private readonly DbFixture _dbFixture;
//private readonly IDekEncryptionService _dekEncryptionService = EncryptionServiceSubstitute.CreatePassthrough(); private readonly NullDataEncryptionService _dataEncryptionService = new();
private readonly IDataEncryptionService _dataEncryptionService = Substitute.For<IDataEncryptionService>();
private readonly IClock _clock = Substitute.For<IClock>(); private readonly IClock _clock = Substitute.For<IClock>();
private readonly Guid _realmId = new("a1b2c3d4-0000-0000-0000-000000000001"); private readonly Guid _realmId = new("a1b2c3d4-0000-0000-0000-000000000001");
public ClientServiceTests(DbFixture dbFixture) public ClientServiceTests(DbFixture dbFixture)
{ {
_dataEncryptionService.Encrypt(Arg.Any<ReadOnlyMemory<byte>>())
.Returns(x => new EncryptedValue(DekId.NewId(), x.ArgAt<ReadOnlyMemory<byte>>(0).ToArray()));
_dbFixture = dbFixture; _dbFixture = dbFixture;
using Db db = dbFixture.CreateDbContext(); using Db db = dbFixture.CreateDbContext();
if (!db.Database.EnsureCreated()) if (!db.Database.EnsureCreated())

View file

@ -4,6 +4,6 @@ namespace IdentityShroud.Core.Contracts;
public interface IDataEncryptionService public interface IDataEncryptionService
{ {
EncryptedValue Encrypt(ReadOnlyMemory<byte> plain); EncryptedValue Encrypt(ReadOnlySpan<byte> plain);
byte[] Decrypt(EncryptedValue input); byte[] Decrypt(EncryptedValue input);
} }

View file

@ -6,6 +6,6 @@ namespace IdentityShroud.Core.Contracts;
public interface IDekEncryptionService public interface IDekEncryptionService
{ {
EncryptedDek Encrypt(ReadOnlyMemory<byte> plain); EncryptedDek Encrypt(ReadOnlySpan<byte> plain);
byte[] Decrypt(EncryptedDek input); byte[] Decrypt(EncryptedDek input);
} }

View file

@ -12,7 +12,7 @@ public static class Encryption
new(1, 12, 16), // version 1 new(1, 12, 16), // version 1
]; ];
public static byte[] Encrypt(ReadOnlyMemory<byte> plaintext, ReadOnlySpan<byte> key) public static byte[] Encrypt(ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> key)
{ {
const int versionNumber = 1; const int versionNumber = 1;
AlgVersion versionParams = _versions[versionNumber]; AlgVersion versionParams = _versions[versionNumber];
@ -31,7 +31,7 @@ public static class Encryption
// use the spans to place the data directly in its place // use the spans to place the data directly in its place
RandomNumberGenerator.Fill(nonce); RandomNumberGenerator.Fill(nonce);
using var aes = new AesGcm(key, versionParams.TagSize); using var aes = new AesGcm(key, versionParams.TagSize);
aes.Encrypt(nonce, plaintext.Span, cipher, tag); aes.Encrypt(nonce, plaintext, cipher, tag);
return result; return result;
} }

View file

@ -31,7 +31,7 @@ public class DataEncryptionService(
return Encryption.Decrypt(input.Value, key); return Encryption.Decrypt(input.Value, key);
} }
public EncryptedValue Encrypt(ReadOnlyMemory<byte> plain) public EncryptedValue Encrypt(ReadOnlySpan<byte> plain)
{ {
var dek = GetActiveDek(); var dek = GetActiveDek();
var key = dekCryptor.Decrypt(dek.KeyData); var key = dekCryptor.Decrypt(dek.KeyData);

View file

@ -22,7 +22,7 @@ public class DekEncryptionService : IDekEncryptionService
// throw new Exception("Key must be 256bits (32 bytes) for AES256GCM."); // throw new Exception("Key must be 256bits (32 bytes) for AES256GCM.");
} }
public EncryptedDek Encrypt(ReadOnlyMemory<byte> plaintext) public EncryptedDek Encrypt(ReadOnlySpan<byte> plaintext)
{ {
var encryptionKey = ActiveKey; var encryptionKey = ActiveKey;
byte[] cipher = Encryption.Encrypt(plaintext, encryptionKey.Key); byte[] cipher = Encryption.Encrypt(plaintext, encryptionKey.Key);

View file

@ -1,21 +0,0 @@
using IdentityShroud.Core.Contracts;
using IdentityShroud.Core.Security;
namespace IdentityShroud.TestUtils.Substitutes;
public static class EncryptionServiceSubstitute
{
public static KekId KeyId { get; } = KekId.NewId();
public static IDekEncryptionService CreatePassthrough()
{
var encryptionService = Substitute.For<IDekEncryptionService>();
encryptionService
.Encrypt(Arg.Any<ReadOnlyMemory<byte>>())
.Returns(x => new EncryptedDek(KeyId, x.ArgAt<ReadOnlyMemory<byte>>(0).ToArray()));
encryptionService
.Decrypt(Arg.Any<EncryptedDek>())
.Returns(x => x.ArgAt<EncryptedDek>(0).Value);
return encryptionService;
}
}

View file

@ -0,0 +1,18 @@
using IdentityShroud.Core.Contracts;
using IdentityShroud.Core.Security;
namespace IdentityShroud.TestUtils.Substitutes;
public class NullDataEncryptionService : IDataEncryptionService
{
public DekId KeyId { get; } = DekId.NewId();
public EncryptedValue Encrypt(ReadOnlySpan<byte> plain)
{
return new(KeyId, plain.ToArray());
}
public byte[] Decrypt(EncryptedValue input)
{
return input.Value;
}
}

View file

@ -0,0 +1,18 @@
using IdentityShroud.Core.Contracts;
using IdentityShroud.Core.Security;
namespace IdentityShroud.TestUtils.Substitutes;
public class NullDekEncryptionService : IDekEncryptionService
{
public KekId KeyId { get; } = KekId.NewId();
public EncryptedDek Encrypt(ReadOnlySpan<byte> plain)
{
return new(KeyId, plain.ToArray());
}
public byte[] Decrypt(EncryptedDek input)
{
return input.Value;
}
}