Skip to content
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

U2F registration fails (FIDO2 works) #498

Open
DigitalBrains1 opened this issue Feb 2, 2024 · 4 comments
Open

U2F registration fails (FIDO2 works) #498

DigitalBrains1 opened this issue Feb 2, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@DigitalBrains1
Copy link

This issue report stems from this comment. While FIDO2 works fine, it seems the older U2F fails where a different device, a NitroKey 3, works fine.

I installed libu2f-server and libu2f-host, simply by installing the Debian bookworm/stable packages, versions 1.1.0-4+b1 (u2f-server) and 1.1.10-3 (u2f-host).

These two programs should allow you to register a U2F device and have it validate authentication challenges, and it works with the Nitrokey 3. However, with the Precursor, it cannot be registered, the u2f-host program that talks to the device gives an error

error (-2): error in transport layer

Here is how to reproduce, and I also included USB traffic dumps for both Precursor and Nitrokey.

Generate challenge

The following invocation will make u2f-server generate a registration challenge, save the key handle to keyhandle-precursor.dat and the user key to userkey-precursor.dat:

$ u2f-server -aregister -o https://example.org -i https://example.org -k keyhandle-precursor.dat -p userkey-precursor.dat

This will print to stdout some JSON:

{ "challenge": "-736B0R1cxJXorY77D3dp1T3ovnvj5pppwGAt-xxQmE", "version": "U2F_V2", "appId": "https:\/\/example.org" }

Note that for exact reproduction, you can make it reuse that exact challenge again by passing it in with -c "[...challenge...]" as such:

$ u2f-server -aregister -o https://digitalbrains.com -i https://digitalbrains.com -k keyhandle-precursor.dat -p userkey-precursor.dat -c "-736B0R1cxJXorY77D3dp1T3ovnvj5pppwGAt-xxQmE"

Pass challenge to Precursor

Invoke u2f-host as:

$ u2f-host -aregister -o https://example.org

and then copy-paste the JSON output by u2f-server on stdin of the u2f-host process. End with a newline and EOF (Ctrl-D).

The Precursor will now prompt:
image

Clicking accept will make u2f-host error out:

error (-2): error in transport layer

at which point you cannot continue with registration. The USB conversation between u2f-host and the Precursor, as captured by Wireshark, should be this:
precursor-u2f-register-fail.pcapng.gz

Pass challenge to Nitrokey

Again, invoke u2f-host as:

$ u2f-host -aregister -o https://digitalbrains.com

and then copy-paste the JSON output by u2f-server on stdin of the u2f-host process. End with a newline and EOF (Ctrl-D). I used the exact same challenge as for the Precursor.

The Nitrokey starts to blink, touch it.

u2f-host outputs some JSON on stdout:

{ "registrationData": "BQTjF9hE8yPDZdhLuLcPmZSotCH942Alte4MQRhmjifdh6huMTdPLVXFC9uJNaPs8NH4vTx8PQC3Px8nNZ5z0wj_tqMAWJIDZkGxCfKIG-fb0TrB_pvHyT6m_vFFndxkYmCtXohO--CnlBtGJYLXaJ5KnHZIG93eqbRZSHnx0PbSRfT6F2p7wuITYF8xOPz4XyzYfUV4rhJv_3btbHT8dwJS4VglAtBBzGdM1_2q6np2fD33p0kPF66mIm26GziBEwTFBCOhQAjAbvbJK-6l-ZFOsiATRKQ7XwFMRsY2Gfs3Ir8TzJG0AlDc-I7Rmgx0C1dRv-oIPbLnMIICLjCCAdSgAwIBAgIEAMzMzDAKBggqhkjOPQQDAjA5MQswCQYDVQQGEwJERTEWMBQGA1UECgwNTml0cm9rZXkgR21iSDESMBAGA1UEAwwJRklETyBDQSAzMCAXDTIyMDQwNjExMjUyOFoYDzIwNzIwMzI0MTEyNTI4WjBtMQswCQYDVQQGEwJERTEWMBQGA1UECgwNTml0cm9rZXkgR21iSDEiMCAGA1UECwwZQXV0aGVudGljYXRvciBBdHRlc3RhdGlvbjEiMCAGA1UEAwwZTml0cm9rZXkgRklETyBBdHRlc3RhdGlvbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCq6VUCC4Of2hGSyM7O9_uw4B_-pcLgYnFLQllKGO5wmK1I9sNNMpW-ubz52uyMOMUr7hbuuiZBZZj-dBD0ijaCjgZMwgZAwHQYDVR0OBBYEFDOBXdHoZV9fBKa27eCRiBPdwhnJMB8GA1UdIwQYMBaAFMFz5URWwMhuWGifn2LOKMiRlXYkMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMCEGCysGAQQBguUcAQEEBBIEEOyZ2xnNH0wGoqmUDxemowswEwYLKwYBBAGC5RwCAQEEBAMCBDAwCgYIKoZIzj0EAwIDSAAwRQIhAIcFpLaFPfU3XV-pA0ePZrpdukN06yOAijhpXnzGHO8IAiA8-1RKaNurtgplX5IYG4V9pPYcTgrVvdzfOmHZDS_JqDBGAiEAnpEA3G9YicGaha1ZjaSnC2qITmDXUfcD1yxhloDSOj8CIQDcfPNwX9DA6KOvs_MQACHc6BxWOX59PP_A5-RuuA98EA", "clientData": "eyAiY2hhbGxlbmdlIjogIi03MzZCMFIxY3hKWG9yWTc3RDNkcDFUM292bnZqNXBwcHdHQXQteHhRbUUiLCAib3JpZ2luIjogImh0dHBzOlwvXC9leGFtcGxlLm9yZyIsICJ0eXAiOiAibmF2aWdhdG9yLmlkLmZpbmlzaEVucm9sbG1lbnQiIH0" }

