# Path: yubioath/core/exc.py
# class CardError(Exception):
# 
#     def __init__(self, status, message=''):
#         super(CardError, self).__init__('Card Error (%04x): %s' %
#                                         (status, message))
#         self.status = status
# 
# class DeviceLockedError(Exception):
# 
#     def __init__(self):
#         super(DeviceLockedError, self).__init__('Device is locked!')
# 
# class NoSpaceError(Exception):
# 
#     def __init__(self):
#         super(NoSpaceError, self).__init__('No space available on device.')
# 
# Path: yubioath/core/utils.py
# def hmac_sha1(secret, message):
# def time_challenge(t=None):
# def parse_full(resp):
# def parse_truncated(resp):
# def format_code(code, digits=6):
# def parse_uri(uri):
# def derive_key(salt, passphrase):
# def der_pack(*values):
# def der_read(der_data, expected_t=None):
# def b2len(bs):
# def kill_scdaemon():
# def ccid_supported_but_disabled():
# def _get_pids_linux():
# def _get_pids_osx():
# def _get_pids_win():
#         WMI = GetObject('winmgmts:')
# NON_CCID_YK_PIDS = set([0x0110, 0x0113, 0x0114, 0x0401, 0x0402, 0x0403])
# 
# Path: yubioath/yubicommon/compat.py
# def int2byte(i):
#     if _PY2:
#         return chr(i)
#     return bytes((i,))
# 
# def byte2int(i):
#     if _PY2:
#         return ord(i)
#     return i


from .exc import CardError, DeviceLockedError, NoSpaceError
from .utils import (
    der_read, der_pack, hmac_sha1, derive_key, get_random_bytes,
    time_challenge, parse_truncated, format_code)
from yubioath.yubicommon.compat import int2byte, byte2int
import hashlib
import struct
import os
    @property
    def locked(self):
        return self._challenge is not None

    def delete(self, name):
        data = der_pack(TAG_NAME, name.encode('utf8'))
        self._send(INS_DELETE, data)

    def calculate(self, name, oath_type, timestamp=None):
        challenge = time_challenge(timestamp) \
            if oath_type == TYPE_TOTP else b''
        data = der_pack(
            TAG_NAME, name.encode('utf8'), TAG_CHALLENGE, challenge)
        resp = self._send(INS_CALCULATE, data)
        # Manual dynamic truncation required for Steam entries
        resp = der_read(resp, TAG_RESPONSE)[0]
        digits, resp = resp[0:1], resp[1:]
        offset = byte2int(resp[-1]) & 0xF
        resp = resp[offset:offset + 4]
        scheme = SCHEME_STEAM if name.startswith('Steam:') else SCHEME_STANDARD
        return format_truncated(digits + resp, scheme)

    def calculate_key(self, passphrase):
        return derive_key(self.id, passphrase)

    def unlock(self, key):
        if not self.locked:
            return

        response = hmac_sha1(key, self._challenge)

# Path: yubioath/core/exc.py
# class CardError(Exception):
# 
#     def __init__(self, status, message=''):
#         super(CardError, self).__init__('Card Error (%04x): %s' %
#                                         (status, message))
#         self.status = status
# 
# class DeviceLockedError(Exception):
# 
#     def __init__(self):
#         super(DeviceLockedError, self).__init__('Device is locked!')
# 
# class NoSpaceError(Exception):
# 
#     def __init__(self):
#         super(NoSpaceError, self).__init__('No space available on device.')
# 
# Path: yubioath/core/utils.py
# def hmac_sha1(secret, message):
# def time_challenge(t=None):
# def parse_full(resp):
# def parse_truncated(resp):
# def format_code(code, digits=6):
# def parse_uri(uri):
# def derive_key(salt, passphrase):
# def der_pack(*values):
# def der_read(der_data, expected_t=None):
# def b2len(bs):
# def kill_scdaemon():
# def ccid_supported_but_disabled():
# def _get_pids_linux():
# def _get_pids_osx():
# def _get_pids_win():
#         WMI = GetObject('winmgmts:')
# NON_CCID_YK_PIDS = set([0x0110, 0x0113, 0x0114, 0x0401, 0x0402, 0x0403])
# 
# Path: yubioath/yubicommon/compat.py
# def int2byte(i):
#     if _PY2:
#         return chr(i)
#     return bytes((i,))
# 
# def byte2int(i):
#     if _PY2:
#         return ord(i)
#     return i


# Path: yubioath/core/standard.py
from .exc import CardError, DeviceLockedError, NoSpaceError
from .utils import (
    der_read, der_pack, hmac_sha1, derive_key, get_random_bytes,
    time_challenge, parse_truncated, format_code)
from yubioath.yubicommon.compat import int2byte, byte2int
import hashlib
import struct
import os

    @property
    def locked(self):
        return self._challenge is not None

    def delete(self, name):
        data = der_pack(TAG_NAME, name.encode('utf8'))
        self._send(INS_DELETE, data)

    def calculate(self, name, oath_type, timestamp=None):
        challenge = time_challenge(timestamp) \
            if oath_type == TYPE_TOTP else b''
        data = der_pack(
            TAG_NAME, name.encode('utf8'), TAG_CHALLENGE, challenge)
        resp = self._send(INS_CALCULATE, data)
        # Manual dynamic truncation required for Steam entries
        resp = der_read(resp, TAG_RESPONSE)[0]
        digits, resp = resp[0:1], resp[1:]
        offset = byte2int(resp[-1]) & 0xF
        resp = resp[offset:offset + 4]
        scheme = SCHEME_STEAM if name.startswith('Steam:') else SCHEME_STANDARD
        return format_truncated(digits + resp, scheme)

    def calculate_key(self, passphrase):
        return derive_key(self.id, passphrase)

    def unlock(self, key):
        if not self.locked:
            return

        response = hmac_sha1(key, self._challenge)

        challenge = get_random_bytes(8)