Yubico / yubikey-manager

Python library and command line tool for configuring any YubiKey over all USB interfaces.
https://developers.yubico.com/yubikey-manager/
BSD 2-Clause "Simplified" License
877 stars 124 forks source link

yubikey 4 stuck in CCID mode, can't get out #448

Closed ghost closed 3 years ago

ghost commented 3 years ago

Steps to reproduce

$ pcsc_scan
Using reader plug'n play mechanism
Scanning present readers...
0: Yubico YubiKey CCID 00 00

Thu Aug 19 10:05:35 2021
 Reader 0: Yubico YubiKey CCID 00 00
  Event number: 0
  Card state: Card inserted, 
  ATR: 3B F8 13 00 00 81 31 FE 15 59 75 62 69 6B 65 79 34 D4

ATR: 3B F8 13 00 00 81 31 FE 15 59 75 62 69 6B 65 79 34 D4
+ TS = 3B --> Direct Convention
+ T0 = F8, Y(1): 1111, K: 8 (historical bytes)
  TA(1) = 13 --> Fi=372, Di=4, 93 cycles/ETU
    43010 bits/s at 4 MHz, fMax for Fi = 5 MHz => 53763 bits/s
  TB(1) = 00 --> VPP is not electrically connected
  TC(1) = 00 --> Extra guard time: 0
  TD(1) = 81 --> Y(i+1) = 1000, Protocol T = 1 
-----
  TD(2) = 31 --> Y(i+1) = 0011, Protocol T = 1 
-----
  TA(3) = FE --> IFSC: 254
  TB(3) = 15 --> Block Waiting Integer: 1 - Character Waiting Integer: 5
+ Historical bytes: 59 75 62 69 6B 65 79 34
  Category indicator byte: 59 (proprietary format)
+ TCK = D4 (correct checksum)

Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
3B F8 13 00 00 81 31 FE 15 59 75 62 69 6B 65 79 34 D4
    Yubico Yubikey 4 OTP+CCID

Using ykman:

$ ykman list
YubiKey 4 [CCID] <access denied>
$ ykman list --readers
Yubico YubiKey CCID 00 00
$ ykman list --serials
$ ykman config mode "OTP+FIDO+CCID"
Error: 'utf-8' codec can't decode byte 0x90 in position 30: invalid start byte

Expected result

switch back to OTP/FIDO/CCID mode.

Actual results and logs

Error message. I tried this on Fedora 34, Debian 11 and macOS 11, always the same error message.

dainnilsson commented 3 years ago

Can you provide the output of running ykman --log-level debug config mode "OTP+FIDO+CCID" as well as the output of ykman --diagnose?

ghost commented 3 years ago
$ ykman --log-level debug config mode "OTP+FIDO+CCID"
2021-08-19T10:12:31+0200 INFO [ykman.logging_setup.setup:76] Initialized logging for level: DEBUG
2021-08-19T10:12:31+0200 INFO [ykman.logging_setup.setup:77] Running ykman version: 4.0.5
2021-08-19T10:12:31+0200 DEBUG [ykman.logging_setup.log_sys_info:48] Python: 3.9.6 (default, Jul 16 2021, 00:00:00) 
[GCC 11.1.1 20210531 (Red Hat 11.1.1-3)]
2021-08-19T10:12:31+0200 DEBUG [ykman.logging_setup.log_sys_info:49] Platform: linux
2021-08-19T10:12:31+0200 DEBUG [ykman.logging_setup.log_sys_info:50] Arch: x86_64
2021-08-19T10:12:31+0200 DEBUG [ykman.logging_setup.log_sys_info:56] Running as admin: False
2021-08-19T10:12:31+0200 DEBUG [ykman.pcsc.send_and_receive:118] SEND: 00a4040008a000000527471117
2021-08-19T10:12:31+0200 DEBUG [ykman.pcsc.send_and_receive:120] RECV: 5669727475616c206d6772202d2046572076657273696f6e20342e312e319000 SW=9000
2021-08-19T10:12:31+0200 ERROR [ykman.cli.__main__.retrying_connect:93] Failed opening connection
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/ykman/cli/__main__.py", line 88, in retrying_connect
    return connect_to_device(serial, connections)
  File "/usr/lib/python3.9/site-packages/ykman/device.py", line 221, in connect_to_device
    info = read_info(dev.pid, conn)
  File "/usr/lib/python3.9/site-packages/ykman/device.py", line 445, in read_info
    info = _read_info_ccid(conn, key_type, interfaces)
  File "/usr/lib/python3.9/site-packages/ykman/device.py", line 278, in _read_info_ccid
    mgmt = ManagementSession(conn)
  File "/usr/lib/python3.9/site-packages/yubikit/management.py", line 418, in __init__
    self.backend = _ManagementSmartCardBackend(connection)
  File "/usr/lib/python3.9/site-packages/yubikit/management.py", line 357, in __init__
    select_str = self.protocol.select(AID.MANAGEMENT).decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x90 in position 30: invalid start byte
