BryanJacobs / fido2-hid-bridge

HID -> PC/SC Bridge for FIDO2 Device Use
MIT License
24 stars 6 forks source link

Bridge (or card?) not working anymore #7

Closed equaeghe closed 6 months ago

equaeghe commented 7 months ago

In September, I had installed and setup this bridge for use with my Badgeo FIDO2 card. It had been working quite nicely from within Firefox on Linux. Namely, I used it for 2FA on Github, Gitlab, dropbox, etc. Only for Microsoft services (Office 365) I got an error.

A few months ago (January, I think), Github stopped working in the sense that I could register the card as a 2FA device, but it gave an error on login. At that point Gitlab and Dropbox were still working. Recently, also Gitlab and Dropbox stopped working in the same way Github did: registration of the card as a 2FA device works, but I get an error on usage. (Gitlab says There was a problem communicating with your device. (NotAllowedError).)

I updated the bridge to the latest revision today, but the issue persists. I'm assuming this means either the websites or Firefox (currently at 124.0) changed in a way that make the setup break. I do not know whether this bridge is in any way involved, but I would like to investigate that. Any help is appreciated.

equaeghe commented 7 months ago

After I typed the above message, I remembered that the card also has NFC connectivity and that I had used it successfully as such once on my phone. So I tried that again. That works, also with the earlier failing Github, which suggests it is not an issue of the websites I try to login to. So it seems there is an issue with the bridge and/or Firefox on my laptop.

BryanJacobs commented 7 months ago

I just tested with Firefox 123.0.1 on Linux and a Github passkey (not "security key" - "passkey"). Worked fine. There don't seem to be any related changes in Firefox 124.

If you're having trouble, please attach debug output from the script including the CTAP commands/responses.

equaeghe commented 7 months ago

The following is the debug output when trying to login to a Gitlab instance (card used as security key). The bridge was started with sudo -E .venv/bin/fido2-hid-bridge. I've now tried both Firefox and a Chromium-based browser, Falkon.

Failure with Firefox

INFO:UHIDDevice:initializing device
INFO:UHIDDevice:(UHID_CREATE2) create UHIDDevice(vid=39321, pid=39321, name=FIDO2 Virtual USB Device, uniq=UHIDDevice_14ce6275-a705-4145-be57-5d64e7bdbc36)
INFO:root:WAITING FOR NEW DEVICE
[LAST LINE REPEATED UNTIL I PUT IN THE CARD]
INFO:root:WAITING FOR NEW DEVICE
INFO:UHIDDevice:(UHID_INPUT2) send ffffffff860011773faa16e9df5165330b1285020100000c00000000000000000000000000000000000000000000000000000000000000000000000000000000
Level 5:fido2.pcsc:SEND: 80108000010400
Level 5:fido2.pcsc:RECV: 00af0183665532465f5632684649444f5f325f30684649444f5f325f3102856b6372656450726f746563746863726564426c6f626c6c61726765426c6f624b65796c6d696e50696e4c656e6774686b686d61632d7365637265740350c5703116972b4851a3e7ae125984339904ab64706c6174f462726bf569636c69656e7450696ef4627570f46e70696e557641757468546f6b656ef56a6c61726765426c6f6273f569617574686e72436667f568637265644d676d74f56f7365744d696e50494e4c656e677468f5706d616b654372656455764e6f74527164f568616c776179735576f40519028006820201071008100981636e66630a81a264747970656a SW=1840000000000
Level 5:fido2.pcsc:SEND: 00c0000022
Level 5:fido2.pcsc:RECV: 7075626c69632d6b657963616c67260b1904000d040e1a020100020f190100101820 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send 330b128590012200af0183665532465f5632684649444f5f325f30684649444f5f325f3102856b6372656450726f746563746863726564426c6f626c6c617267
INFO:UHIDDevice:(UHID_INPUT2) send 330b12850065426c6f624b65796c6d696e50696e4c656e6774686b686d61632d7365637265740350c5703116972b4851a3e7ae125984339904ab64706c6174f4
INFO:UHIDDevice:(UHID_INPUT2) send 330b12850162726bf569636c69656e7450696ef4627570f46e70696e557641757468546f6b656ef56a6c61726765426c6f6273f569617574686e72436667f568
INFO:UHIDDevice:(UHID_INPUT2) send 330b128502637265644d676d74f56f7365744d696e50494e4c656e677468f5706d616b654372656455764e6f74527164f568616c776179735576f40519028006
INFO:UHIDDevice:(UHID_INPUT2) send 330b128503820201071008100981636e66630a81a264747970656a7075626c69632d6b657963616c67260b1904000d040e1a020100020f190100101820000000
Level 5:fido2.pcsc:SEND: 801080006a02a4017668747470733a2f2f696e76656e742e6b64652e6f7267025820e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550381a262696450855aacf0053a2e3681672c59a04205f164747970656a7075626c69632d6b657905a1627570f400
Level 5:fido2.pcsc:RECV: 2e SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send 330b12859000012e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Level 5:fido2.pcsc:SEND: 801080006202a4016e696e76656e742e6b64652e6f7267025820e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550381a262696450855aacf0053a2e3681672c59a04205f164747970656a7075626c69632d6b657905a1627570f400
Level 5:fido2.pcsc:RECV: 00a301a362696450855aacf0053a2e3681672c59a04205f164747970656a7075626c69632d6b65796a7472616e73706f72747381636e6663025825f16cc5b7d3132765cc35d56bd5d1a426ff650259a6772b03d05d34195ea92c6100000000080358473045022100a50a0a49548715062eed0c5b5cbd71810d3a80b59be8523412568b5fc7c9cdad02206db8eec30f33f20e59ef7cbef4d3bf63becbbf309977d118c5a7f76ccfd055c304 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send 330b12859000ab00a301a362696450855aacf0053a2e3681672c59a04205f164747970656a7075626c69632d6b65796a7472616e73706f72747381636e666302
INFO:UHIDDevice:(UHID_INPUT2) send 330b1285005825f16cc5b7d3132765cc35d56bd5d1a426ff650259a6772b03d05d34195ea92c6100000000080358473045022100a50a0a49548715062eed0c5b
INFO:UHIDDevice:(UHID_INPUT2) send 330b1285015cbd71810d3a80b59be8523412568b5fc7c9cdad02206db8eec30f33f20e59ef7cbef4d3bf63becbbf309977d118c5a7f76ccfd055c30400000000
Level 5:fido2.pcsc:SEND: 801080006e01a6015820d0cee6fc7dbf599a919db8fb951311269f0eb781f7841c6cc0544ad9da34154b02a16269646d6d616b652e6d652e626c696e6b03a26269644100646e616d656d6d616b652e6d652e626c696e6b0481a263616c672664747970656a7075626c69632d6b65790840090100
Level 5:fido2.pcsc:RECV: 35 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send 330b1285900001350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Failure with Falkon

