Yubico / libfido2

Provides library functionality for FIDO2, including communication with a device over USB or NFC.
Other
590 stars 152 forks source link

Making credentials using fido_dev_make_cred: only one algorithm at a time supported #140

Open yami36 opened 4 years ago

yami36 commented 4 years ago

Making credentials using fido_dev_make_cred.

The fido_cred_set_type funcion allows only one algorithm to be set. The standard for pubKeyCredParams https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#authenticatorMakeCredential allows multiple ones.

As we don't have an API to check if an authenticator supports a given algorithm, we are forced to set the algorithm to COSE_ES256

martelletto commented 4 years ago

Hi,

With the current API, your only option is to iterate over the list of preferred algorithms. We will revisit this for libfido2 2.0. With some luck, there will be an API to retrieve the list of supported algorithms by then, and we will be able to keep the credential API simple as it is.

-p.

yami36 commented 4 years ago

I tried to iterate (with uv=FIDO_OPT_FALSE and no pin) but with some authenticator other than YubiKeys (HyperFido, eWMB GoldenGate) user presence is always required.

I added cbor_add_bool(item, "up", false) to cbor_encode_options in cbor.c to circumvent the problem.

Can you add the option "up" to fido_cred_t (same as fido_assert_t) ?

martelletto commented 4 years ago

This sounds a bit strange. Are you excluding credentials, i.e. using fido_cred_exclude()?

yami36 commented 4 years ago

No. I am using the following pattern:

fido_cred_t* cred = fido_cred_new(); fido_cred_set_type(cred, alg) fido_cred_set_clientdata_hash(cred, dummy) fido_cred_set_rp(cred, dummy) fido_cred_set_user(cred, dummy) fido_cred_set_extensions(cred, 0); fido_cred_set_uv(cred, FIDO_OPT_FALSE) fido_dev_make_cred(dev, cred, nullptr);

It works great with some authenticators (YubiKeys, SoloKeys, ...) but not all (HyperFido, eWMB GoldenGate). It seems that "up" in this screnario is authneticator dependent. Hence my request.

martelletto commented 4 years ago

Could you send me the output of FIDO_DEBUG=1 with one of these authenticators (HyperFIDO, eWBM)?

yami36 commented 4 years ago

First detection en print info, then algorithm detection. (start after line with eWBM eWBM Security Key(Goldengate G310)). It takes a few seconds instead of instantaneous