2021-08-19T10:12:31+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:32+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:32+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:33+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:33+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:34+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:34+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:35+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:35+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:36+0200 DEBUG [ykman.cli.__main__.retrying_connect:101] Sleep...
2021-08-19T10:12:36+0200 ERROR [ykman.cli.__main__.main:379] Error
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/ykman/cli/__main__.py", line 371, in main
    cli(obj={})
  File "/usr/lib/python3.9/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.9/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3.9/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.9/site-packages/click/decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/lib/python3.9/site-packages/ykman/cli/config.py", line 598, in mode
    info = ctx.obj["info"]
  File "/usr/lib/python3.9/site-packages/ykman/cli/util.py", line 164, in __getitem__
    self.resolve()
  File "/usr/lib/python3.9/site-packages/ykman/cli/util.py", line 161, in resolve
    self._objects[k] = f()
  File "/usr/lib/python3.9/site-packages/ykman/cli/__main__.py", line 299, in <lambda>
    ctx.obj.add_resolver("conn", lambda: resolve()[0])
  File "/usr/lib/python3.9/site-packages/ykman/cli/__main__.py", line 294, in resolve
    items = _run_cmd_for_single(ctx, subcmd.name, connections, reader)
  File "/usr/lib/python3.9/site-packages/ykman/cli/__main__.py", line 190, in _run_cmd_for_single
    return retrying_connect(None, connections, state=state)
  File "/usr/lib/python3.9/site-packages/ykman/cli/__main__.py", line 88, in retrying_connect
    return connect_to_device(serial, connections)
  File "/usr/lib/python3.9/site-packages/ykman/device.py", line 221, in connect_to_device
    info = read_info(dev.pid, conn)
  File "/usr/lib/python3.9/site-packages/ykman/device.py", line 445, in read_info
    info = _read_info_ccid(conn, key_type, interfaces)
  File "/usr/lib/python3.9/site-packages/ykman/device.py", line 278, in _read_info_ccid
    mgmt = ManagementSession(conn)
  File "/usr/lib/python3.9/site-packages/yubikit/management.py", line 418, in __init__
    self.backend = _ManagementSmartCardBackend(connection)
  File "/usr/lib/python3.9/site-packages/yubikit/management.py", line 357, in __init__
    select_str = self.protocol.select(AID.MANAGEMENT).decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x90 in position 30: invalid start byte
Error: 'utf-8' codec can't decode byte 0x90 in position 30: invalid start byte
$ ykman --diagnose
ykman: 4.0.5
Python: 3.9.6 (default, Jul 16 2021, 00:00:00) 
[GCC 11.1.1 20210531 (Red Hat 11.1.1-3)]
Platform: linux
Arch: x86_64
Running as admin: False

Detected PC/SC readers:
    Yubico YubiKey CCID 00 00 (connect: Success)

Detected YubiKeys over PC/SC:
    ScardYubiKeyDevice(pid=0404, fingerprint='Yubico YubiKey CCID 00 00')
    Failed to read device info via Management: UnicodeDecodeError('utf-8', b'Virtual mgr - FW version 4.1.1\x90\x00', 30, 31, 'invalid start byte')
    Failed to read device info: UnicodeDecodeError('utf-8', b'Virtual mgr - FW version 4.1.1\x90\x00', 30, 31, 'invalid start byte')
    PIV not accessible ApplicationNotAvailableError()
    OATH not accessible ApplicationNotAvailableError()
    OpenPGP not accessible ApplicationNotAvailableError()

Detected YubiKeys over HID OTP:

Detected YubiKeys over HID FIDO:
End of diagnostics
dainnilsson commented 3 years ago

The firmware version (4.1.1) indicates that that device is a YubiKey Edge, which doesn't support any CCID applications. It does however contain a partial CCID implementation (disabled by default) which isn't fully understood by ykman. You'll want to change the mode to OTP+FIDO (without CCID) to prevent the non-functional CCID interface from causing problems for ykman.

Unfortunately the YubiKey is currently in a state where ykman can't fix it, so changing it using the "config mode" command doesn't work (as you've already run into). I'll add enough support to ykman that the command should work for a future version.

In the meantime, since you already have pcsc-tools installed, you can manually send the commands needed to the YubiKey using scriptor as follows:

$ scriptor
No reader given: using Yubico YubiKey CCID 00 00
Using T=1 protocol
Reading commands from STDIN
00 A4 04 00 08 A0 00 00 05 27 47 11 17
> 00 A4 04 00 08 A0 00 00 05 27 47 11 17
< 56 69 72 74 75 61 6c 20 6d 67 72 20 2d 20 46 57 20 76 65 72 73 69 6f 6e 20 34 2e 31 2e 31 90 00
90 00 : Normal processing.
00 16 11 00 04 04 00 00 00
> 00 16 11 00 04 04 00 00 00
< 90 00 : Normal processing.

Then just unplug and replug the YubiKey, and it should be back to OTP+FIDO.

ghost commented 3 years ago

Thanks! That fixed it! Had to do it twice, but then it did work :)

dainnilsson commented 3 years ago

Great!