Beispiel #1
0
def _save_device_with_password(key_file: Path, device: LocalDevice,
                               password: str, force: bool) -> None:
    if key_file.exists() and not force:
        raise LocalDeviceAlreadyExistsError(
            f"Device key file `{key_file}` already exists")

    try:
        key, salt = derivate_secret_key_from_password(password)
        ciphertext = key.encrypt(device.dump())

    except (CryptoError, DataError) as exc:
        raise LocalDeviceValidationError(
            f"Cannot dump local device: {exc}") from exc

    key_file_content = key_file_serializer.dumps({
        "salt": salt,
        "ciphertext": ciphertext,
        "human_handle": device.human_handle,
        "device_label": device.device_label,
        "organization_id": device.organization_id,
        "device_id": device.device_id,
        "slug": device.slug,
    })

    try:
        key_file.parent.mkdir(mode=0o700, exist_ok=True, parents=True)
        key_file.write_bytes(key_file_content)

    except OSError as exc:
        raise LocalDeviceError(f"Cannot save {key_file}: {exc}") from exc
Beispiel #2
0
def _save_device(
    key_file: Path,
    device: LocalDevice,
    force: bool,
    encrypt_dump: Callable[[bytes], Tuple[DeviceFileType, bytes, dict]],
) -> None:
    assert key_file.suffix == DEVICE_FILE_SUFFIX

    if key_file.exists() and not force:
        raise LocalDeviceAlreadyExistsError(
            f"Device key file `{key_file}` already exists")

    cleartext = device.dump()
    type, ciphertext, extra_args = encrypt_dump(cleartext)
    key_file_content = key_file_serializer.dumps({
        "type": type,
        **extra_args,
        "ciphertext": ciphertext,
        "human_handle": device.human_handle,
        "device_label": device.device_label,
        "organization_id": device.organization_id,
        "device_id": device.device_id,
        "slug": device.slug,
    })

    try:
        key_file.parent.mkdir(mode=0o700, exist_ok=True, parents=True)
        key_file.write_bytes(key_file_content)

    except OSError as exc:
        raise LocalDeviceError(f"Cannot save {key_file}: {exc}") from exc
Beispiel #3
0
def _save_device(key_file: Path,
                 device: LocalDevice,
                 encryptor: BaseLocalDeviceEncryptor,
                 force: bool = False) -> None:
    """
    Raises:
        LocalDeviceError
        LocalDeviceAlreadyExistsError
        LocalDeviceCryptoError
        LocalDeviceValidationError
        LocalDevicePackingError
    """
    if key_file.exists() and not force:
        raise LocalDeviceAlreadyExistsError(
            f"Device `{device.organization_id}:{device.device_id}` already exists"
        )

    try:
        raw = device.dump()

    except DataError as exc:
        raise LocalDeviceValidationError(
            f"Cannot dump local device: {exc}") from exc

    ciphertext = encryptor.encrypt(raw)
    try:
        key_file.parent.mkdir(exist_ok=True, parents=True)
        key_file.write_bytes(ciphertext)

    except OSError as exc:
        raise LocalDeviceError(f"Cannot save {key_file}: {exc}") from exc
Beispiel #4
0
async def save_recovery_device(key_file: PurePath,
                               device: LocalDevice,
                               force: bool = False) -> str:
    """
    Return the recovery passphrase
    """
    assert key_file.suffix == RECOVERY_DEVICE_FILE_SUFFIX
    key_file = trio.Path(key_file)

    if await key_file.exists() and not force:
        raise LocalDeviceAlreadyExistsError(
            f"Device key file `{key_file}` already exists")

    passphrase, key = generate_recovery_passphrase()

    try:
        ciphertext = key.encrypt(device.dump())

    except (CryptoError, DataError) as exc:
        raise LocalDeviceValidationError(
            f"Cannot dump local device: {exc}") from exc

    key_file_content = key_file_serializer.dumps({
        "type": DeviceFileType.RECOVERY,
        "ciphertext": ciphertext,
        "human_handle": device.human_handle,
        "device_label": device.device_label,
        "organization_id": device.organization_id,
        "device_id": device.device_id,
        "slug": device.slug,
    })

    try:
        await key_file.parent.mkdir(mode=0o700, exist_ok=True, parents=True)
        await key_file.write_bytes(key_file_content)

    except OSError as exc:
        raise LocalDeviceError(f"Cannot save {key_file}: {exc}") from exc

    return passphrase