keys-pub / go-libfido2

libfido2 bindings for golang
https://keys.pub
Other
72 stars 22 forks source link

Verifying assertion #27

Open i0x71 opened 3 years ago

i0x71 commented 3 years ago

Hi, Do you have any examples or pointers on verifying assertion ? If i understand correctly, AuthDataCBOR needs to be decoded from CBOR, but im unsure how to parse the data structure is inside. Also since there is no challenge being generated when we make the assertion, what do we verify ? Do i also need to ed25519.Verify something using .Sig and the public key ?

I was under assumption that there is random challenge that gets provided to the token, which then returns the encrypted challenge which gets verified afterwards.

Thanks in advance!

gabriel commented 3 years ago

I've only used the hmac-secret extension part, so I'm not sure. The library is meant to wrap and follow the libfido2 library as closely as possible, so you might want to look there?

prateeknischal commented 1 year ago

FWIW, I saw a strange thing parsing AuthDataCBOR. So, For v1.5.3 of go-libfido2, the auth data from an assertion is released as,

58 25 accf5d46ee3936b66555503d0548a9fcb63901f5eeb53547c7dc59cf2a31caac 05 0000029d

58 25                                   # bytes(37)
   ACCF5D46EE3936B66555503D0548A9FCB63901F5EEB53547C7DC59CF2A31CAAC050000029D # "\xAC\xCF]F\xEE96\xB6eUP=\u0005H\xA9\xFC\xB69\u0001\xF5\xEE\xB55G\xC7\xDCY\xCF*1ʬ\u0005\u0000\u0000\u0002\x9D"

Where 58 - Haven't read the RFC well enough to identify this byte, it's some sort of indicator of the incoming structure 25 - The length of bytes in this container acc..aac - The SHA256 of the relying party 05 - The flags passed 29d - a 4 byte assertion counter

This is all fine, but for the same yubikey, when I try to get assertions via python-fido2 and libfido2, I see that the auth data bytes are released as,

accf5d46ee3936b66555503d0548a9fcb63901f5eeb53547c7dc59cf2a31caac 05 0000029d

Notice that the first 2 bytes are missing. I looked around and this seems like the diagnostic representation, without the header. I am not sure if this is intentional for fido2. From what I can tell, the go-libfido2 is doing what's write with annotating the type and length before the value.

What's more confusing is that, from the code, all I see is CGO passing the bytes to Go from the libfido2 bindings. So supposedly Go runtime isn't doing anything funky with the output.

I had faced similar problem when trying to decode the public key exported from libfido2. The EC256 points were just stacked on top of each other without any information or encoding. I had to add a byte to tell the Go stdlib that it's an EC key and is in the uncompressed format with the 0x04 preceding byte.

prateeknischal commented 1 year ago

So I went around the libfido2 code, I think the data serialization on the interface between the security key and the platform is CBOR. The platform can then decide to do whatever with it. So, assuming that the output from libfido2 is CBOR is incorrect. The question still remains though, how is go-libfido2 producing valid CBOR with type and length information when it's just FFI calling libfido2.