Skip to content

Commit 2705379

Browse files
committed
tests: PivSessionIntegrationTestBase.cs can now manage Fips credentials
1 parent 78b1f2c commit 2705379

File tree

5 files changed

+97
-34
lines changed

5 files changed

+97
-34
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,20 @@ public void Attest_Imported_ThrowsException(
5151
Session.CreateAttestationStatement(PivSlot.Retired1));
5252
}
5353

54-
[Theory]
54+
[SkippableTheory(typeof(DeviceNotFoundException))]
5555
[InlineData(KeyType.RSA2048, StandardTestDevice.Fw5)]
5656
[InlineData(KeyType.RSA3072, StandardTestDevice.Fw5)]
5757
[InlineData(KeyType.RSA4096, StandardTestDevice.Fw5)]
58-
[InlineData(KeyType.ECP256, StandardTestDevice.Fw5)]
58+
[InlineData(KeyType.ECP256, StandardTestDevice.Fw5Fips)]
5959
[InlineData(KeyType.Ed25519, StandardTestDevice.Fw5)]
6060
public void AttestGenerated(
6161
KeyType keyType,
6262
StandardTestDevice deviceType)
6363
{
6464
TestDeviceType = deviceType;
6565
const byte slotNumber = PivSlot.Retired1;
66-
Session.GenerateKeyPair(slotNumber, keyType, PivPinPolicy.Never, PivTouchPolicy.Never);
66+
67+
Session.GenerateKeyPair(slotNumber, keyType);
6768

6869
// If this test fails, it's possible the attestation key or cert is missing or broken.
6970
// In that case, run LoadAttestationPair(KeyType, true) to fix the problem.

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

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
using System;
16+
using System.Diagnostics;
1617
using Xunit;
1718
using Yubico.YubiKey.Cryptography;
1819
using Yubico.YubiKey.Scp;
@@ -34,23 +35,51 @@ public class PivSessionIntegrationTestBase : IDisposable
3435
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
3536
};
3637

38+
public static readonly byte[] ComplexManagementKey =
39+
{
40+
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
41+
0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x12,
42+
0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9A
43+
};
44+
45+
// public void SetFipsApprovedCredentials(PivSession? session)
46+
// {
47+
// session ??= Session;
48+
// session.TryChangePin(DefaultPin, ComplexPin, out _);
49+
// session.TryChangePuk(DefaultPuk, ComplexPuk, out _);
50+
// session.TryChangeManagementKey(DefaultManagementKey, ComplexManagementKey, PivTouchPolicy.Always);
51+
// Assert.True(session.TryVerifyPin(ComplexPin, out _));
52+
// }
53+
54+
// public void SetFipsApprovedCredentials(
55+
// IYubiKeyDevice? device,
56+
// ScpKeyParameters parameters)
57+
// {
58+
// device ??= Device;
59+
// using var session = new PivSession(device, parameters);
60+
// SetFipsApprovedCredentials(session);
61+
// }
62+
3763
protected KeyType DefaultManagementKeyType =>
3864
Device.FirmwareVersion > FirmwareVersion.V5_7_0 ? KeyType.AES192 : KeyType.TripleDES;
3965

40-
protected StandardTestDevice TestDeviceType { get; set; } = StandardTestDevice.Fw5;
41-
66+
protected StandardTestDevice TestDeviceType { get; set; } = StandardTestDevice.Any;
67+
4268
/// <summary>
4369
/// Returns an authenticated PivSession.
4470
/// </summary>
4571
protected PivSession Session => _session ??= GetSession(true);
72+
4673
protected IYubiKeyDevice Device => IntegrationTestDeviceEnumeration.GetTestDevice(TestDeviceType);
4774

4875
private bool _disposed;
4976
private PivSession? _session;
5077

78+
private bool UseComplexCreds => Device.IsFipsSeries || Device.IsPinComplexityEnabled;
79+
5180
protected PivSessionIntegrationTestBase()
5281
{
53-
using var session = GetSessionInternal(Device, false);
82+
using var session = GetSessionInternal(Device, false, false);
5483
session.ResetApplication();
5584
}
5685

@@ -60,10 +89,11 @@ protected PivSessionIntegrationTestBase()
6089
}
6190