INFO:UHIDDevice:initializing device
INFO:UHIDDevice:(UHID_CREATE2) create UHIDDevice(vid=39321, pid=39321, name=FIDO2 Virtual USB Device, uniq=UHIDDevice_0ad3ce85-7b40-4d45-b6ce-0f1b9f6be167)
INFO:root:WAITING FOR NEW DEVICE
INFO:UHIDDevice:(UHID_INPUT2) send ffffffff8600118c2754f79f9fd177d8a16dc7020100000c00000000000000000000000000000000000000000000000000000000000000000000000000000000
Level 5:fido2.pcsc:SEND: 80108000010400
Level 5:fido2.pcsc:RECV: 00af0183665532465f5632684649444f5f325f30684649444f5f325f3102856b6372656450726f746563746863726564426c6f626c6c61726765426c6f624b65796c6d696e50696e4c656e6774686b686d61632d7365637265740350c5703116972b4851a3e7ae125984339904ab64706c6174f462726bf569636c69656e7450696ef4627570f46e70696e557641757468546f6b656ef56a6c61726765426c6f6273f569617574686e72436667f568637265644d676d74f56f7365744d696e50494e4c656e677468f5706d616b654372656455764e6f74527164f568616c776179735576f40519028006820201071008100981636e66630a81a264747970656a SW=1840000000000
Level 5:fido2.pcsc:SEND: 00c0000022
Level 5:fido2.pcsc:RECV: 7075626c69632d6b657963616c67260b1904000d040e1a020100020f190100101820 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc790012200af0183665532465f5632684649444f5f325f30684649444f5f325f3102856b6372656450726f746563746863726564426c6f626c6c617267
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc70065426c6f624b65796c6d696e50696e4c656e6774686b686d61632d7365637265740350c5703116972b4851a3e7ae125984339904ab64706c6174f4
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc70162726bf569636c69656e7450696ef4627570f46e70696e557641757468546f6b656ef56a6c61726765426c6f6273f569617574686e72436667f568
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc702637265644d676d74f56f7365744d696e50494e4c656e677468f5706d616b654372656455764e6f74527164f568616c776179735576f40519028006
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc703820201071008100981636e66630a81a264747970656a7075626c69632d6b657963616c67260b1904000d040e1a020100020f190100101820000000
Level 5:fido2.pcsc:SEND: 00020300514cb416701f991590d77c76a193867c97a5bf56137d2cf3e5d2393f4c7cd6631cb6d88822b1c18d440a06cc2ec2780cc6ad9ad148c7185aff0980c8d1a845fa8a10855aacf0053a2e3681672c59a04205f100
Level 5:fido2.pcsc:RECV:  SW=6A0000000000000000000000000000000000
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc78300026a8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Level 5:fido2.pcsc:SEND: 00020300514cb416701f991590d77c76a193867c97a5bf56137d2cf3e5d2393f4c7cd6631cf16cc5b7d3132765cc35d56bd5d1a426ff650259a6772b03d05d34195ea92c6110855aacf0053a2e3681672c59a04205f100
Level 5:fido2.pcsc:RECV:  SW=D200000000000000000000000000000000000
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc7830002698500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Level 5:fido2.pcsc:SEND: 00020300514cb416701f991590d77c76a193867c97a5bf56137d2cf3e5d2393f4c7cd6631cf16cc5b7d3132765cc35d56bd5d1a426ff650259a6772b03d05d34195ea92c6110855aacf0053a2e3681672c59a04205f100
Level 5:fido2.pcsc:RECV:  SW=D200000000000000000000000000000000000
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc7830002698500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Level 5:fido2.pcsc:SEND: 00020300514cb416701f991590d77c76a193867c97a5bf56137d2cf3e5d2393f4c7cd6631cf16cc5b7d3132765cc35d56bd5d1a426ff650259a6772b03d05d34195ea92c6110855aacf0053a2e3681672c59a04205f100
Level 5:fido2.pcsc:RECV:  SW=D200000000000000000000000000000000000
INFO:UHIDDevice:(UHID_INPUT2) send d8a16dc7830002698500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[LAST THREE LINES KEEP ON BEING REPEATED UNTIL I BREAK IT OFF]
equaeghe commented 7 months ago

The following is the debug output when trying to login to Github (card used as security key). The bridge was started with sudo -E .venv/bin/fido2-hid-bridge. I've again tried both Firefox and Falkon. Now there is success with the latter!

