async def do_get_claim_requests(self) -> "DeviceGreetInProgress4Ctx": rep = await self._cmds.invite_4_greeter_communicate(token=self.token, payload=b"") if rep["status"] in ("not_found", "already_deleted"): raise InviteNotAvailableError() elif rep["status"] == "invalid_state": raise InvitePeerResetError() elif rep["status"] != "ok": raise InviteError( f"Backend error during step 4 (data exchange): {rep}") if rep["payload"] is None: raise InviteError("Missing InviteDeviceData payload") try: data = InviteDeviceData.decrypt_and_load( rep["payload"], key=self._shared_secret_key) except DataError as exc: raise InviteError( "Invalid InviteDeviceData payload provided by peer") from exc return DeviceGreetInProgress4Ctx( token=self.token, requested_device_label=data.requested_device_label, verify_key=data.verify_key, shared_secret_key=self._shared_secret_key, cmds=self._cmds, )
async def do_claim_device( self, requested_device_label: Optional[DeviceLabel]) -> LocalDevice: # Device key is generated here and kept in memory until the end of # the enrollment process. This mean we can lost it if something goes wrong. # This has no impact until step 4 (somewhere between data exchange and # confirmation exchange steps) where greeter upload our certificate in # the server. # This is considered acceptable given 1) the error window is small and # 2) if this occurs the inviter can revoke the device and retry the # enrollment process to fix this signing_key = SigningKey.generate() try: payload = InviteDeviceData( requested_device_label=requested_device_label, verify_key=signing_key.verify_key).dump_and_encrypt( key=self._shared_secret_key) except DataError as exc: raise InviteError( "Cannot generate InviteDeviceData payload") from exc rep = await self._cmds.invite_4_claimer_communicate(payload=payload) _check_rep(rep, step_name="step 4 (data exchange)") rep = await self._cmds.invite_4_claimer_communicate(payload=b"") _check_rep(rep, step_name="step 4 (confirmation exchange)") try: confirmation = InviteDeviceConfirmation.decrypt_and_load( rep["payload"], key=self._shared_secret_key) except DataError as exc: raise InviteError( "Invalid InviteDeviceConfirmation payload provided by peer" ) from exc organization_addr = BackendOrganizationAddr.build( backend_addr=self._cmds.addr.get_backend_addr(), organization_id=self._cmds.addr.organization_id, root_verify_key=confirmation.root_verify_key, ) return LocalDevice( organization_addr=organization_addr, device_id=confirmation.device_id, device_label=confirmation.device_label, human_handle=confirmation.human_handle, profile=confirmation.profile, private_key=confirmation.private_key, signing_key=signing_key, user_manifest_id=confirmation.user_manifest_id, user_manifest_key=confirmation.user_manifest_key, local_symkey=SecretKey.generate(), )
async def do_claim_device( self, requested_device_label: Optional[str]) -> LocalDevice: signing_key = SigningKey.generate() try: payload = InviteDeviceData( requested_device_label=requested_device_label, verify_key=signing_key.verify_key).dump_and_encrypt( key=self._shared_secret_key) except DataError as exc: raise InviteError( "Cannot generate InviteDeviceData payload") from exc rep = await self._cmds.invite_4_claimer_communicate(payload=payload) if rep["status"] == "invalid_state": raise InvitePeerResetError() elif rep["status"] != "ok": raise InviteError( f"Backend error during step 4 (data exchange): {rep}") rep = await self._cmds.invite_4_claimer_communicate(payload=b"") if rep["status"] == "invalid_state": raise InvitePeerResetError() elif rep["status"] != "ok": raise InviteError( f"Backend error during step 4 (confirmation exchange): {rep}") try: confirmation = InviteDeviceConfirmation.decrypt_and_load( rep["payload"], key=self._shared_secret_key) except DataError as exc: raise InviteError( "Invalid InviteDeviceConfirmation payload provided by peer" ) from exc organization_addr = BackendOrganizationAddr.build( backend_addr=self._cmds.addr, organization_id=self._cmds.addr.organization_id, root_verify_key=confirmation.root_verify_key, ) return LocalDevice( organization_addr=organization_addr, device_id=confirmation.device_id, device_label=confirmation.device_label, human_handle=confirmation.human_handle, profile=confirmation.profile, private_key=confirmation.private_key, signing_key=signing_key, user_manifest_id=confirmation.user_manifest_id, user_manifest_key=confirmation.user_manifest_key, local_symkey=SecretKey.generate(), )
async def do_get_claim_requests(self) -> "DeviceGreetInProgress4Ctx": rep = await self._cmds.invite_4_greeter_communicate(token=self.token, payload=b"") _check_rep(rep, step_name="step 4 (data exchange)") if rep["payload"] is None: raise InviteError("Missing InviteDeviceData payload") try: data = InviteDeviceData.decrypt_and_load(rep["payload"], key=self._shared_secret_key) except DataError as exc: raise InviteError("Invalid InviteDeviceData payload provided by peer") from exc return DeviceGreetInProgress4Ctx( token=self.token, requested_device_label=data.requested_device_label, verify_key=data.verify_key, shared_secret_key=self._shared_secret_key, cmds=self._cmds, )