is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len is_fido: unsupported report len tx: d=00BF5288, cmd=0x86, buf=00BF5288, len=8 3a 72 fb 34 c0 bc 2e ab rx: initiation frame at 0095F5AC, len 64 ff ff ff ff 86 00 11 3a 72 fb 34 c0 bc 2e ab 49 ef f2 fa 02 01 01 02 01 ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee tx: d=00BF54D0, cmd=0x86, buf=00BF54D0, len=8 76 7a bf 07 a5 cc c1 51 rx: initiation frame at 0095F5AC, len 64 ff ff ff ff 86 00 11 76 7a bf 07 a5 cc c1 51 00 07 00 08 02 02 08 68 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fido_dev_get_cbor_info_tx: dev=00BF54D0 tx: d=00BF54D0, cmd=0x90, buf=0095F5FB, len=1 04 fido_dev_dummy_get_cbor_info_rx: dev=00BF54D0, ms=-1 rx: initiation frame at 0095F104, len 64 00 07 00 08 90 00 b3 00 a9 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f 5f 32 5f 30 6c 46 49 44 4f 5f 32 5f 31 5f 50 52 45 02 82 6b 63 72 65 64 50 72 6f 74 65 63 74 6b 68 6d 61 63 2d 73 65 63 72 rx: continuation frame at 0095F104, len 64 00 07 00 08 00 65 74 03 50 95 44 2b 2e f1 5e 4d ef b2 70 ef b1 06 fa cb 4e 04 a7 62 72 6b f5 62 75 70 f5 62 75 76 f4 64 70 6c 61 74 f4 69 63 6c 69 65 6e 74 50 69 6e f4 75 63 72 65 64 65 6e 74 rx: continuation frame at 0095F104, len 64 00 07 00 08 01 69 61 6c 4d 67 6d 74 50 72 65 76 69 65 77 f5 78 1b 75 73 65 72 56 65 72 69 66 69 63 61 74 69 6f 6e 4d 67 6d 74 50 72 65 76 69 65 77 f4 05 19 08 00 06 81 01 07 06 08 18 c0 09 81 rx: continuation frame at 0095F104, len 64 00 07 00 08 02 63 75 73 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 rx: buf=0095F3EC, len=179 00 a9 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f 5f 32 5f 30 6c 46 49 44 4f 5f 32 5f 31 5f 50 52 45 02 82 6b 63 72 65 64 50 72 6f 74 65 63 74 6b 68 6d 61 63 2d 73 65 63 72 65 74 03 50 95 44 2b 2e f1 5e 4d ef b2 70 ef b1 06 fa cb 4e 04 a7 62 72 6b f5 62 75 70 f5 62 75 76 f4 64 70 6c 61 74 f4 69 63 6c 69 65 6e 74 50 69 6e f4 75 63 72 65 64 65 6e 74 69 61 6c 4d 67 6d 74 50 72 65 76 69 65 77 f5 78 1b 75 73 65 72 56 65 72 69 66 69 63 61 74 69 6f 6e 4d 67 6d 74 50 72 65 76 69 65 77 f4 05 19 08 00 06 81 01 07 06 08 18 c0 09 81 63 75 73 62 \?\hid#vid_311f&pid_4a1a#7&263bd8fb&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}: vendor=0x311f, product=0x4a1a (eWBM eWBM Security Key(Goldengate G310)) 1 FIDO2 device(s) found tx: d=00C10C60, cmd=0x86, buf=00C10C60, len=8 6b 92 51 5e 7b cc c0 d7 rx: initiation frame at 0095F744, len 64 ff ff ff ff 86 00 11 6b 92 51 5e 7b cc c0 d7 00 07 00 09 02 02 08 68 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fido_dev_get_cbor_info_tx: dev=00C10C60 tx: d=00C10C60, cmd=0x90, buf=0095F793, len=1 04 fido_dev_dummy_get_cbor_info_rx: dev=00C10C60, ms=-1 rx: initiation frame at 0095F29C, len 64 00 07 00 09 90 00 b3 00 a9 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f 5f 32 5f 30 6c 46 49 44 4f 5f 32 5f 31 5f 50 52 45 02 82 6b 63 72 65 64 50 72 6f 74 65 63 74 6b 68 6d 61 63 2d 73 65 63 72 rx: continuation frame at 0095F29C, len 64 00 07 00 09 00 65 74 03 50 95 44 2b 2e f1 5e 4d ef b2 70 ef b1 06 fa cb 4e 04 a7 62 72 6b f5 62 75 70 f5 62 75 76 f4 64 70 6c 61 74 f4 69 63 6c 69 65 6e 74 50 69 6e f4 75 63 72 65 64 65 6e 74 rx: continuation frame at 0095F29C, len 64 00 07 00 09 01 69 61 6c 4d 67 6d 74 50 72 65 76 69 65 77 f5 78 1b 75 73 65 72 56 65 72 69 66 69 63 61 74 69 6f 6e 4d 67 6d 74 50 72 65 76 69 65 77 f4 05 19 08 00 06 81 01 07 06 08 18 c0 09 81 rx: continuation frame at 0095F29C, len 64 00 07 00 09 02 63 75 73 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 rx: buf=0095F584, len=179 00 a9 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f 5f 32 5f 30 6c 46 49 44 4f 5f 32 5f 31 5f 50 52 45 02 82 6b 63 72 65 64 50 72 6f 74 65 63 74 6b 68 6d 61 63 2d 73 65 63 72 65 74 03 50 95 44 2b 2e f1 5e 4d ef b2 70 ef b1 06 fa cb 4e 04 a7 62 72 6b f5 62 75 70 f5 62 75 76 f4 64 70 6c 61 74 f4 69 63 6c 69 65 6e 74 50 69 6e f4 75 63 72 65 64 65 6e 74 69 61 6c 4d 67 6d 74 50 72 65 76 69 65 77 f5 78 1b 75 73 65 72 56 65 72 69 66 69 63 61 74 69 6f 6e 4d 67 6d 74 50 72 65 76 69 65 77 f4 05 19 08 00 06 81 01 07 06 08 18 c0 09 81 63 75 73 62 proto: 0x02 major: 0x02 minor: 0x08 build: 0x68 caps: 0x0d (wink, cbor, nomsg) fido_dev_get_cbor_info_tx: dev=00C10C60 tx: d=00C10C60, cmd=0x90, buf=0095F883, len=1 04 fido_dev_get_cbor_info_rx: dev=00C10C60, ci=00C10FE0, ms=-1 rx: initiation frame at 0095F388, len 64 00 07 00 09 90 00 b3 00 a9 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f 5f 32 5f 30 6c 46 49 44 4f 5f 32 5f 31 5f 50 52 45 02 82 6b 63 72 65 64 50 72 6f 74 65 63 74 6b 68 6d 61 63 2d 73 65 63 72 rx: continuation frame at 0095F388, len 64 00 07 00 09 00 65 74 03 50 95 44 2b 2e f1 5e 4d ef b2 70 ef b1 06 fa cb 4e 04 a7 62 72 6b f5 62 75 70 f5 62 75 76 f4 64 70 6c 61 74 f4 69 63 6c 69 65 6e 74 50 69 6e f4 75 63 72 65 64 65 6e 74 rx: continuation frame at 0095F388, len 64 00 07 00 09 01 69 61 6c 4d 67 6d 74 50 72 65 76 69 65 77 f5 78 1b 75 73 65 72 56 65 72 69 66 69 63 61 74 69 6f 6e 4d 67 6d 74 50 72 65 76 69 65 77 f4 05 19 08 00 06 81 01 07 06 08 18 c0 09 81 rx: continuation frame at 0095F388, len 64 00 07 00 09 02 63 75 73 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 rx: buf=0095F670, len=179 00 a9 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f 5f 32 5f 30 6c 46 49 44 4f 5f 32 5f 31 5f 50 52 45 02 82 6b 63 72 65 64 50 72 6f 74 65 63 74 6b 68 6d 61 63 2d 73 65 63 72 65 74 03 50 95 44 2b 2e f1 5e 4d ef b2 70 ef b1 06 fa cb 4e 04 a7 62 72 6b f5 62 75 70 f5 62 75 76 f4 64 70 6c 61 74 f4 69 63 6c 69 65 6e 74 50 69 6e f4 75 63 72 65 64 65 6e 74 69 61 6c 4d 67 6d 74 50 72 65 76 69 65 77 f5 78 1b 75 73 65 72 56 65 72 69 66 69 63 61 74 69 6f 6e 4d 67 6d 74 50 72 65 76 69 65 77 f4 05 19 08 00 06 81 01 07 06 08 18 c0 09 81 63 75 73 62 parse_reply_element: cbor type parse_reply_element: cbor type parse_reply_element: cbor type version strings: U2F_V2, FIDO_2_0, FIDO_2_1_PRE extension strings: credProtect, hmac-secret aaguid: 95442b2ef15e4defb270efb106facb4e options: rk(yes), up(yes), uv(no), plat(no), clientPin(no), credentialMgmtPreview(yes), userVerificationMgmtPreview(no) maxmsgsiz: 2048 pin protocols: 1 tx: d=00C10C60, cmd=0x90, buf=00BFB4F8, len=122 01 a5 01 58 20 ec 8d 8f 78 42 4a 2b b7 82 34 aa ca 07 a1 f6 56 42 1c b6 f6 b3 00 86 52 35 2d a2 62 4a be 89 76 02 a2 62 69 64 6a 6d 6f 69 40 6d 6f 69 2e 66 72 64 6e 61 6d 65 63 6d 6f 69 03 a2 62 69 64 4f 41 6c 7a 4b 4b 6c 4d 4d 6c 4a 4a 4a 6e 55 53 64 6e 61 6d 65 63 4d 4f 49 04 81 a2 63 61 6c 67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 07 a1 62 75 76 f4 rx: initiation frame at 0095DF2C, len 64 00 07 00 09 90 00 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cbor_parse_reply: blob[0]=0x27 fido_dev_make_cred_rx: parse_makecred_reply tx: d=00C10C60, cmd=0x90, buf=00BFB4F8, len=122 01 a5 01 58 20 ec 8d 8f 78 42 4a 2b b7 82 34 aa ca 07 a1 f6 56 42 1c b6 f6 b3 00 86 52 35 2d a2 62 4a be 89 76 02 a2 62 69 64 6a 6d 6f 69 40 6d 6f 69 2e 66 72 64 6e 61 6d 65 63 6d 6f 69 03 a2 62 69 64 4f 41 6c 7a 4b 4b 6c 4d 4d 6c 4a 4a 4a 6e 55 53 64 6e 61 6d 65 63 4d 4f 49 04 81 a2 63 61 6c 67 27 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 07 a1 62 75 76 f4 rx: initiation frame at 0095DF2C, len 64 00 07 00 09 90 00 01 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cbor_parse_reply: blob[0]=0x26 fido_dev_make_cred_rx: parse_makecred_reply tx: d=00C10C60, cmd=0x90, buf=00BFB4F8, len=124 01 a5 01 58 20 ec 8d 8f 78 42 4a 2b b7 82 34 aa ca 07 a1 f6 56 42 1c b6 f6 b3 00 86 52 35 2d a2 62 4a be 89 76 02 a2 62 69 64 6a 6d 6f 69 40 6d 6f 69 2e 66 72 64 6e 61 6d 65 63 6d 6f 69 03 a2 62 69 64 4f 41 6c 7a 4b 4b 6c 4d 4d 6c 4a 4a 4a 6e 55 53 64 6e 61 6d 65 63 4d 4f 49 04 81 a2 63 61 6c 67 39 01 00 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 07 a1 62 75 76 f4 rx: initiation frame at 0095DF2C, len 64 00 07 00 09 90 00 01 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cbor_parse_reply: blob[0]=0x26 fido_dev_make_cred_rx: parse_makecred_reply fido_dev_make_cred_tx: cdh=00C08260, type=0 Supported algorithms: ES256(-7),ECDH_ES256(-25)

