-
-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Use multiple yubikeys at same time #503
Changes from 18 commits
dfb673f
7293210
956311f
e5773f6
40e91d7
1670ce8
7622adf
1d4d318
ca0501c
15aa12c
00c1194
f68ec8f
24738ca
0c990d3
d84c53d
84c8b56
dde9b7b
f283f7b
d355f96
7ed01c1
ad6bbfd
fc7b990
ed16878
738d6af
a956c1b
93d6129
d61cfae
35284ad
c9dbac7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,27 +146,35 @@ def yubikey_signature_provider(name, key_id, key, data): # pylint: disable=W061 | |
|
||
def _check_key_and_get_pin(expected_key_id): | ||
try: | ||
inserted_key = yk.get_piv_public_key_tuf() | ||
if expected_key_id != inserted_key["keyid"]: | ||
return None | ||
serial_num = yk.get_serial_num(inserted_key) | ||
pin = yk.get_key_pin(serial_num) | ||
yubikey_count = yk.check_yubikey_count() | ||
if yubikey_count < 2: | ||
inserted_key = yk.get_piv_public_key_tuf() | ||
if expected_key_id != inserted_key["keyid"]: | ||
return None, None | ||
serial = yk.get_serial_num(inserted_key) | ||
else: | ||
print(f"Final confirmation for {name} key") | ||
serial = yk.verify_yubikey_serial() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am currently unable to test this since I am not able to insert two yubikeys at the same time, but based on the code, it looks like you have to manually enter each of the yubikey's serial number. This is probably less user-friendly compared to having to remove and insert the devices. A bigger issue, however, is that we want to be able to sign metadata using YubiKeys plugged into our server. So, this should iterate over all inserted YubiKeys and simply try to sign using all of them, instead of asking for any input. So, let's say that you have timestamp and snapshot keys inserted and you need to sign timestamp metadata. We need to automatically detect the key that can sign the timestamp metadata. At the moment, the user will have to enter pins too, but we don't need to address that in this PR. |
||
inserted_key = yk.get_piv_public_key_tuf(serial=serial) | ||
if expected_key_id != inserted_key["keyid"]: | ||
return None, None | ||
pin = yk.get_key_pin(serial) | ||
if pin is None: | ||
pin = yk.get_and_validate_pin(name) | ||
return pin | ||
pin = yk.get_and_validate_pin(name, serial=serial) | ||
return pin, serial | ||
except Exception: | ||
return None | ||
return None, None | ||
|
||
while True: | ||
# check if the needed YubiKey is inserted before asking the user to do so | ||
# this allows us to use this signature provider inside an automated process | ||
# assuming that all YubiKeys needed for signing are inserted | ||
pin = _check_key_and_get_pin(key_id) | ||
if pin is not None: | ||
pin, serial = _check_key_and_get_pin(key_id) | ||
if pin is not None and serial is not None: | ||
break | ||
input(f"\nInsert {name} and press enter") | ||
|
||
signature = yk.sign_piv_rsa_pkcs1v15(data, pin) | ||
signature = yk.sign_piv_rsa_pkcs1v15(data, pin, serial=serial) | ||
return {"keyid": key_id, "sig": hexlify(signature).decode()} | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember having to build pyscard from source a while back, but at some point, it was no longer necessary. If this is a temporary workaround, please create an issue and provide some details, so that we don't forget about it.