Yubico / yubikit-android

Yubico Mobile Android SDK - YubiKit
Apache License 2.0
109 stars 40 forks source link

Challenge-response command doesn't wait for button press on USB #3

Closed jefftharris closed 4 years ago

jefftharris commented 4 years ago

I am attempting to use the challege-response feature of a Yubikey with the Yubikit library to work transparently over NFC and USB. My app is able to use the challenge-response method successfully using Android's built-in NFC library. I'm attempting to add USB support as well.

Upon discovery of a Yubikey NEO over USB, I select the OTP AID and issue the challenge-response command with the Apdu(0x00, 0x01, 0x38, 0x00) using slot 2 and the bytes to hash. Most of the time, the command returns a 0x6985 error code which seems to be a 'conditions not satisfied' error. Sometimes, if I repeat the command and attempt to press or hold the button, the command succeeds with the correct hash value. I'm not able to determine a reliable sequence of holding or pressing the button to get a successful result.

Logs with the failure:

22 bytes sent over ccid: 6f 0c 00 00 00 00 71 00 00 00 00 a4 04 00 07 a0 00 00 05 27 20 01 
22 bytes received: 80 0c 00 00 00 00 71 00 00 00 03 02 00 03 87 07 02 00 00 00 90 00 
28 bytes sent over ccid: 6f 12 00 00 00 00 72 00 00 00 00 01 38 00 0d 74 00 65 00 73 00 74 00 31 00 32 00 33 
12 bytes received: 80 02 00 00 00 00 72 00 00 00 69 85 

Logs with success:

22 bytes sent over ccid: 6f 0c 00 00 00 00 05 00 00 00 00 a4 04 00 07 a0 00 00 05 27 20 01 
22 bytes received: 80 0c 00 00 00 00 05 00 00 00 03 02 00 03 87 07 02 00 00 00 90 00 
28 bytes sent over ccid: 6f 12 00 00 00 00 06 00 00 00 00 01 38 00 0d 74 00 65 00 73 00 74 00 31 00 32 00 33 
32 bytes received: 80 16 00 00 00 00 06 00 00 00 54 ba b2 b8 98 65 6f 2f 67 bb a2 11 c5 3b de f5 64 c8 5b 34 90 00 
imakhalova commented 4 years ago

Hey @jefftharris ,

Thank you so much for your feedback. I'm glad to hear that you trying to use this Android SDK. But using CCID interface for challenge-response feature of YubiKey USB device is NOT what I would suggest. And it's even disabled on YubiKey 5 Series for security reasons. This feature works nice using HID (specifically HID keyboard) interface.

This SDK currently doesn't provide the implementation for the challenge-response application, but I can share some version with you within a couple of weeks (if you'd like to give it a try).

FYI, I was able to reproduce your issue on YK NEO. The issue is gone on YK4.

jefftharris commented 4 years ago

Before trying this SDK, I did attempt to use the USB HID interface directly following the messages used by the Linux C SDKs. I ended up in the same place where the button press was unreliable.

Maybe I'll try a newer key to see how it works. I've been using the NFC interface on the NEO for a while in my app, PasswdSafe. People have been asking to support the keys without NFC.

If I use my NEO on Linux, the challenge-response application works reliably with the button to wait for the press. Also, on Android without my app, the button works fine to type the OTP key. With my app, the button becomes unreliable. I do notice in the log that Android is unregistering the keyboard input device for the key when the app claims the USB interface. Is there something in that process which makes the button unreliable perhaps?

imakhalova commented 4 years ago

Can you share please what was the issue when you used HID interface? Did it work in case if challenge-response does not require touch? Which interface are you using on Linux: CCID or HID?

jefftharris commented 4 years ago

I was following the code used by the ykchalresp program from the yubikey-personalization package. It uses the HID interface with the get/set report requests. When polling for the key status to indicate a response to the hash request, it never indicated that the response was ready.

Other commands like reading the serial number and such which do not require a key press are successful immediately.

imakhalova commented 4 years ago

Hey @jefftharris , Yes, ykchalresp is great resource to see what report requests need to be sent and received.

Here is my implementation of challenge-response (https://github.com/Yubico/yubikit-android/pull/4) for Android. Can you take a look at it please. It has readme on how to use it. And also you can checkout this branch and try out demo. I also deployed this version to maven but under snapshots for now. Within your project you can try version 1.0.0-beta04-SNAPSHOT (yubikit and mgmt - libraries that required for challenge-response). Using snapshots from maven central requires also to add this in your app build.gradle before naming dependencies

repositories {
    ....
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots"
    }
    ...
}

Early feedback can help me to release to maven with confidence.

jefftharris commented 4 years ago

I was able to try the updates with my 4 NEO and a new 5 NFC. I had to pull down the code and build the libraries manually. The snapshot files in maven had sources for the merged changes but the class jars didn't have the updates. Regardless, building manually worked fine.

I was able to use the USB support on the 5 NFC with and without touch being required. For the 4 NEO, it would only work without touch enabled. Is there a set of known key types that will not function with the touch enabled? Is it just the NEO or any v4 key? I'll need to inform users of the key settings that would be required.

So, good news I have a path forward with enabling support for the USB keys. Will there be an official beta04 release where I could use the maven dependency?

imakhalova commented 4 years ago

I'm glad to hear that this change worked well for you, thank you for verification.

I re-uploaded snapshot and verified whether app builds using it. So it should work now (though it might fail for you bcz the Android Studio caches libraries with the same version).

Can you please share what is your experience with NEO YuiKey? Also please share firmware version of the key that doesn't work properly. Does it timeout and not returns anything? Or it fails to use HID and fallbacks to use CCID? FYI I've tested challenge-response with touch on NEO using this demo and it works. So I'd need more details on what fails for you to help to workaround it.

Yes, it's going to be part of beta04 release. Most probably by the end of this week.

jefftharris commented 4 years ago

The NEO has been working great with my old NFC implementation. With USB and configured to require touch, it almost never recognizes the button touch when I start sending the HID or CCID commands to do the challenge-response hash. Rarely, while the code is retrying, it will register the touch, but I can't find any pattern on how to make it work (how fast to push, push-and-hold, etc.).

With the HID method, the response feature report never indicates that the response is ready. The sequence number continues to count down. Likewise with CCID, the response is always that 0x6985 value indicating that a touch is needed.

Turning off the configuration to use touch, both methods succeed immediately.

My NEO is using firmware 3.2.0.

I likely won't get back to the project until the weekend, so I'll get the beta04 release then or sync the project and rebuild locally.

imakhalova commented 4 years ago

I've got NEO with 3.4.9 and it works with touch. Beta04 with Challenge-response feature is out. Closing issue because it is not SDK related and it's not reproducible on older firmware.