def pivman_change_pin(session: PivSession, old_pin: str, new_pin: str) -> None: """Change the PIN, while keeping PivmanData in sync.""" session.change_pin(old_pin, new_pin) pivman = get_pivman_data(session) if pivman.has_derived_key: session.authenticate( MANAGEMENT_KEY_TYPE.TDES, derive_management_key(old_pin, cast(bytes, pivman.salt)), ) session.verify_pin(new_pin) new_salt = os.urandom(16) new_key = derive_management_key(new_pin, new_salt) session.set_management_key(MANAGEMENT_KEY_TYPE.TDES, new_key) pivman.salt = new_salt session.put_object(OBJECT_ID_PIVMAN_DATA, pivman.get_bytes())
def pivman_set_mgm_key( session: PivSession, new_key: bytes, algorithm: MANAGEMENT_KEY_TYPE, touch: bool = False, store_on_device: bool = False, ) -> None: """Set a new management key, while keeping PivmanData in sync.""" pivman = get_pivman_data(session) if store_on_device or (not store_on_device and pivman.has_stored_key): # Ensure we have access to protected data before overwriting key try: pivman_prot = get_pivman_protected_data(session) except Exception as e: logger.debug("Failed to initialize protected pivman data", exc_info=e) if store_on_device: raise # Set the new management key session.set_management_key(algorithm, new_key, touch) if pivman.has_derived_key: # Clear salt for old derived keys. pivman.salt = None # Set flag for stored or not stored key. pivman.mgm_key_protected = store_on_device # Update readable pivman data session.put_object(OBJECT_ID_PIVMAN_DATA, pivman.get_bytes()) if store_on_device: # Store key in protected pivman data pivman_prot.key = new_key session.put_object(OBJECT_ID_PIVMAN_PROTECTED_DATA, pivman_prot.get_bytes()) elif not store_on_device and pivman.has_stored_key: # If new key should not be stored and there is an old stored key, # try to clear it. try: pivman_prot.key = None session.put_object( OBJECT_ID_PIVMAN_PROTECTED_DATA, pivman_prot.get_bytes(), ) except ApduError as e: logger.debug("No PIN provided, can't clear key...", exc_info=e)