yami36 commented 4 years ago

The detection iterates through { COSE_ES256, COSE_EDDSA, COSE_RS256, COSE_ECDH_ES256 }

martelletto commented 4 years ago

Thank you for the debug info and apologies for my earlier brevity; I was short of time.

Let's first get some things out of the way. The list of steps a FIDO2 authenticator takes when issued with a fido_dev_make_cred() (authenticatorMakeCredential in CTAP2) is defined in https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#authenticatorMakeCredential.

The first step is to check for excluded credentials. That's why I asked about fido_cred_exclude(). The next step is to check for supported algorithms. Note that fido_dev_cred_make_cred() options (rk, uv) are not involved up to this point. What this tells us is that, unless excluded credentials are present, the authenticator ir supposed to return immediately if it does not support the requested algorithm, regardless of options. That is the first oddity in the behaviour you are experiencing.

The eighth step requires the authenticator to wait for user consent. Again, regardless of options. That is the second oddity in the behaviour you are experiencing. If you look at the table of options defined for authenticatorMakeCredential, you will see that only rk and uv are defined. That is the third oddity -- 'up' should not play a role in authenticatorMakeCredential. In fact, I am fairly sure that if you pass 'up' in a authenticatorMakeCredential to a Yubikey, the Yubikey will fail the request with FIDO_ERR_INVALID_OPTION.