Failure with Firefox

INFO:UHIDDevice:initializing device
INFO:UHIDDevice:(UHID_CREATE2) create UHIDDevice(vid=39321, pid=39321, name=FIDO2 Virtual USB Device, uniq=UHIDDevice_a0bb9aea-e6e1-484e-8809-278373de5ebe)
INFO:root:WAITING FOR NEW DEVICE
INFO:UHIDDevice:(UHID_INPUT2) send ffffffff86001197989e9d8388936eff2b7a4d020100000c00000000000000000000000000000000000000000000000000000000000000000000000000000000
Level 5:fido2.pcsc:SEND: 80108000010400
Level 5:fido2.pcsc:RECV: 00af0183665532465f5632684649444f5f325f30684649444f5f325f3102856b6372656450726f746563746863726564426c6f626c6c61726765426c6f624b65796c6d696e50696e4c656e6774686b686d61632d7365637265740350c5703116972b4851a3e7ae125984339904ab64706c6174f462726bf569636c69656e7450696ef4627570f46e70696e557641757468546f6b656ef56a6c61726765426c6f6273f569617574686e72436667f568637265644d676d74f56f7365744d696e50494e4c656e677468f5706d616b654372656455764e6f74527164f568616c776179735576f40519028006820201071008100981636e66630a81a264747970656a SW=1840000000000
Level 5:fido2.pcsc:SEND: 00c0000022
Level 5:fido2.pcsc:RECV: 7075626c69632d6b657963616c67260b1904000d040e1a020100020f190100101820 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d90012200af0183665532465f5632684649444f5f325f30684649444f5f325f3102856b6372656450726f746563746863726564426c6f626c6c617267
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d0065426c6f624b65796c6d696e50696e4c656e6774686b686d61632d7365637265740350c5703116972b4851a3e7ae125984339904ab64706c6174f4
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d0162726bf569636c69656e7450696ef4627570f46e70696e557641757468546f6b656ef56a6c61726765426c6f6273f569617574686e72436667f568
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d02637265644d676d74f56f7365744d696e50494e4c656e677468f5706d616b654372656455764e6f74527164f568616c776179735576f40519028006
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d03820201071008100981636e66630a81a264747970656a7075626c69632d6b657963616c67260b1904000d040e1a020100020f190100101820000000
Level 5:fido2.pcsc:SEND: 801080005e02a4016a6769746875622e636f6d025820e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550381a26269645014c2c3e3918b20d45d0ccbb12d3c32cb64747970656a7075626c69632d6b657905a1627570f400
Level 5:fido2.pcsc:RECV: 00a301a36269645014c2c3e3918b20d45d0ccbb12d3c32cb64747970656a7075626c69632d6b65796a7472616e73706f72747381636e66630258253aeb002460381c6f258e8395d3026f571f0d9a76488dcd837639b13aed31656000000000130358483046022100c2f608bfc04c754b058140ed282d45d824e02a97e3e0df1aeda0cab4bfd816e8022100cb610c413b56375e076000b2ba22c77cb3bbd024d217f1118fe3aff8d41da24904 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d9000ac00a301a36269645014c2c3e3918b20d45d0ccbb12d3c32cb64747970656a7075626c69632d6b65796a7472616e73706f72747381636e666302
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d0058253aeb002460381c6f258e8395d3026f571f0d9a76488dcd837639b13aed31656000000000130358483046022100c2f608bfc04c754b058140ed
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d01282d45d824e02a97e3e0df1aeda0cab4bfd816e8022100cb610c413b56375e076000b2ba22c77cb3bbd024d217f1118fe3aff8d41da24904000000
Level 5:fido2.pcsc:SEND: 801080006e01a6015820d0cee6fc7dbf599a919db8fb951311269f0eb781f7841c6cc0544ad9da34154b02a16269646d6d616b652e6d652e626c696e6b03a26269644100646e616d656d6d616b652e6d652e626c696e6b0481a263616c672664747970656a7075626c69632d6b65790840090100
Level 5:fido2.pcsc:RECV: 35 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send ff2b7a4d900001350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Success with Falkon

