Skip to content

Commit 96196da

Browse files
committed
tests: Fix PinOnlyWithResetTests.cs for devices gt v5.7
1 parent 32256bf commit 96196da

File tree

1 file changed

+63
-34
lines changed

1 file changed

+63
-34
lines changed

Yubico.YubiKey/tests/integration/Yubico/YubiKey/Piv/PinOnlyWithResetTests.cs

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222

2323
namespace Yubico.YubiKey.Piv
2424
{
25-
// All these tests will reset the PIV application, run, then reset the PIV
26-
// application again.
2725
// All these tests will also use a random number generator with a specified
2826
// set of bytes, followed by 2048 random bytes. If you want to get only
2927
// random bytes, skip the first SpecifiedStart bytes (get a random object and
@@ -33,20 +31,51 @@ public class PinOnlyWithResetTests : PivSessionIntegrationTestBase
3331
{
3432
private const int SpecifiedStart = 72;
3533
private const int RandomTrailingCount = 2048;
36-
readonly RandomObjectUtility replacement;
37-
readonly private byte[] specifiedBytes;
34+
readonly RandomObjectUtility _partiallyRandomGenerator;
35+
36+
private Span<byte> GetTripleDesKey_Strong_PrecomputedRandomBytes() => new byte[]
37+
{
38+
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B,
39+
0x05, 0x01, 0xC9, 0x5E, 0x72, 0xAB, 0x58, 0x9E,
40+
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B,
41+
};
42+
43+
private Span<byte> GetTripleDesKey_Weak_PrecomputedRandomBytes() => new byte[]
44+
{
45+
0x05, 0x01, 0xC9, 0x5E, 0x72, 0xAB, 0x58, 0x9E,
46+
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B,
47+
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B
48+
};
49+
50+
// 3DES key that is derived using a PIN of "123456" and a salt of the first 16 bytes.
51+
private Span<byte> Get_DerivedKey_PrecomputedRandomBytes() => new byte[]
52+
{
53+
0xc9, 0xf4, 0x20, 0x5a, 0x29, 0x38, 0x1b, 0xb8,
54+
0x60, 0x6b, 0xd4, 0xde, 0x18, 0xef, 0xf4, 0x3d,
55+
0x43, 0x24, 0x87, 0x3e, 0x5e, 0xd2, 0xc1, 0xed
56+
};
57+
58+
// Same as the weak 3DES key, but since it's AES it is allowed and not considered weak
59+
private Span<byte> GetAesKey_PrecomputedRandomBytes() => new byte[]
60+
{
61+
0x05, 0x01, 0xC9, 0x5E, 0x72, 0xAB, 0x58, 0x9E,
62+
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B,
63+
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B
64+
};
65+
66+
private Span<byte> GetSalt_PrecomputedRandomBytes() => new byte[]
67+
{
68+
0x05, 0x01, 0xC9, 0x5E, 0x72, 0xAB, 0x58, 0x9E,
69+
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B
70+
};
3871

3972
public PinOnlyWithResetTests()
4073
{
74+
// The data in this array correspond to the getter fields above (Span<byte> Get_XXX_PrecomputedRandomBytes).
4175
// This buffer will hold the random bytes to return.
42-
// The first 24 will be a weak 3DES key
43-
// The first 16 can also be a salt.
44-
// The second 24 will be a non-weak 3DES key.
45-
// The third 24 bytes is the 3DES key that is derived using a PIN of
46-
// "123456" and a salt of the first 16 bytes.
4776
// Then there will be 2048 random bytes.
48-
specifiedBytes =
49-
[
77+
byte[] predefinedPrefixedBytes =
78+
[
5079
0x05, 0x01, 0xC9, 0x5E, 0x72, 0xAB, 0x58, 0x9E,
5180
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B,
5281
0x6D, 0x82, 0x95, 0xA3, 0x74, 0xB7, 0x69, 0x2B,
@@ -59,11 +88,12 @@ public PinOnlyWithResetTests()
5988
];
6089

6190
var randomBytes = new byte[SpecifiedStart + RandomTrailingCount];
62-
using var random = RandomObjectUtility.GetRandomObject(null);
91+
using var random = RandomNumberGenerator.Create();
6392
random.GetBytes(randomBytes);
6493

65-
Array.Copy(specifiedBytes, 0, randomBytes, 0, specifiedBytes.Length);
66-
replacement = RandomObjectUtility.SetRandomProviderFixedBytes(randomBytes);
94+
// Set the first 72 bytes with the predefined prefixed bytes so that we can anticipate the values in the tests.
95+
predefinedPrefixedBytes.CopyTo(randomBytes.AsSpan());
96+
_partiallyRandomGenerator = RandomObjectUtility.SetRandomProviderFixedBytes(randomBytes);
6797
}
6898

6999
[Fact]
@@ -120,7 +150,7 @@ public void Run_SetPinDerived_UsesSalt()
120150
var adminData = Session.ReadObject<AdminData>();
121151
Assert.NotNull(adminData.Salt);
122152

123-
var expected = GetSpecifiedSpan(0, 16);
153+
var expected = GetSalt_PrecomputedRandomBytes();
124154
var result = (ReadOnlyMemory<byte>)adminData.Salt;
125155
var isValid = expected.SequenceEqual(result.Span);
126156
Assert.True(isValid);
@@ -196,34 +226,36 @@ public void SetProtectThenDerive_GetMode_ReturnsCorrect()
196226
[Fact]
197227
public void SetProtectThenDerive_CorrectMgmtKey()
198228
{
199-
var expected1 = GetSpecifiedSpan(24, 24);
200-
var expected2 = GetSpecifiedSpan(48, 24);
229+
var expectedManagementKey = DefaultManagementKeyType == KeyType.AES192
230+
? GetAesKey_PrecomputedRandomBytes()
231+
: GetTripleDesKey_Strong_PrecomputedRandomBytes();
232+
233+
var expectedRandomDerivedKey = Get_DerivedKey_PrecomputedRandomBytes();
201234
using (var pivSession = GetSession())
202235
{
203236
// Act
204237
pivSession.SetPinOnlyMode(PivPinOnlyMode.PinProtected);
205238

239+
// Assert
206240
var pinProtect = pivSession.ReadObject<PinProtectedData>();
207-
Assert.False(pinProtect.IsEmpty);
208241
Assert.NotNull(pinProtect.ManagementKey);
209-
var result = (ReadOnlyMemory<byte>)pinProtect.ManagementKey;
210-
var isValid = expected1.SequenceEqual(result.Span);
242+
var isValid = expectedManagementKey.SequenceEqual(pinProtect.ManagementKey.Value.Span);
211243
Assert.True(isValid);
212244
}
213245

214246
using (var pivSession = GetSession())
215247
{
216248
// Act
217-
pivSession.SetPinOnlyMode(PivPinOnlyMode.PinDerived);
218-
249+
pivSession.SetPinOnlyMode(PivPinOnlyMode
250+
.PinDerived);
219251
var mode = pivSession.GetPinOnlyMode();
220252
Assert.Equal(PivPinOnlyMode.PinProtected | PivPinOnlyMode.PinDerived, mode);
221253

222254
var pinProtect = pivSession.ReadObject<PinProtectedData>();
223255
Assert.False(pinProtect.IsEmpty);
224256
Assert.NotNull(pinProtect.ManagementKey);
225-
var result = (ReadOnlyMemory<byte>)pinProtect.ManagementKey;
226-
var isValid = expected2.SequenceEqual(result.Span);
257+
var result = pinProtect.ManagementKey;
258+
var isValid = expectedRandomDerivedKey.SequenceEqual(result.Value!.Span);
227259
Assert.True(isValid);
228260
}
229261
}
@@ -232,7 +264,9 @@ public void SetProtectThenDerive_CorrectMgmtKey()
232264
public void SetProtect_ThenNone_CorrectMode()
233265
{
234266
// Arrange
235-
var mgmtKey = GetSpecifiedSpan(24, 24);
267+
var expectedManagementKey = DefaultManagementKeyType == KeyType.AES192
268+
? GetAesKey_PrecomputedRandomBytes()
269+
: GetTripleDesKey_Strong_PrecomputedRandomBytes();
236270
using (var pivSession = GetSession())
237271
{
238272
// Act
@@ -242,8 +276,8 @@ public void SetProtect_ThenNone_CorrectMode()
242276
var pinProtect = pivSession.ReadObject<PinProtectedData>();
243277
Assert.False(pinProtect.IsEmpty);
244278
Assert.NotNull(pinProtect.ManagementKey);
245-
// var isValid = mgmtKey.SequenceEqual(pinProtect.ManagementKey.Value.Span);
246-
// Assert.True(isValid);
279+
var isValid = expectedManagementKey.SequenceEqual(pinProtect.ManagementKey.Value.Span);
280+
Assert.True(isValid);
247281
}
248282

249283
var isBlocked = IsPukBlocked();
@@ -273,7 +307,7 @@ public void SetProtect_ThenNone_CorrectMode()
273307
var specifiedCollector = new SpecifiedKeyCollector(
274308
DefaultPin,
275309
DefaultPuk,
276-
mgmtKey.ToArray());
310+
expectedManagementKey.ToArray());
277311
pivSession.KeyCollector = specifiedCollector.SpecifiedKeyCollectorDelegate;
278312

279313
var mode = pivSession.GetPinOnlyMode();
@@ -541,11 +575,6 @@ public void SetPinOnly_ThenNone_Success(
541575
}
542576
}
543577

544-
private Span<byte> GetSpecifiedSpan(
545-
int offset,
546-
int length) =>
547-
specifiedBytes.AsSpan(offset, length);
548-
549578
// If the PUK is blocked, return true.
550579
// If the PUK is not blocked, return false.
551580
// If there is any other error, throw an exception.
@@ -576,7 +605,7 @@ protected override void Dispose(
576605
{
577606
if (disposing)
578607
{
579-
replacement.RestoreRandomProvider();
608+
_partiallyRandomGenerator.RestoreRandomProvider();
580609
}
581610

582611
base.Dispose(disposing);

0 commit comments

Comments
 (0)