def _read_info_otp(conn, key_type, interfaces): otp = None serial = None try: mgmt = ManagementSession(conn) except ApplicationNotAvailableError: otp = YubiOtpSession(conn) # Retry during potential reclaim timeout period (~3s). for _ in range(8): try: if otp is None: try: return mgmt.read_device_info() # Rejected while reclaim except NotSupportedError: otp = YubiOtpSession(conn) serial = otp.get_serial( ) # Rejected if reclaim (or not API_SERIAL_VISIBLE) break except CommandRejectedError: sleep(0.5) # Potential reclaim else: otp = YubiOtpSession(conn) # Synthesize info logger.debug("Unable to get info via Management application, use fallback") version = otp.version if key_type == YUBIKEY.NEO: usb_supported = BASE_NEO_APPS if USB_INTERFACE.FIDO in interfaces or version >= (3, 3, 0): usb_supported |= CAPABILITY.U2F capabilities = { TRANSPORT.USB: usb_supported, TRANSPORT.NFC: usb_supported, } elif key_type == YUBIKEY.YKP: capabilities = { TRANSPORT.USB: CAPABILITY.OTP | TRANSPORT.U2F, } else: capabilities = { TRANSPORT.USB: CAPABILITY.OTP, } return DeviceInfo( config=DeviceConfig( enabled_capabilities={}, # Populated later auto_eject_timeout=0, challenge_response_timeout=0, device_flags=0, ), serial=serial, version=version, form_factor=FORM_FACTOR.UNKNOWN, supported_capabilities=capabilities.copy(), is_locked=False, )
def _otp_read_data(conn): otp = YubiOtpSession(conn) version = otp.version try: serial = otp.get_serial() except Exception as e: logger.debug("Unable to read serial over OTP, no serial", exc_info=e) serial = None return version, serial
def get_overall_fips_status(pid, info): statuses = {} usb_enabled = info.config.enabled_applications[TRANSPORT.USB] statuses["OTP"] = False if usb_enabled & APPLICATION.OTP: for dev in list_otp_devices(): if dev.pid == pid: with dev.open_connection(OtpConnection) as conn: app = YubiOtpSession(conn) if app.get_serial() == info.serial: statuses["OTP"] = otp_in_fips_mode(app) break statuses["OATH"] = False if usb_enabled & APPLICATION.OATH: for dev in list_ccid(): with dev.open_connection(SmartCardConnection) as conn: info2 = read_info(pid, conn) if info2.serial == info.serial: app = OathSession(conn) statuses["OATH"] = oath_in_fips_mode(app) break statuses["FIDO U2F"] = False if usb_enabled & APPLICATION.U2F: for dev in list_ctap_devices(): if dev.pid == pid: with dev.open_connection(FidoConnection) as conn: info2 = read_info(pid, conn) if info2.serial == info.serial: statuses["FIDO U2F"] = ctap_in_fips_mode(conn) break return statuses
def serial_modhex(self): with self._open_device([OtpConnection]) as conn: session = YubiOtpSession(conn) return modhex_encode(b'\xff\x00' + struct.pack(b'>I', session.get_serial()))