示例#1
0
def load_device_with_password(key_file: Path, password: str) -> LocalDevice:
    """
        LocalDeviceNotFoundError
        LocalDeviceCryptoError
        LocalDeviceValidationError
        LocalDevicePackingError
    """
    try:
        ciphertext = key_file.read_bytes()
    except OSError as exc:
        raise LocalDeviceNotFoundError(
            f"Config file `{key_file}` is missing") from exc

    try:
        data = key_file_serializer.loads(ciphertext)
    except LocalDeviceError:
        data = legacy_key_file_serializer.loads(ciphertext)

    try:
        key, _ = derivate_secret_key_from_password(password, data["salt"])
        plaintext = key.decrypt(data["ciphertext"])
    except CryptoError as exc:
        raise LocalDeviceCryptoError(str(exc)) from exc

    try:
        return LocalDevice.load(plaintext)

    except DataError as exc:
        raise LocalDeviceValidationError(
            f"Cannot load local device: {exc}") from exc
示例#2
0
def test_supports_legacy_is_admin_field(alice):
    # Manually craft a local user in legacy format
    raw_legacy_local_user = {
        "organization_addr": alice.organization_addr.to_url(),
        "device_id": str(alice.device_id),
        "signing_key": alice.signing_key.encode(),
        "private_key": alice.private_key.encode(),
        "is_admin": True,
        "user_manifest_id": UUID(alice.user_manifest_id.hex),
        "user_manifest_key": bytes(alice.user_manifest_key.secret),
        "local_symkey": bytes(alice.local_symkey.secret),
    }
    dumped_legacy_local_user = packb(raw_legacy_local_user)

    # Make sure the legacy format can be loaded
    legacy_local_user = LocalDevice.load(dumped_legacy_local_user)
    assert legacy_local_user == alice

    # Manually decode new format to check it is compatible with legacy
    dumped_local_user = alice.dump()
    raw_local_user = unpackb(dumped_local_user)
    assert raw_local_user == {
        **raw_legacy_local_user,
        "profile": alice.profile.value,
        "human_handle": None,
        "device_label": None,
    }
示例#3
0
async def load_recovery_device(key_file: PurePath,
                               passphrase: str) -> LocalDevice:
    """
    Raises:
        LocalDeviceError
        LocalDeviceNotFoundError
        LocalDeviceCryptoError
        LocalDeviceValidationError
        LocalDevicePackingError
    """
    key_file = trio.Path(key_file)
    try:
        ciphertext = await key_file.read_bytes()
    except OSError as exc:
        raise LocalDeviceNotFoundError(
            f"Recovery file `{key_file}` is missing") from exc

    try:
        data = key_file_serializer.loads(ciphertext)
    except LocalDevicePackingError as exc:
        raise LocalDeviceValidationError("Not a device recovery file") from exc

    if data["type"] != DeviceFileType.RECOVERY:
        raise LocalDeviceValidationError("Not a device recovery file")

    try:
        key = derivate_secret_key_from_recovery_passphrase(passphrase)
    except ValueError as exc:
        # Not really a crypto operation, but it is more coherent for the caller
        raise LocalDeviceCryptoError("Invalid passphrase") from exc

    try:
        plaintext = key.decrypt(data["ciphertext"])
    except CryptoError as exc:
        raise LocalDeviceCryptoError(str(exc)) from exc

    try:
        return LocalDevice.load(plaintext)

    except DataError as exc:
        raise LocalDeviceValidationError(
            f"Cannot load local device: {exc}") from exc
示例#4
0
def _load_device(key_file: Path,
                 decryptor: BaseLocalDeviceDecryptor) -> LocalDevice:
    """
    Raises:
        LocalDeviceNotFoundError
        LocalDeviceCryptoError
        LocalDeviceValidationError
        LocalDevicePackingError
    """
    try:
        ciphertext = key_file.read_bytes()
    except OSError as exc:
        raise LocalDeviceNotFoundError(
            f"Config file {key_file} is missing") from exc

    raw = decryptor.decrypt(ciphertext)
    try:
        return LocalDevice.load(raw)

    except DataError as exc:
        raise LocalDeviceValidationError(
            f"Cannot load local device: {exc}") from exc
示例#5
0
def _load_device(key_file: Path,
                 decrypt_ciphertext: Callable[[dict], bytes]) -> LocalDevice:
    try:
        ciphertext = key_file.read_bytes()
    except OSError as exc:
        raise LocalDeviceNotFoundError(
            f"Config file `{key_file}` is missing") from exc

    try:
        data = key_file_serializer.loads(ciphertext)
    except LocalDeviceError:
        data = legacy_key_file_serializer.loads(ciphertext)

    plaintext = decrypt_ciphertext(data)

    try:
        local_device = LocalDevice.load(plaintext)

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

    _KEY_FILE_DATA[local_device.device_id] = data
    return local_device