Source code for cryptnoxpy.card.nft

# -*- coding: utf-8 -*-
"""
Module containing class for NFT card
"""
from typing import Tuple

from . import base
from . import basic_g1
from .user_data import UserData
from .. import exceptions
from ..enums import (
    Derivation,
    KeyType,
    SlotIndex
)


[docs] class Nft(basic_g1.BasicG1): """ Class containing functionality for NFT card which has limited capabilities """ type = ord("N") _type = "NFT"
[docs] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.user_data = UserData(self, 1)
[docs] def derive(self, key_type: KeyType = KeyType.K1, path: str = ""): raise NotImplementedError("Card doesn't have this functionality")
[docs] def get_public_key(self, derivation: Derivation = Derivation.CURRENT_KEY, key_type: KeyType = KeyType.K1, path: str = "", compressed: bool = False, hexed: bool = True) -> str: if derivation is not Derivation.CURRENT_KEY: raise exceptions.DerivationSelectionException("This card type doesn't support this " "derivation form") if key_type is not KeyType.K1: raise exceptions.KeySelectionException("This card type doesn't support this key type") return super().get_public_key(derivation, key_type, path, compressed, hexed)
[docs] def get_public_key_clear(self, derivation: int, path: str = "", compressed: bool = True) -> bytes: if derivation != Derivation.CURRENT_KEY: raise exceptions.DerivationSelectionException("This card type doesn't support this derivation form") return super().get_public_key_clear(derivation, path, compressed)
[docs] def set_pubexport(self, status: bool, p1: int, puk: str) -> None: if p1 not in [0, 1]: raise exceptions.DataValidationException("P1 must be 0 (xpub) or 1 (clear pubkey)") super().set_pubexport(status, p1, puk)
[docs] def set_clearpubkey(self, status: bool, puk: str) -> None: super().set_clearpubkey(status, puk)
[docs] def generate_random_number(self, size: int) -> bytes: raise NotImplementedError("Card doesn't have this functionality")
[docs] def load_seed(self, seed: bytes, pin: str = "") -> None: raise NotImplementedError("Card doesn't have this functionality")
[docs] def set_pin_authentication(self, status: bool, puk: str) -> None: raise NotImplementedError("Card doesn't have this functionality")
[docs] def set_pinless_path(self, path: str, puk: str) -> None: raise NotImplementedError("Card doesn't have this functionality")
[docs] def user_key_add(self, slot: SlotIndex, data_info: str, public_key: bytes, puk_code: str, cred_id: bytes = b"") -> None: raise NotImplementedError("Card doesn't have this functionality")
[docs] def user_key_delete(self, slot: SlotIndex, puk_code: str) -> None: raise NotImplementedError("")
[docs] def user_key_info(self, slot: SlotIndex) -> Tuple[str, str]: raise NotImplementedError("")
[docs] def user_key_enabled(self, slot_index: SlotIndex): return False
[docs] def user_key_challenge_response_nonce(self) -> bytes: raise NotImplementedError("")
[docs] def user_key_challenge_response_open(self, slot: SlotIndex, signature: bytes) -> bool: raise NotImplementedError("")
[docs] def user_key_signature_open(self, slot: SlotIndex, message: bytes, signature: bytes) -> bool: raise NotImplementedError("")
[docs] def signature_check(self, nonce: bytes) -> base.SignatureCheckResult: message = [0x80, 0xF8, 0x01, 0x00] try: result = self.connection.send_encrypted(message, nonce) except exceptions.GenericException as error: if error.status[0] == 0x69 and error.status[1] == 0x84: raise exceptions.DataValidationException("Nonce has to be 16 bytes.") if error.status[0] == 0x69 and error.status[1] == 0x85: raise exceptions.SeedException("Seed not on card.") raise error if result[0:2] != b"CR" or result[35] != 0x00: raise exceptions.DataException("Result not in correct format.") return base.SignatureCheckResult(result[:36], result[36:])
def _init_data(self, name: str, email: str, pin: str, puk: str, pairing_secret: bytes = base.BASIC_PAIRING_SECRET, nfc_sign: bool = False): data = Nft._get_coded_value(name) + Nft._get_coded_value(email) data += bytes(pin, 'ascii') + bytes(puk, 'ascii') data += bytes.fromhex("5A5A") if nfc_sign else bytes.fromhex("A5A5") data += pairing_secret return data