INFO:UHIDDevice:initializing device
INFO:UHIDDevice:(UHID_CREATE2) create UHIDDevice(vid=39321, pid=39321, name=FIDO2 Virtual USB Device, uniq=UHIDDevice_45d89fcf-f68a-4200-bce8-dd1a19b01415)
INFO:root:WAITING FOR NEW DEVICE
INFO:UHIDDevice:(UHID_INPUT2) send ffffffff860011c398bc81f2fed07331e4f4cb020100000c00000000000000000000000000000000000000000000000000000000000000000000000000000000
Level 5:fido2.pcsc:SEND: 80108000010400
Level 5:fido2.pcsc:RECV: 00af0183665532465f5632684649444f5f325f30684649444f5f325f3102856b6372656450726f746563746863726564426c6f626c6c61726765426c6f624b65796c6d696e50696e4c656e6774686b686d61632d7365637265740350c5703116972b4851a3e7ae125984339904ab64706c6174f462726bf569636c69656e7450696ef4627570f46e70696e557641757468546f6b656ef56a6c61726765426c6f6273f569617574686e72436667f568637265644d676d74f56f7365744d696e50494e4c656e677468f5706d616b654372656455764e6f74527164f568616c776179735576f40519028006820201071008100981636e66630a81a264747970656a SW=1840000000000
Level 5:fido2.pcsc:SEND: 00c0000022
Level 5:fido2.pcsc:RECV: 7075626c69632d6b657963616c67260b1904000d040e1a020100020f190100101820 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send 31e4f4cb90012200af0183665532465f5632684649444f5f325f30684649444f5f325f3102856b6372656450726f746563746863726564426c6f626c6c617267
INFO:UHIDDevice:(UHID_INPUT2) send 31e4f4cb0065426c6f624b65796c6d696e50696e4c656e6774686b686d61632d7365637265740350c5703116972b4851a3e7ae125984339904ab64706c6174f4
INFO:UHIDDevice:(UHID_INPUT2) send 31e4f4cb0162726bf569636c69656e7450696ef4627570f46e70696e557641757468546f6b656ef56a6c61726765426c6f6273f569617574686e72436667f568
INFO:UHIDDevice:(UHID_INPUT2) send 31e4f4cb02637265644d676d74f56f7365744d696e50494e4c656e677468f5706d616b654372656455764e6f74527164f568616c776179735576f40519028006
INFO:UHIDDevice:(UHID_INPUT2) send 31e4f4cb03820201071008100981636e66630a81a264747970656a7075626c69632d6b657963616c67260b1904000d040e1a020100020f190100101820000000
Level 5:fido2.pcsc:SEND: 0002030051b3cb2d9bbadcc643f6ebe4a10a909a07ca3399128189a6c70e5be9a89fa450443aeb002460381c6f258e8395d3026f571f0d9a76488dcd837639b13aed3165601014c2c3e3918b20d45d0ccbb12d3c32cb00
Level 5:fido2.pcsc:RECV: 010000001230450220589d4ba2b2cef58e8ade36ff49ee3c7342205d45f81cd9c6b58f34acbe03c933022100d4fa0a2042ef48a341dcd66be01eaebcdfbcb4d86f4878400d405f69d5f54c73 SW=9000
INFO:UHIDDevice:(UHID_INPUT2) send 31e4f4cb83004e010000001230450220589d4ba2b2cef58e8ade36ff49ee3c7342205d45f81cd9c6b58f34acbe03c933022100d4fa0a2042ef48a341dcd66be0
INFO:UHIDDevice:(UHID_INPUT2) send 31e4f4cb001eaebcdfbcb4d86f4878400d405f69d5f54c7390000000000000000000000000000000000000000000000000000000000000000000000000000000
BryanJacobs commented 7 months ago

Your card is responding with "pin not set". The bridge is successfully relaying that response to the browser.

Github, when you use a "security key" (not "passkey"), sends a CTAP make-credential request with an empty pinUvAuthToken parameter. The CTAP 2.0 and 2.1 specifications say that's supposed to result in either PIN_NOT_SET or PIN_AUTH_INVALID depending on whether a PIN is set.

That's what's happening here. Have you tried setting a PIN?

equaeghe commented 6 months ago

Your card is responding with "pin not set". The bridge is successfully relaying that response to the browser.

Github, when you use a "security key" (not "passkey"), sends a CTAP make-credential request with an empty pinUvAuthToken parameter. The CTAP 2.0 and 2.1 specifications say that's supposed to result in either PIN_NOT_SET or PIN_AUTH_INVALID depending on whether a PIN is set.

That's what's happening here. Have you tried setting a PIN?

I hadn't tried that yet, because I preferred for now to use it pinless, as that worked before. Also, it still works pinless for Github in Falkon and using the NFC interface on my phone. So I guess Firefox and Falkon do FIDO2 differenly, or the websites act differently depending on the browser.

Anyway, I tried setting a pin, but TBH, did not manage. Namely, the two options I found, through a browser when registering for Microsoft services or using libfido2's fido2-token. The former doesn't work as it never asks for the key and then errors out (after apparent initial success on Firefox and quite immediate error on Falkon); I could generate and provide debug output if that is of interest. In the latter case, the card doesn't seem to be recognized, as with or without the card I get:

$ fido2-token -L
/dev/hidraw0: vendor=0x9999, product=0x9999 ( )

$ fido2-token -I /dev/hidraw0
proto: 0x02
major: 0x01
minor: 0x00
build: 0x00
caps: 0x08 (nowink, nocbor, nomsg)

$ fido2-token -S /dev/hidraw0
Enter new PIN for /dev/hidraw0: 
Enter the same PIN again: 
fido2-token: fido_dev_set_pin: FIDO_ERR_INTERNAL

(I tried this as a superuser as well, with the same result.) Again, I can generate debug output (if any) if that is of interest.

BryanJacobs commented 6 months ago

libfido2 supports PC/SC natively if compiled that way, such as with https://aur.archlinux.org/packages/libfido2-full . Perhaps try setting a PIN with that and no bridge involved. That said, something is wrong with your card if you can't set a PIN. It advertises support:

{1: ["U2F_V2", "FIDO_2_0", "FIDO_2_1"], 2: ["credProtect", "credBlob", "largeBlobKey", "minPinLength", "hmac-secret"], 3: h'C5703116972B4851A3E7AE1259843399', 4: {"plat": false, "rk": true, "clientPin": false, "up": false, "pinUvAuthToken": true, "largeBlobs": true, "authnrCfg": true, "credMgmt": true, "setMinPINLength": true, "makeCredUvNotRqd": true, "alwaysUv": false}, 5: 640, 6: [2, 1], 7: 16, 8: 16, 9: ["nfc"], 10: [{"type": "public-key", "alg": -7}], 11: 1024, 13: 4, 14: 33619970, 15: 256, 16: 32}

The issue here is that the bridge, this repository's software, appears to be doing exactly what it's supposed to do. Firefox sent a makeCredential for the domain make.me.blink with an empty pinUvAuth. The card responded with error 0x35, "pin not set". The bridge relayed response 0x35 to the browser. The browser displayed an error.

To double check, I have upgraded to Firefox 124. Using a smartcard running my own known-good authenticator applet ( https://github.com/BryanJacobs/FIDO2Applet/ ), I was able to:

All operations were performed while a PIN was set on the card.

To say it concisely, this is not a bug in the bridge. Your problem is elsewhere, with the card and/or Firefox and/or the site(s). I know that github does some browser feature detection to determine how it tries to use "security keys", so possibly what's going on is that the code it uses for Firefox specifically only works when a PIN is set.

I could theoretically add code to this repository that parses the CTAP requests and does some kind of massaging to try to keep Firefox+github happy by lying to them, but I'm not going to do that. It's a dumb relay, it sends HID requests to PC/SC and the responses back. It's doing that right now without a problem I can see.

equaeghe commented 6 months ago

libfido2 supports PC/SC natively if compiled that way, […].

OK, got libfido2 with native PC/SC.

Perhaps try setting a PIN with that and no bridge involved.

Done, same type of problem (the fact that the vendor/product is unknown already seems quite bad):

$ sudo fido2-token -L
/dev/hidraw0: vendor=0x9999, product=0x9999 ( )
pcsc://slot0: vendor=0x0000, product=0x0000 (PC/SC Alcor Micro AU9540 00 00)

$ sudo fido2-token -I pcsc://slot0
proto: 0x00
major: 0x00
minor: 0x00
build: 0x00
caps: 0x00 (nowink, nocbor, msg)

$ fido2-token -S pcsc://slot0
Enter new PIN for pcsc://slot0: 
Enter the same PIN again: 
fido2-token: fido_dev_set_pin: FIDO_ERR_INTERNAL

That said, something is wrong with your card if you can't set a PIN.

I'm fearing as much. The fido2-token-output is discouraging. Likely I need to find a Windows PC to test the card…

It advertises support:

{1: ["U2F_V2", "FIDO_2_0", "FIDO_2_1"], 2: ["credProtect", "credBlob", "largeBlobKey", "minPinLength", "hmac-secret"], 3: h'C5703116972B4851A3E7AE1259843399', 4: {"plat": false, "rk": true, "clientPin": false, "up": false, "pinUvAuthToken": true, "largeBlobs": true, "authnrCfg": true, "credMgmt": true, "setMinPINLength": true, "makeCredUvNotRqd": true, "alwaysUv": false}, 5: 640, 6: [2, 1], 7: 16, 8: 16, 9: ["nfc"], 10: [{"type": "public-key", "alg": -7}], 11: 1024, 13: 4, 14: 33619970, 15: 256, 16: 32}

How did you get that? I guess it's in the hex strings, but it is not clear to me how to decode it.

To double check, I have upgraded to Firefox 124. Using a smartcard running my own known-good authenticator applet ( https://github.com/BryanJacobs/FIDO2Applet/ ), I was able to:

[…]

Thanks very much for testing. I should perhaps just buy a blank card and try to get your applet on there… (What I wanted to avoid when buying the BADGEO FIDO2, as it seems like a big hurdle.)

To say it concisely, this is not a bug in the bridge. Your problem is elsewhere, with the card and/or Firefox and/or the site(s). I know that github does some browser feature detection to determine how it tries to use "security keys", so possibly what's going on is that the code it uses for Firefox specifically only works when a PIN is set.

So my next step is to try using a Windows PC, to see what works there and to see if I can set a pin.

I could theoretically […], but I'm not going to do that. […]

Of course, there shouldn't be any hacks or complexity added because what is likely an issue elsewhere.

BryanJacobs commented 6 months ago

Done, same type of problem (the fact that the vendor/product is unknown already seems quite bad):

The vendor and product ID come from the USB HID report descriptor, which doesn't exist in PC/SC. They should be zeroes for a PC/SC device.


$ sudo fido2-token -L
/dev/hidraw0: vendor=0x9999, product=0x9999 ( )
pcsc://slot0: vendor=0x0000, product=0x0000 (PC/SC Alcor Micro AU9540 00 00)

$ sudo fido2-token -I pcsc://slot0
proto: 0x00
major: 0x00
minor: 0x00
build: 0x00
caps: 0x00 (nowink, nocbor, msg)

This is not the right/happy output here. You should see a CTAP2 getInfo response (like I decoded for you earlier), but it appears to be missing. Caps should include cbor, but you have nocbor. nocbor means "only send me U2F stuff".

Perhaps what's going on is your "FIDO card" advertises FIDO_2_0 and FIDO_2_1 but actually only properly supports U2F/CTAP1? Clearly there is some CTAP2 logic in the card because it does answer a getInfo request from the trace you pasted earlier...

Or maybe your connection was just interrupted when you ran this command? Please try it again with -d.

$ fido2-token -S pcsc://slot0 Enter new PIN for pcsc://slot0: Enter the same PIN again: fido2-token: fido_dev_set_pin: FIDO_ERR_INTERNAL

This should not fail, and the fact it failed is not a good sign. If your card doesn't support CTAP2 that would happen - U2F does not have PINs.

It advertises support:

{1: ["U2F_V2", "FIDO_2_0", "FIDO_2_1"], 2: ["credProtect", "credBlob", "largeBlobKey", "minPinLength", "hmac-secret"], 3: h'C5703116972B4851A3E7AE1259843399', 4: {"plat": false, "rk": true, "clientPin": false, "up": false, "pinUvAuthToken": true, "largeBlobs": true, "authnrCfg": true, "credMgmt": true, "setMinPINLength": true, "makeCredUvNotRqd": true, "alwaysUv": false}, 5: 640, 6: [2, 1], 7: 16, 8: 16, 9: ["nfc"], 10: [{"type": "public-key", "alg": -7}], 11: 1024, 13: 4, 14: 33619970, 15: 256, 16: 32}

How did you get that? I guess it's in the hex strings, but it is not clear to me how to decode it.

The hex strings are CTAP2 commands. CTAP2 commands are encoded as CBOR. The web site cbor.me provides an easy decoder if you want one, although when looking at HID stuff you also have to reassemble the right parts of the requests/responses.

I know how to parse these things quickly from the dozens of hours I spent writing an entire authenticator and a platform from scratch.

Thanks very much for testing. I should perhaps just buy a blank card and try to get your applet on there… (What I wanted to avoid when buying the BADGEO FIDO2, as it seems like a big hurdle.)

I'm sorry about that. If you want, getcybernetic.com will sell you a nifty ring that can host my applet without you doing special work - just press a button. If you're incredibly daring you can get one implanted under your skin from vivokey.com :-).

So my next step is to try using a Windows PC, to see what works there and to see if I can set a pin.

Good luck. Windows supports PC/SC management natively but I don't see why the result would be different from what you got with libfido2.

BryanJacobs commented 6 months ago

FYI, the way this is supposed to work is that the applet on the card is selected, and the card replies to the applet select command with either FIDO_2_0 or U2F_V2.

If your card is replying with U2F_V2, none of its CTAP2 functionality would ever get used. It would just sit there, vestigially. So perhaps what we're seeing is that Firefox is using it anyway.

BryanJacobs commented 6 months ago

If you want you can try hardcoding line 199 of ctap_hid_bridge.py to 0x00 instead of ctap.capabilities. That will disable all CTAP2 functionality through the bridge.

equaeghe commented 6 months ago

[…] Please try it again with -d.

$ fido2-token -S -d pcsc://slot0
fido_tx: dev=0x5ab3ad2982a0, cmd=0x06
fido_tx: buf=0x5ab3ad2982a0, len=8
0000: 70 db 32 16 1d fa 78 f8
fido_pcsc_write: writing: buf=0x7ffcfa2175e0, len=14
0000: 00 a4 04 00 08 a0 00 00 06 47 2f 00 01 00
fido_pcsc_write: read: buf=0x5ab3ad2989d0, len=8
0000: 55 32 46 5f 56 32 90 00
fido_rx: dev=0x5ab3ad2982a0, cmd=0x06, ms=-1
fido_pcsc_read: reading: buf=0x5ab3ad2989d0, len=8
0000: 55 32 46 5f 56 32 90 00
fido_dev_get_cbor_info_tx: dev=0x5ab3ad2982a0
fido_tx: dev=0x5ab3ad2982a0, cmd=0x10
fido_tx: buf=0x7ffcfa217857, len=1
0000: 04
fido_pcsc_write: writing: buf=0x7ffcfa2175a0, len=7
0000: 80 10 00 00 01 04 00
fido_pcsc_write: read: buf=0x5ab3ad2989d0, len=258
0000: 00 af 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f
0016: 5f 32 5f 30 68 46 49 44 4f 5f 32 5f 31 02 85 6b
0032: 63 72 65 64 50 72 6f 74 65 63 74 68 63 72 65 64
0048: 42 6c 6f 62 6c 6c 61 72 67 65 42 6c 6f 62 4b 65
0064: 79 6c 6d 69 6e 50 69 6e 4c 65 6e 67 74 68 6b 68
0080: 6d 61 63 2d 73 65 63 72 65 74 03 50 c5 70 31 16
0096: 97 2b 48 51 a3 e7 ae 12 59 84 33 99 04 ab 64 70
0112: 6c 61 74 f4 62 72 6b f5 69 63 6c 69 65 6e 74 50
0128: 69 6e f5 62 75 70 f4 6e 70 69 6e 55 76 41 75 74
0144: 68 54 6f 6b 65 6e f5 6a 6c 61 72 67 65 42 6c 6f
0160: 62 73 f5 69 61 75 74 68 6e 72 43 66 67 f5 68 63
0176: 72 65 64 4d 67 6d 74 f5 6f 73 65 74 4d 69 6e 50
0192: 49 4e 4c 65 6e 67 74 68 f5 70 6d 61 6b 65 43 72
0208: 65 64 55 76 4e 6f 74 52 71 64 f5 68 61 6c 77 61
0224: 79 73 55 76 f4 05 19 02 80 06 82 02 01 07 10 08
0240: 10 09 81 63 6e 66 63 0a 81 a2 64 74 79 70 65 6a
0256: 61 22
fido_dev_get_cbor_info_rx: dev=0x5ab3ad2982a0, ci=0x5ab3ad298b30, ms=-1
fido_rx: dev=0x5ab3ad2982a0, cmd=0x10, ms=-1
fido_pcsc_read: reading: buf=0x5ab3ad2989d0, len=258
0000: 00 af 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f
0016: 5f 32 5f 30 68 46 49 44 4f 5f 32 5f 31 02 85 6b
0032: 63 72 65 64 50 72 6f 74 65 63 74 68 63 72 65 64
0048: 42 6c 6f 62 6c 6c 61 72 67 65 42 6c 6f 62 4b 65
0064: 79 6c 6d 69 6e 50 69 6e 4c 65 6e 67 74 68 6b 68
0080: 6d 61 63 2d 73 65 63 72 65 74 03 50 c5 70 31 16
0096: 97 2b 48 51 a3 e7 ae 12 59 84 33 99 04 ab 64 70
0112: 6c 61 74 f4 62 72 6b f5 69 63 6c 69 65 6e 74 50
0128: 69 6e f5 62 75 70 f4 6e 70 69 6e 55 76 41 75 74
0144: 68 54 6f 6b 65 6e f5 6a 6c 61 72 67 65 42 6c 6f
0160: 62 73 f5 69 61 75 74 68 6e 72 43 66 67 f5 68 63
0176: 72 65 64 4d 67 6d 74 f5 6f 73 65 74 4d 69 6e 50
0192: 49 4e 4c 65 6e 67 74 68 f5 70 6d 61 6b 65 43 72
0208: 65 64 55 76 4e 6f 74 52 71 64 f5 68 61 6c 77 61
0224: 79 73 55 76 f4 05 19 02 80 06 82 02 01 07 10 08
0240: 10 09 81 63 6e 66 63 0a 81 a2 64 74 79 70 65 6a
0256: 61 22
fido_pcsc_write: writing: buf=0x7ffcfa217663, len=5
0000: 00 c0 00 00 22
fido_pcsc_write: read: buf=0x5ab3ad2989d0, len=36
0000: 70 75 62 6c 69 63 2d 6b 65 79 63 61 6c 67 26 0b
0016: 19 04 00 0d 04 0e 1a 02 01 00 02 0f 19 01 00 10
0032: 18 20 90 00
fido_pcsc_read: reading: buf=0x5ab3ad2989d0, len=36
0000: 70 75 62 6c 69 63 2d 6b 65 79 63 61 6c 67 26 0b
0016: 19 04 00 0d 04 0e 1a 02 01 00 02 0f 19 01 00 10
0032: 18 20 90 00
ctap_check_cbor: invalid cbor
cbor_map_iter: ctap_check_cbor
cbor_map_iter: iterator < 0 on i=3
cbor_parse_reply: cbor_map_iter
fido_dev_open_rx: fido_dev_cbor_info_wait: -4
fido_dev_open_rx: falling back to u2f
Enter new PIN for pcsc://slot0: 
Enter the same PIN again: 
fido_dev_authkey_tx: dev=0x5ab3ad2982a0
cbor_encode_pin_opt: fido_dev_get_pin_protocol
fido_dev_authkey_tx: cbor_build
fido_do_ecdh: fido_dev_authkey
fido_dev_set_pin_tx: fido_do_ecdh
fido_dev_set_pin_wait: fido_dev_set_pin_tx
fido2-token: fido_dev_set_pin: FIDO_ERR_INTERNAL

So as you surmised, it is “falling back to u2f”.

The same happens when going over the bridge, although the conversation is different:

$ fido2-token -S -d /dev/hidraw0
fido_tx: dev=0x59437c4182a0, cmd=0x06
fido_tx: buf=0x59437c4182a0, len=8
0000: 86 c0 04 45 18 70 47 64
fido_rx: dev=0x59437c4182a0, cmd=0x06, ms=-1
rx_preamble: buf=0x7fffb566b820, len=64
0000: ff ff ff ff 86 00 11 86 c0 04 45 18 70 47 64 59
0016: ec c5 8e 02 01 00 00 0c 00 00 00 00 00 00 00 00
0032: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
rx: payload_len=17
fido_rx: buf=0x59437c4182a8, len=17
0000: 86 c0 04 45 18 70 47 64 59 ec c5 8e 02 01 00 00
0016: 0c
fido_dev_get_cbor_info_tx: dev=0x59437c4182a0
fido_tx: dev=0x59437c4182a0, cmd=0x10
fido_tx: buf=0x7fffb566b8d7, len=1
0000: 04
fido_dev_get_cbor_info_rx: dev=0x59437c4182a0, ci=0x59437c4183f0, ms=-1
fido_rx: dev=0x59437c4182a0, cmd=0x10, ms=-1
rx_preamble: buf=0x7fffb566b7e0, len=64
0000: 59 ec c5 8e 90 01 22 00 af 01 83 66 55 32 46 5f
0016: 56 32 68 46 49 44 4f 5f 32 5f 30 68 46 49 44 4f
0032: 5f 32 5f 31 02 85 6b 63 72 65 64 50 72 6f 74 65
0048: 63 74 68 63 72 65 64 42 6c 6f 62 6c 6c 61 72 67
rx: payload_len=290
rx: buf=0x7fffb566b7e0, len=64
0000: 59 ec c5 8e 00 65 42 6c 6f 62 4b 65 79 6c 6d 69
0016: 6e 50 69 6e 4c 65 6e 67 74 68 6b 68 6d 61 63 2d
0032: 73 65 63 72 65 74 03 50 c5 70 31 16 97 2b 48 51
0048: a3 e7 ae 12 59 84 33 99 04 ab 64 70 6c 61 74 f4
rx: buf=0x7fffb566b7e0, len=64
0000: 59 ec c5 8e 01 62 72 6b f5 69 63 6c 69 65 6e 74
0016: 50 69 6e f5 62 75 70 f4 6e 70 69 6e 55 76 41 75
0032: 74 68 54 6f 6b 65 6e f5 6a 6c 61 72 67 65 42 6c
0048: 6f 62 73 f5 69 61 75 74 68 6e 72 43 66 67 f5 68
rx: buf=0x7fffb566b7e0, len=64
0000: 59 ec c5 8e 02 63 72 65 64 4d 67 6d 74 f5 6f 73
0016: 65 74 4d 69 6e 50 49 4e 4c 65 6e 67 74 68 f5 70
0032: 6d 61 6b 65 43 72 65 64 55 76 4e 6f 74 52 71 64
0048: f5 68 61 6c 77 61 79 73 55 76 f4 05 19 02 80 06
rx: buf=0x7fffb566b7e0, len=64
0000: 59 ec c5 8e 03 82 02 01 07 10 08 10 09 81 63 6e
0016: 66 63 0a 81 a2 64 74 79 70 65 6a 70 75 62 6c 69
0032: 63 2d 6b 65 79 63 61 6c 67 26 0b 19 04 00 0d 04
0048: 0e 1a 02 01 00 02 0f 19 01 00 10 18 20 00 00 00
fido_rx: buf=0x59437c4184f0, len=290
0000: 00 af 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f
0016: 5f 32 5f 30 68 46 49 44 4f 5f 32 5f 31 02 85 6b
0032: 63 72 65 64 50 72 6f 74 65 63 74 68 63 72 65 64
0048: 42 6c 6f 62 6c 6c 61 72 67 65 42 6c 6f 62 4b 65
0064: 79 6c 6d 69 6e 50 69 6e 4c 65 6e 67 74 68 6b 68
0080: 6d 61 63 2d 73 65 63 72 65 74 03 50 c5 70 31 16
0096: 97 2b 48 51 a3 e7 ae 12 59 84 33 99 04 ab 64 70
0112: 6c 61 74 f4 62 72 6b f5 69 63 6c 69 65 6e 74 50
0128: 69 6e f5 62 75 70 f4 6e 70 69 6e 55 76 41 75 74
0144: 68 54 6f 6b 65 6e f5 6a 6c 61 72 67 65 42 6c 6f
0160: 62 73 f5 69 61 75 74 68 6e 72 43 66 67 f5 68 63
0176: 72 65 64 4d 67 6d 74 f5 6f 73 65 74 4d 69 6e 50
0192: 49 4e 4c 65 6e 67 74 68 f5 70 6d 61 6b 65 43 72
0208: 65 64 55 76 4e 6f 74 52 71 64 f5 68 61 6c 77 61
0224: 79 73 55 76 f4 05 19 02 80 06 82 02 01 07 10 08
0240: 10 09 81 63 6e 66 63 0a 81 a2 64 74 79 70 65 6a
0256: 70 75 62 6c 69 63 2d 6b 65 79 63 61 6c 67 26 0b
0272: 19 04 00 0d 04 0e 1a 02 01 00 02 0f 19 01 00 10
0288: 18 20
ctap_check_cbor: invalid cbor
cbor_map_iter: ctap_check_cbor
cbor_map_iter: iterator < 0 on i=3
cbor_parse_reply: cbor_map_iter
fido_dev_open_rx: fido_dev_cbor_info_wait: -4
fido_dev_open_rx: falling back to u2f
Enter new PIN for /dev/hidraw0: 
Enter the same PIN again: 
fido_dev_authkey_tx: dev=0x59437c4182a0
cbor_encode_pin_opt: fido_dev_get_pin_protocol
fido_dev_authkey_tx: cbor_build
fido_do_ecdh: fido_dev_authkey
fido_dev_set_pin_tx: fido_do_ecdh
fido_dev_set_pin_wait: fido_dev_set_pin_tx
fido2-token: fido_dev_set_pin: FIDO_ERR_INTERNAL

Good luck. Windows supports PC/SC management natively but I don't see why the result would be different from what you got with libfido2.

I thought I would need a Windows machine, but my VM worked fine with smartcard-passthrough. The result is that everything works on Windows: login to websites with card as second factor (security key), registering for MS services (including setting pin) and then using that registration to login with the card+pin.

Afterwards, back on Linux, nothing changed. Namely, I thought that maybe because a pin had been set, things would be magically fixed. But I guess that on Windows, the FIDO2 module is accessed as needed (for Github, no pin was needed for 2FA even after setting one, so that must be the U2F path) and on Linux only the U2F one (successfully only for Github with Chromium-based browsers). So Firefox and other websites (e.g., Gitlab) must be trying the FIDO2 path only or something like that. I guess it is a consequence of how the card ‘talks’, because it works properly for your card.

equaeghe commented 6 months ago

If you want you can try hardcoding line 199 of ctap_hid_bridge.py to 0x00 instead of ctap.capabilities. That will disable all CTAP2 functionality through the bridge.

That indeed makes Firefox behave again as before: I can use the card for 2FA for Github and Gitlab. For Falkon (Chromium-based), the same situation as before exists: Github works, but Gitlab doesn't. So the ~issue is~ issues are

BryanJacobs commented 6 months ago

Your card is returning invalid CTAP CBOR, which is a problem with the card. That should never happen. This is a buggy smartcard.

4: {"plat": false, "rk": true, "clientPin": true, "up": false, "pinUvAuthToken": true, "largeBlobs": true, "authnrCfg": true, "credMgmt": true, "setMinPINLength": true, "makeCredUvNotRqd": true, "alwaysUv": false}

Canonical CBOR requires that map entries be sorted in a particular way. From https://fidoalliance.org/specs/fido-v2.2-rd-20230321/fido-client-to-authenticator-protocol-v2.2-rd-20230321.html#ctap2-canonical-cbor-encoding-form :

The keys in every map MUST be sorted lowest value to highest. The sorting rules are:

    If the major types are different, the one with the lower value in numerical order sorts earlier.

    If two keys have different lengths, the shorter one sorts earlier;

    If two keys have the same length, the one with the lower value in (byte-wise) lexical order sorts earlier.

The response from your authenticator has "plat", four bytes, before "up", two bytes. That is invalid. The RFC says "MUST" so any conformant implementation may reject or fail your card.

I'm sorry but you have a buggy card here. I'd recommend getting one that is not buggy.

BryanJacobs commented 6 months ago

Closing as the cause is identified and workarounds unfeasible.