Skip to content

Commit e8e8f39

Browse files
committed
Fix another case of RK overwrite statekeeping loss
Fixes #50 (for real this time)
1 parent 1f6483c commit e8e8f39

2 files changed

Lines changed: 53 additions & 3 deletions

File tree

python_tests/ctap/test_cred_mgmt.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,53 @@ def test_rk_overwrite(self):
199199

200200
creds = cm.enumerate_creds(rp_id_hash=self.rp_id_hash(self.rp_id))
201201
self.assertEqual(1, len(creds))
202+
203+
def test_rk_overwrite_multiple_creds(self):
204+
pin_client = self.get_high_level_client(user_interaction=FixedPinUserInteraction(self.pin))
205+
self.basic_makecred_params['options'] = {
206+
'rk': True
207+
}
208+
209+
cm = self.get_credential_management()
210+
211+
user_id_1 = secrets.token_bytes(30)
212+
user_id_2 = secrets.token_bytes(30)
213+
214+
res_1 = pin_client.make_credential(
215+
self.get_high_level_make_cred_options(
216+
ResidentKeyRequirement.REQUIRED, user_id=user_id_1
217+
)
218+
)
219+
220+
rps = cm.enumerate_rps()
221+
self.assertEqual(1, len(rps))
222+
creds = cm.enumerate_creds(rp_id_hash=self.rp_id_hash(self.rp_id))
223+
self.assertEqual(1, len(creds))
224+
225+
pin_client.make_credential(
226+
self.get_high_level_make_cred_options(
227+
ResidentKeyRequirement.REQUIRED, user_id=user_id_2
228+
)
229+
)
230+
rps = cm.enumerate_rps()
231+
self.assertEqual(1, len(rps))
232+
creds = cm.enumerate_creds(rp_id_hash=self.rp_id_hash(self.rp_id))
233+
self.assertEqual(2, len(creds))
234+
235+
pin_client.get_assertion(self.get_high_level_assertion_opts_from_cred(cred=res_1, rp_id=self.rp_id))
236+
237+
rps = cm.enumerate_rps()
238+
self.assertEqual(1, len(rps))
239+
creds = cm.enumerate_creds(rp_id_hash=self.rp_id_hash(self.rp_id))
240+
self.assertEqual(2, len(creds))
241+
242+
pin_client.make_credential(
243+
self.get_high_level_make_cred_options(
244+
ResidentKeyRequirement.REQUIRED, user_id=user_id_1
245+
)
246+
)
247+
248+
rps = cm.enumerate_rps()
249+
self.assertEqual(1, len(rps))
250+
creds = cm.enumerate_creds(rp_id_hash=self.rp_id_hash(self.rp_id))
251+
self.assertEqual(2, len(creds))

src/main/java/us/q3q/fido2/FIDO2Applet.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public final class FIDO2Applet extends Applet implements ExtendedLength {
1414
/**
1515
* The version of this applet in use
1616
*/
17-
private static final byte FIRMWARE_VERSION = 0x06;
17+
private static final byte FIRMWARE_VERSION = 0x07;
1818

1919
/**
2020
* The AID to which this applet should respond (ignoring any other AIDs sent to it)
@@ -1056,15 +1056,15 @@ private void makeCredential(APDU apdu, short lc, byte[] buffer) {
10561056
}
10571057
} else {
10581058
// Found a matching RK - overwrite it
1059+
uniqueRP = residentKeys[targetRKSlot].isUniqueRP();
1060+
10591061
if (targetRKSlot < (short) (numResidentCredentials - 1)) {
10601062
// We need to put the credential at the end of the list so it's still the "most recent" one
10611063
for (short i = targetRKSlot; i < (short) (numResidentCredentials - 1); i++) {
10621064
residentKeys[i] = residentKeys[(short) (i + 1)];
10631065
}
10641066
targetRKSlot = (short) (numResidentCredentials - 1);
10651067
}
1066-
1067-
uniqueRP = residentKeys[targetRKSlot].isUniqueRP();
10681068
}
10691069

10701070
byte effectiveCredBlobLen = credBlobLen;

0 commit comments

Comments
 (0)