(I did it twice with the same challenge. registrationData changed, clientData stayed the same)

I am hoping that the following capture by Wireshark is the correct conversation for this exact response:
nitrokey-u2f-success.pcapng.gz

Finish registration of Nitrokey

Paste the JSON that u2f-host outputted on stdin of the still running u2f-server process, ending in newline and EOF. u2f-host will reply:

Registration successful

and will save the credentials in the two files: key handle and user key.

Authenticate with Nitrokey

Very similar to the steps we did up to now, but instead of -aregister we now do -aauthenticate and the files are now input instead of output.

$ u2f-server -aauthenticate -o https://digitalbrains.com -i https://digitalbrains.com -k keyhandle-nitrokey.dat -p userkey-nitrokey.dat 

gives us some JSON:

{ "keyHandle": "owBYkgNmQbEJ8ogb59vROsH-m8fJPqb-8UWd3GRiYK1eiE774KeUG0Ylgtdonkqcdkgb3d6ptFlIefHQ9tJF9PoXanvC4hNgXzE4_PhfLNh9RXiuEm__du1sdPx3AlLhWCUC0EHMZ0zX_arqenZ8PfenSQ8XrqYibbobOIETBMUEI6FACMBu9skr7qX5kU6yIBNEpDtfAUxGxjYZ-zcivxPMkbQCUNz4jtGaDHQLV1G_6gg9suc", "version": "U2F_V2", "challenge": "Ni590tN3zf-MJmkZD9cArRXH5P5tetfAWWvv6YRF9sw", "appId": "https:\/\/example.org" }
u2f-host -aauthenticate  -o https://example.org

Paste the JSON from u2f-server into u2f-host as before, touch the Nitrokey, and u2f-host will output the challenge response:

{ "signatureData": "AQAAAIcwRgIhAPatcIRyUp7u8wpf7BKZGLvcQ8YtWiA6FWBp1BKr5VzBAiEA-SKkkF6bDijVNnStKFycqrWsPm_2ARO07IhpuV2HnxY", "clientData": "eyAiY2hhbGxlbmdlIjogIk5pNTkwdE4zemYtTUpta1pEOWNBclJYSDVQNXRldGZBV1d2djZZUkY5c3ciLCAib3JpZ2luIjogImh0dHBzOlwvXC9leGFtcGxlLm9yZyIsICJ0eXAiOiAibmF2aWdhdG9yLmlkLmdldEFzc2VydGlvbiIgfQ", "keyHandle": "owBYkgNmQbEJ8ogb59vROsH-m8fJPqb-8UWd3GRiYK1eiE774KeUG0Ylgtdonkqcdkgb3d6ptFlIefHQ9tJF9PoXanvC4hNgXzE4_PhfLNh9RXiuEm__du1sdPx3AlLhWCUC0EHMZ0zX_arqenZ8PfenSQ8XrqYibbobOIETBMUEI6FACMBu9skr7qX5kU6yIBNEpDtfAUxGxjYZ-zcivxPMkbQCUNz4jtGaDHQLV1G_6gg9suc" }

Paste that back again to u2f-server and it will say:

Successful authentication, counter: 135, user presence 1

I suspect that with all this data, people might be able to pose as the https://example.org server to my Nitrokey. But that server is not going to exist and it seems like a weird attacker model anyway; what should protect me from people posing as example.org is a signed SSL certificate, not this exchange above. Still, I decided not to use a real hostname.

@DigitalBrains1
Copy link
Author

DigitalBrains1 commented Feb 2, 2024

Ah. This is with latest bleeding edge:

ver xous
Xous version: v0.9.15-459-g38855960
Thu, 01 Feb 2024 13:55:23 +0800

But it doesn't work with the stable release either. I just thought you'd prefer testing with bleeding edge.

@bunnie
Copy link
Member

bunnie commented Feb 3, 2024

Thank you for the incredibly detailed notes. This will help debugging it more later.

As I mentioned elsewhere, I might de-prioritize this until this actually is a blocker for someone's workflow -- at the moment slogging through upgrading the crypto APIs to support the Signal client effort.

@bunnie bunnie added the bug Something isn't working label Feb 3, 2024
@DigitalBrains1
Copy link
Author

Yes, in practice the places where I actually use Precursor with FIDO work fine, so this issue might not be a problem for anyone.

at the moment slogging through upgrading the crypto APIs to support the Signal client effort.

Operator: We get signal.
Captain: What !
Operator: Main screen turn on.

:-D Good luck!

@bunnie
Copy link
Member

bunnie commented Feb 3, 2024

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants