Skip to content

Commit

Permalink
Error handling for restricted NFC
Browse files Browse the repository at this point in the history
  • Loading branch information
dainnilsson committed Aug 12, 2024
1 parent d175d4a commit 5673494
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
15 changes: 13 additions & 2 deletions ykman/_cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
parse_private_key,
parse_certificates,
InvalidPasswordError,
is_nfc_restricted,
)
from ..logging import init_logging
from ..diagnostics import get_diagnostics, sys_info
Expand Down Expand Up @@ -126,11 +127,21 @@ def require_reader(connection_types, reader):
readers = list_ccid(reader)
if len(readers) == 1:
dev = readers[0]
nfc_restricted = False
try:
with dev.open_connection(SmartCardConnection) as conn:
info = read_info(conn, dev.pid)
return dev, info
try:
info = read_info(conn, dev.pid)
return dev, info
except ValueError:
nfc_restricted = is_nfc_restricted(conn)
raise # Re-raise to be handled in block below
except Exception:
if nfc_restricted:
raise CliFail(
"YubiKey is in NFC restricted mode "
"(see: https://www.yubico.com/getting-started/)."
)
raise CliFail("Failed to connect to YubiKey.")
elif len(readers) > 1:
raise CliFail("Multiple external readers match name.")
Expand Down
22 changes: 22 additions & 0 deletions ykman/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
# POSSIBILITY OF SUCH DAMAGE.

from yubikit.core import Tlv, int2bytes
from yubikit.core.smartcard import (
SmartCardConnection,
SmartCardProtocol,
ApduError,
ApplicationNotAvailableError,
)
from cryptography.hazmat.primitives.serialization import pkcs12
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
Expand Down Expand Up @@ -192,3 +198,19 @@ def get_windows_version() -> Tuple[int, int, int]:
osvi.dwOSVersionInfoSize = ctypes.sizeof(osvi)
ctypes.windll.Ntdll.RtlGetVersion(ctypes.byref(osvi)) # type: ignore
return osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber


_RESTRICTED_NDEF = bytes.fromhex("001FD1011B5504") + b"yubico.com/getting-started"


def is_nfc_restricted(connection: SmartCardConnection) -> bool:
"""Check if the given SmartCardConnection over NFC is in restricted NFC mode."""
try:
p = SmartCardProtocol(connection)
p.select(bytes.fromhex("D2760000850101"))
p.send_apdu(0x00, 0xA4, 0x00, 0x0C, bytes([0xE1, 0x04]))
ndef = p.send_apdu(0x00, 0xB0, 0x00, 0x00)
except (ApduError, ApplicationNotAvailableError):
ndef = None

return ndef == _RESTRICTED_NDEF

0 comments on commit 5673494

Please sign in to comment.