Skip to content

Commit 933ab6d

Browse files
committed
refactor: change zeroMemoryHandle to work with Memory<byte>
1 parent 9c0008c commit 933ab6d

File tree

4 files changed

+16
-58
lines changed

4 files changed

+16
-58
lines changed

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyEncoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ private static byte[] EncodeECKey(
190190
writer.PopSequence();
191191

192192
// PrivateKey as OCTET STRING
193-
writer.WriteOctetString(ecPrivateKeyHandle.Data);
193+
writer.WriteOctetString(ecPrivateKeyHandle.Data.Span);
194194
writer.PopSequence();
195195

196196
return writer.Encode();
@@ -237,7 +237,7 @@ private static byte[] EncodeCurve25519Key(ReadOnlySpan<byte> privateKey, string
237237
privateKeyWriter.WriteOctetString(privateKey);
238238

239239
using var privateKeyBytesHandle = new ZeroingMemoryHandle(privateKeyWriter.Encode());
240-
writer.WriteOctetString(privateKeyBytesHandle.Data);
240+
writer.WriteOctetString(privateKeyBytesHandle.Data.Span);
241241

242242
// End PrivateKeyInfo SEQUENCE
243243
writer.PopSequence();

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/ZeroingMemoryHandle.cs

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,76 +13,34 @@
1313
// limitations under the License.
1414

1515
using System;
16-
using System.Collections;
17-
using System.Collections.Generic;
1816
using System.Security.Cryptography;
1917

2018
namespace Yubico.YubiKey.Cryptography;
2119

22-
#pragma warning disable CA1710
23-
internal class ZeroingMemoryHandle : IDisposable, IReadOnlyCollection<byte>, IEnumerable<byte>
24-
#pragma warning restore CA1710
20+
internal class ZeroingMemoryHandle : IDisposable
2521
{
26-
private readonly byte[] _data;
22+
private readonly Memory<byte> _data;
2723
private bool _disposed;
28-
2924
public int Length => _disposed ? 0 : _data.Length;
30-
public int Count => Length; // For IReadOnlyCollection
31-
32-
public byte this[int index] => _disposed
33-
? throw new ObjectDisposedException(nameof(ZeroingMemoryHandle))
34-
: _data[index];
25+
public int Count => Length;
3526

36-
public ZeroingMemoryHandle(byte[] data)
27+
public ZeroingMemoryHandle(Memory<byte> data)
3728
{
38-
_data = data ?? throw new ArgumentNullException(nameof(data));
29+
_data = data;
3930
}
4031

41-
public ReadOnlySpan<byte> AsSpan() => _disposed
42-
? ReadOnlySpan<byte>.Empty
43-
: _data.AsSpan();
44-
45-
public byte[] Data => _disposed
32+
public Memory<byte> Data => _disposed
4633
? throw new ObjectDisposedException(nameof(ZeroingMemoryHandle))
4734
: _data;
48-
49-
public void CopyTo(byte[] destination, int destinationIndex = 0)
50-
{
51-
if (_disposed)
52-
{
53-
throw new ObjectDisposedException(nameof(ZeroingMemoryHandle));
54-
}
55-
56-
Buffer.BlockCopy(_data, 0, destination, destinationIndex, _data.Length);
57-
}
58-
59-
public ReadOnlySpan<byte> Slice(int start, int length) => _disposed
60-
? ReadOnlySpan<byte>.Empty
61-
: _data.AsSpan(start, length);
62-
63-
public IEnumerator<byte> GetEnumerator()
64-
{
65-
if (_disposed)
66-
{
67-
throw new ObjectDisposedException(nameof(ZeroingMemoryHandle));
68-
}
69-
70-
for (int i = 0; i < _data.Length; i++)
71-
{
72-
yield return _data[i];
73-
}
74-
}
75-
76-
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
77-
35+
7836
public void Dispose()
7937
{
8038
if (_disposed)
8139
{
8240
return;
8341
}
8442

85-
CryptographicOperations.ZeroMemory(_data);
43+
CryptographicOperations.ZeroMemory(_data.Span);
8644
_disposed = true;
8745
GC.SuppressFinalize(this);
8846
}

Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.KeyPairs.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,9 @@ public void ImportPrivateKey(
400400

401401
RefreshManagementKeyAuthentication();
402402

403-
var pivEncodedKey = privateKey.EncodeAsPiv();
403+
using var pivEncodedKeyHandle = new ZeroingMemoryHandle(privateKey.EncodeAsPiv());
404404
var command = new ImportAsymmetricKeyCommand(
405-
pivEncodedKey,
405+
pivEncodedKeyHandle.Data,
406406
privateKey.KeyType,
407407
slotNumber,
408408
pinPolicy,

Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ZeroingMemoryHandleTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void NestedUsage_ZeroesAllArraysWhenDisposed()
6565
// Simulate combining key and IV for an operation
6666
for (int i = 0; i < 5; i++)
6767
{
68-
resultData[i] = (byte)(keyHandle.Data[i] ^ ivHandle.Data[i]);
68+
resultData[i] = (byte)(keyHandle.Data.Span[i] ^ ivHandle.Data.Span[i]);
6969
}
7070
}
7171

@@ -148,14 +148,14 @@ public void MultiLayerComponent_MaintainsSecurityThroughLayers()
148148
Assert.All(sensitiveData, b => Assert.Equal(0, b));
149149
}
150150

151-
// Mock processors for testing
151+
// Mock processors for testing
152152
private static class FirstLayerProcessor
153153
{
154154
public static byte[] Process(ZeroingMemoryHandle handle)
155155
{
156156
// Simulate processing
157157
var result = new byte[handle.Data.Length];
158-
Buffer.BlockCopy(handle.Data, 0, result, 0, handle.Data.Length);
158+
handle.Data.CopyTo(result);
159159
return result;
160160
}
161161
}
@@ -167,7 +167,7 @@ public static byte[] Process(ZeroingMemoryHandle originalHandle, byte[] intermed
167167
// Simulate more processing
168168
for (int i = 0; i < originalHandle.Data.Length; i++)
169169
{
170-
intermediateResult[i] ^= originalHandle.Data[i];
170+
intermediateResult[i] ^= originalHandle.Data.Span[i];
171171
}
172172
return intermediateResult;
173173
}

0 commit comments

Comments
 (0)