Example #1
0
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())
Example #2
0
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)