Yubico / Yubico.NET.SDK

A YubiKey SDK for .NET developers
Apache License 2.0
99 stars 47 forks source link

FIDO2 MakeCredential Failed #50

Closed ismayandi closed 1 year ago

ismayandi commented 1 year ago

Hi Yubico, I'm encoutering the problem when trying to run example code from the yesdk fido2 documentation. The keycollector delegate always point to KeyEntryRequest.VerifyFido2Pin request. After 3 times input the PIN (i had set this before using YubiKey Manager), i got this exception Yubico.YubiKey.Fido2.Fido2Exception: 'The comand failed to complete.'

Here is the stacktrace : at Yubico.YubiKey.Fido2.Fido2Session.TryVerifyPin(ReadOnlyMemory1 currentPin, Nullable1 permissions, String relyingPartyId, Nullable1& retriesRemaining, Nullable1& rebootRequired) at Yubico.YubiKey.Fido2.Fido2Session.TryVerifyPin(Nullable1 permissions, String relyingPartyId) at Yubico.YubiKey.Fido2.Fido2Session.VerifyPin(Nullable1 permissions, String relyingPartyId) at Yubico.YubiKey.Fido2.Fido2Session.AddPermissions(PinUvAuthTokenPermissions permissions, String relyingPartyId) at Yubico.YubiKey.Fido2.Fido2Session.GetAuthToken(Boolean forceNewToken, PinUvAuthTokenPermissions permissions, String relyingPartyId) at Yubico.YubiKey.Fido2.Fido2Session.MakeCredential(MakeCredentialParameters parameters)

My app is targeting .NET6.0, and will run on Linux machine. But currently i'm trying it on windows first. If there is further guide about this topic, that's would be great. Thanks in advance.

GregDomzalski commented 1 year ago

It sounds like PIN collection is not working properly.

The YubiKey will require a reboot (of the key) prior to allowing more than 3 consecutive PIN retries. That is likely what the exception you are getting is trying to tell you.

Are you remembering to convert your PIN from string form to byte form using Encodings.UTF8.GetBytes() or something similar? If your PIN is "123456" in YubiKey Manager, the value you should pass to the key collector is the result of Encodings.UTF8.GetBytes("123456") and not byte[] { 1, 2, 3, 4, 5, 6 }

ismayandi commented 1 year ago

Hi Greg, Thanks for your respons, i'm currently using the utility from Yubico.Core.Buffers namesapce , or should i use UTF8 encoding instread? and if it succeed, is there any information from the MakeCredential() method that i should save, so i can use it in GetAssertion() method? From my understanding after reading the documentation, GetAssertionParameter only need two parameters (relying party and clientdatahash), and user presence to touch the key.

But i will try your suggestion and report it soon. (my office is in long weekend mode now :D).

here is the snippet code i'm currently use for demo.

case KeyEntryRequest.VerifyFido2Pin:
                    {
                        Console.WriteLine($"Enter your PIN and hit enter: ");
                        string input = Console.ReadLine();
                        arg.SubmitValue(Hex.HexToBytes(input).ToArray()); 
                        return true;
                    }

Thanks.

GregDomzalski commented 1 year ago

Yes. You almost certainly should be using Encoding.UTF8.GetBytes. That is what would match the YubiKey Manager behavior.

I don't believe you will need anything from MakeCredential in GetAssertion for most cases. However, you do need to send the MakeCredentialData back to whatever system is acting as your "Relying Party" in order to verify that the credential creation was successful and no alterations or tampering has occurred.

You can read more about the FIDO2/Webauthn flow from the relying party's perspective here: https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred

ismayandi commented 1 year ago

OK, thanks Greg, i get it now. I'll close this issue for now.