Skip to content

Commit 44da6c1

Browse files
committed
Add thirdPartyPayment bit to credman
1 parent d2648ee commit 44da6c1

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

fido2/ctap2/credman.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class RESULT(IntEnum):
8383
TOTAL_CREDENTIALS = 0x09
8484
CRED_PROTECT = 0x0A
8585
LARGE_BLOB_KEY = 0x0B
86+
THIRD_PARTY_PAYMENT = 0x0C
8687

8788
@staticmethod
8889
def is_supported(info: Info) -> bool:

tests/device/test_credman.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,18 @@ def test_list_and_delete(client, ctap2, pin_protocol, algorithm):
6161
assert len(rps) == 1
6262

6363
# Not all keys are required in response, but those that are should match
64-
for k, v in rps[0][3].items():
64+
for k, v in rps[0][CredentialManagement.RESULT.RP].items():
6565
assert rp[k] == v
6666

67-
rp_id_hash = rps[0][4]
67+
rp_id_hash = rps[0][CredentialManagement.RESULT.RP_ID_HASH]
6868
creds = credman.enumerate_creds(rp_id_hash)
6969
assert len(creds) == 1
70-
assert creds[0][6] == user
71-
assert creds[0][7]["id"] == cred.credential_id
72-
assert creds[0][8] == cred.public_key
70+
assert creds[0][CredentialManagement.RESULT.USER] == user
71+
assert (
72+
creds[0][CredentialManagement.RESULT.CREDENTIAL_ID]["id"] == cred.credential_id
73+
)
74+
assert creds[0][CredentialManagement.RESULT.PUBLIC_KEY] == cred.public_key
75+
assert not creds[0].get(CredentialManagement.RESULT.THIRD_PARTY_PAYMENT)
7376

7477
credman.delete_cred(creds[0][7])
7578
metadata = credman.get_metadata()
@@ -102,22 +105,22 @@ def test_update(client, ctap2, pin_protocol):
102105

103106
credman = get_credman(ctap2, pin_protocol)
104107
rps = credman.enumerate_rps()
105-
rp_id_hash = rps[0][4]
108+
rp_id_hash = rps[0][CredentialManagement.RESULT.RP_ID_HASH]
106109

107110
# Check user data
108111
creds = credman.enumerate_creds(rp_id_hash)
109112
assert len(creds) == 1
110113

111114
# Authenticators may or may not store name/displayName
112-
stores_name = "name" in creds[0][6]
113-
stores_display_name = "displayName" in creds[0][6]
115+
stores_name = "name" in creds[0][CredentialManagement.RESULT.USER]
116+
stores_display_name = "displayName" in creds[0][CredentialManagement.RESULT.USER]
114117

115118
if not stores_name:
116119
del user["name"]
117120
if not stores_display_name:
118121
del user["displayName"]
119122

120-
assert creds[0][6] == user
123+
assert creds[0][CredentialManagement.RESULT.USER] == user
121124

122125
# Update user data
123126
user2 = {"id": b"user_id"}
@@ -130,16 +133,18 @@ def test_update(client, ctap2, pin_protocol):
130133

131134
creds = credman.enumerate_creds(rp_id_hash)
132135
assert len(creds) == 1
133-
assert creds[0][6] == user2
134-
assert creds[0][7] == cred_id
136+
assert creds[0][CredentialManagement.RESULT.USER] == user2
137+
assert creds[0][CredentialManagement.RESULT.CREDENTIAL_ID] == cred_id
138+
assert not creds[0].get(CredentialManagement.RESULT.THIRD_PARTY_PAYMENT)
135139

136140
# Test deleting fields
137141
user3 = {"id": b"user_id"}
138142
credman.update_user_info(cred_id, user3)
139143
creds = credman.enumerate_creds(rp_id_hash)
140144
assert len(creds) == 1
141-
assert creds[0][6] == user3
142-
assert creds[0][7] == cred_id
145+
assert creds[0][CredentialManagement.RESULT.USER] == user3
146+
assert creds[0][CredentialManagement.RESULT.CREDENTIAL_ID] == cred_id
147+
assert not creds[0].get(CredentialManagement.RESULT.THIRD_PARTY_PAYMENT)
143148

144149
# Clean up
145150
credman.delete_cred(cred_id)

tests/device/test_payment.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
PaymentClientDataCollector,
1212
)
1313
from fido2.server import Fido2Server
14+
from fido2.ctap2.credman import CredentialManagement
15+
from fido2.ctap2.pin import ClientPin
1416

1517
from . import TEST_PIN, CliInteraction
1618

@@ -21,7 +23,7 @@ def preconditions(dev_manager):
2123
pytest.skip("thirdPartyPayment not supported by authenticator")
2224

2325

24-
def test_payment_extension(device, printer):
26+
def test_payment_extension(device, printer, ctap2, pin_protocol):
2527
rp = {"id": "example.com", "name": "Example RP"}
2628
server = Fido2Server(rp)
2729
user = {"id": b"user_id", "name": "A. User"}
@@ -55,6 +57,16 @@ def test_payment_extension(device, printer):
5557

5658
print("Payment credential created!")
5759

60+
# Test flag in Credential Management
61+
token = ClientPin(ctap2, pin_protocol).get_pin_token(
62+
TEST_PIN, ClientPin.PERMISSION.CREDENTIAL_MGMT
63+
)
64+
cm = CredentialManagement(ctap2, pin_protocol, token)
65+
rps = cm.enumerate_rps()
66+
rp_id_hash = rps[0][4]
67+
creds = cm.enumerate_creds(rp_id_hash)
68+
assert creds[0][CredentialManagement.RESULT.THIRD_PARTY_PAYMENT] == True
69+
5870
# Prepare parameters for getAssertion
5971
request_options, state = server.authenticate_begin(
6072
credentials, user_verification="required"

0 commit comments

Comments
 (0)