Looking at the debug output, assuming you did not interact with the authenticator at any point, and that the authenticator only supports COSE_ES256, the authenticator's behaviour seems correct to me: the fido_dev_make_cred() call with COSE_ES256 fails with FIDO_ERR_OPERATION_DENIED in the eighth step, and the requests with COSE_EDDSA and COSE_RS256 fail in the second step with FIDO_ERR_UNSUPPORTED_ALGORITHM as the algorithms are not supported.

yami36 commented 4 years ago

You're right, it's fast if I add cbor_add_bool(item, "up", FIDO_OPT_FALSE) to cbor_encode_options because it returns FIDO_ERR_INVALID_OPTION

version strings: U2F_V2, FIDO_2_0, FIDO_2_1_PRE extension strings: credProtect, hmac-secret aaguid: 95442b2ef15e4defb270efb106facb4e options: rk(yes), up(yes), uv(no), plat(no), clientPin(no), credentialMgmtPreview(yes), userVerificationMgmtPreview(no) maxmsgsiz: 2048 pin protocols: 1 tx: d=013AE208, cmd=0x90, buf=0139A9A0, len=126 01 a5 01 58 20 ec 8d 8f 78 42 4a 2b b7 82 34 aa ca 07 a1 f6 56 42 1c b6 f6 b3 00 86 52 35 2d a2 62 4a be 89 76 02 a2 62 69 64 6a 6d 6f 69 40 6d 6f 69 2e 66 72 64 6e 61 6d 65 63 6d 6f 69 03 a2 62 69 64 4f 41 6c 7a 4b 4b 6c 4d 4d 6c 4a 4a 4a 6e 55 53 64 6e 61 6d 65 63 4d 4f 49 04 81 a2 63 61 6c 67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 07 a2 62 75 76 f4 62 75 70 f4 rx: initiation frame at 010FDD54, len 64 00 07 00 0f 90 00 01 2c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cbor_parse_reply: blob[0]=0x2c