6291
protected PivSession GetSession(
63-
bool authenticate = false) => GetSessionInternal(Device, authenticate);
92+
bool authenticate = false) => GetSessionInternal(Device, authenticate, UseComplexCreds);
6493

6594
protected PivSession GetSessionScp(
66-
bool authenticate = false) => GetSessionInternal(Device, authenticate, Scp03KeyParameters.DefaultKey);
95+
bool authenticate = false) =>
96+
GetSessionInternal(Device, authenticate, UseComplexCreds, Scp03KeyParameters.DefaultKey);
6797

6898
public void Dispose()
6999
{
@@ -91,30 +121,41 @@ protected virtual void Dispose(
91121
private static PivSession GetSessionInternal(
92122
IYubiKeyDevice testDevice,
93123
bool authenticate,
124+
bool useComplexCreds,
94125
Scp03KeyParameters? keyParameters = null)
95126
{
96127
Assert.True(testDevice.EnabledUsbCapabilities.HasFlag(YubiKeyCapabilities.Piv));
97128

98-
PivSession? pivSession = null;
129+
PivSession? session = null;
99130
try
100131
{
101-
pivSession = new PivSession(testDevice, keyParameters);
102-
if (pivSession.KeyCollector == null)
132+
session = new PivSession(testDevice, keyParameters);
133+
134+
if (useComplexCreds)
135+
{
136+
session.TryChangePin(DefaultPin, ComplexPin, out _);
137+
session.TryChangePuk(DefaultPuk, ComplexPuk, out _);
138+
var managementKeyChanged = session.TryChangeManagementKey(DefaultManagementKey, ComplexManagementKey);
139+
Debug.Assert(managementKeyChanged, "Failed to change management");
140+
Assert.True(session.TryVerifyPin(ComplexPin, out _));
141+
}
142+
143+
if (session.KeyCollector == null)
103144
{
104-
var collectorObj = new Simple39KeyCollector();
105-
pivSession.KeyCollector = collectorObj.Simple39KeyCollectorDelegate;
145+
var collectorObj = new Simple39KeyCollector(false, useComplexCreds);
146+
session.KeyCollector = collectorObj.Simple39KeyCollectorDelegate;
106147
}
107148

108149
if (authenticate)
109150
{
110-
pivSession.AuthenticateManagementKey();
151+
session.AuthenticateManagementKey();
111152
}
112153

113-
return pivSession;
154+
return session;
114155
}
115156
catch
116157
{
117-
pivSession?.Dispose();
158+
session?.Dispose();
118159
throw;
119160
}
120161
}

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

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,21 @@ namespace Yubico.YubiKey.Piv
2424
public class Simple39KeyCollector
2525
{
2626
private static bool _setKeyFlagOnChange;
27+
public static bool _useComplexCreds;
2728

2829
// If the caller sets the input arg to true, then when the call asks for
2930
// Change, return the old and new, then set KeyFlag to the opposite of
3031
// what it currently is.
3132
// For false, then this returns old and new, but does nothing to KeyFlag.
3233
// If there is no arg, that's false.
33-
public Simple39KeyCollector(bool setKeyFlagOnChange = false)
34+
public Simple39KeyCollector(
35+
bool setKeyFlagOnChange = false,
36+
bool useComplexCreds = false)
3437
{
3538
KeyFlag = 0;
3639
RetryFlag = 0;
3740
_setKeyFlagOnChange = setKeyFlagOnChange;
41+
_useComplexCreds = useComplexCreds;
3842
}
3943

4044
// If KeyFlag is set to 0, the current PIN, PUK, or key returned will be
@@ -50,10 +54,11 @@ public Simple39KeyCollector(bool setKeyFlagOnChange = false)
5054
// PUK. This way we can block the PIN or PUK for testing purposes.
5155
public int RetryFlag { get; set; }
5256

53-
public bool Simple39KeyCollectorDelegate(KeyEntryData keyEntryData)
57+
public bool Simple39KeyCollectorDelegate(
58+
KeyEntryData keyEntryData)
5459
{
55-
if (keyEntryData.IsRetry &&
56-
RetryFlag == 0 &&
60+
if (keyEntryData.IsRetry &&
61+
RetryFlag == 0 &&
5762
keyEntryData.RetriesRemaining is not null &&
5863
keyEntryData.RetriesRemaining == 1)
5964
{
@@ -70,28 +75,27 @@ keyEntryData.RetriesRemaining is not null &&
7075
return false;
7176

7277
case KeyEntryRequest.Release:
73-
7478
return true;
7579

7680
case KeyEntryRequest.VerifyPivPin:
77-
currentValue = CollectPin();
81+
currentValue = CollectPin(_useComplexCreds);
7882
break;
7983

8084
case KeyEntryRequest.ChangePivPin:
81-
currentValue = CollectPin();
82-
newValue = CollectPin();
85+
currentValue = CollectPin(_useComplexCreds);
86+
newValue = CollectPin(_useComplexCreds);
8387
isChange = true;
8488
break;
8589

8690
case KeyEntryRequest.ChangePivPuk:
87-
currentValue = CollectPuk();
88-
newValue = CollectPuk();
91+
currentValue = CollectPuk(_useComplexCreds);
92+
newValue = CollectPuk(_useComplexCreds);
8993
isChange = true;
9094
break;
9195

9296
case KeyEntryRequest.ResetPivPinWithPuk:
93-
currentValue = CollectPuk();
94-
newValue = CollectPin();
97+
currentValue = CollectPuk(_useComplexCreds);
98+
newValue = CollectPin(_useComplexCreds);
9599
isChange = true;
96100
break;
97101

@@ -101,7 +105,7 @@ keyEntryData.RetriesRemaining is not null &&
101105
return false;
102106
}
103107

104-
currentValue = CollectMgmtKey();
108+
currentValue = CollectMgmtKey(_useComplexCreds);
105109
break;
106110

107111
case KeyEntryRequest.ChangePivManagementKey:
@@ -110,8 +114,8 @@ keyEntryData.RetriesRemaining is not null &&
110114
return false;
111115
}
112116

113-
currentValue = CollectMgmtKey();
114-
newValue = CollectMgmtKey();
117+
currentValue = CollectMgmtKey(_useComplexCreds);
118+
newValue = CollectMgmtKey(_useComplexCreds);
115119
isChange = true;
116120
break;
117121
}
@@ -147,8 +151,19 @@ keyEntryData.RetriesRemaining is not null &&
147151
return true;
148152
}
149153

150-
public static Memory<byte> CollectPin() => PivSessionIntegrationTestBase.DefaultPin;
151-
public static Memory<byte> CollectPuk() => PivSessionIntegrationTestBase.DefaultPuk;
152-
public static Memory<byte> CollectMgmtKey() => PivSessionIntegrationTestBase.DefaultManagementKey;
154+
public static Memory<byte> CollectPin(
155+
bool useComplex) => useComplex
156+
? PivSessionIntegrationTestBase.ComplexPin
157+
: PivSessionIntegrationTestBase.DefaultPin;
158+
159+
public static Memory<byte> CollectPuk(
160+
bool useComplex) => useComplex
161+
? PivSessionIntegrationTestBase.ComplexPuk
162+
: PivSessionIntegrationTestBase.DefaultPuk;
163+
164+
public static Memory<byte> CollectMgmtKey(
165+
bool useComplex) => useComplex
166+
? PivSessionIntegrationTestBase.ComplexManagementKey
167+
: PivSessionIntegrationTestBase.DefaultManagementKey;
153168
}
154169
}

Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/StandardTestDevice.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ namespace Yubico.YubiKey.TestUtilities
1616
{
1717
public enum StandardTestDevice
1818
{
19+
/// <summary>
20+
/// Any version
21+
/// </summary>
22+
Any,
23+
1924
/// <summary>
2025
/// Major version 3, USB A keychain, not FIPS
2126
/// </summary>

Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/TestDeviceSelection.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public static IYubiKeyDevice SelectByStandardTestDevice(
9090
StandardTestDevice.Fw5 => SelectDevice(5),
9191
StandardTestDevice.Fw5Fips => SelectDevice(5, isFipsSeries: true),
9292
StandardTestDevice.Fw5Bio => SelectDevice(5, [FormFactor.UsbCBiometricKeychain, FormFactor.UsbABiometricKeychain]),
93+
StandardTestDevice.Any => devices.First(),
9394
_ => throw new ArgumentException("Invalid test device value.", nameof(testDeviceType)),
9495
};
9596

0 commit comments

Comments
 (0)