But it detects the right algorithms.

From the output I sent before (ie without forcing up to false) I've marked where I had to wait for 10 seconds while the authenticator winks.

version strings: U2F_V2, FIDO_2_0, FIDO_2_1_PRE extension strings: credProtect, hmac-secret aaguid: 95442b2ef15e4defb270efb106facb4e options: rk(yes), up(yes), uv(no), plat(no), clientPin(no), credentialMgmtPreview(yes), userVerificationMgmtPreview(no) maxmsgsiz: 2048 pin protocols: 1 tx: d=00C9DE18, cmd=0x90, buf=00C8B518, len=122 01 a5 01 58 20 ec 8d 8f 78 42 4a 2b b7 82 34 aa ca 07 a1 f6 56 42 1c b6 f6 b3 00 86 52 35 2d a2 62 4a be 89 76 02 a2 62 69 64 6a 6d 6f 69 40 6d 6f 69 2e 66 72 64 6e 61 6d 65 63 6d 6f 69 03 a2 62 69 64 4f 41 6c 7a 4b 4b 6c 4d 4d 6c 4a 4a 4a 6e 55 53 64 6e 61 6d 65 63 4d 4f 49 04 81 a2 63 61 6c 67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 07 a1 62 75 76 f4 // STUCK HERE FOR 10 seconds // authenticator Winks
rx: initiation frame at 0056DF90, len 64 00 07 00 0b 90 00 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cbor_parse_reply: blob[0]=0x27

For the moment, I am not going to detect the supported algorithms. COSE_RS256 is deprecated and COSE_EDDSA is supported by none of my test devices.

Thank you for your time.

Treeston commented 2 years ago

I am encountering the original issue while attempting to implement a WebAuthN client using libfido2. To work around this shortcoming, I am looking to retrieve the list of supported algorithms from the device, then find the first supported algorithm myself.

However, for compatibility reasons, I need to support the version of libfido2 that is available through the default repositories for Ubuntu 20.04 LTS. This version does not yet expose the fido_cbor_info_algorithm_ functions.

Does libfido2 expose the raw CBOR data returned from CTAP_CBOR_GETINFO in a portable manner? Is there some other way to obtain the supported algorithm list?

Treeston commented 2 years ago

For completeness' sake: Ubuntu 20.04 LTS includes libfido2.so.1.3.1.

LDVG commented 2 years ago

Hi @Treeston,

Does libfido2 expose the raw CBOR data returned from CTAP_CBOR_GETINFO in a portable manner? Is there some other way to obtain the supported algorithm list?

I'm afraid not; the raw CBOR is not kept after parsing.

Treeston commented 2 years ago

So there is no way to obtain supported-algorithm information in the version listed above, then? I'd be stuck with trial-and-error iteration -- which, as previously mentioned, has some pitfalls with some authenticator models?

(Not intending to blame anyone, just trying to evaluate where I stand. Thanks for your response!)

LDVG commented 2 years ago

So there is no way to obtain supported-algorithm information in the version listed above, then? I'd be stuck with trial-and-error iteration -- which, as previously mentioned, has some pitfalls with some authenticator models?

Correct. I should also note that the algorithms member of the authenticatorGetInfo response structure is a CTAP 2.1 addition. Older CTAP 2.0 authenticators return a structure without this data (and fido_cbor_info_algorithm_count() returns zero).

Behaqi commented 1 year ago

Tolong ajari saya cara menggunakan nya