def _construct_response(self, challenge, csr): """Construct response message given challenge and csr message Args: challenge: Challenge(key_type, challenge) csr: CSR object returned by create_csr Returns: protobuf Response object Raises: BootstrapError: Unknown key type, cannot load challenge key, or wrong type of challenge key """ if challenge.key_type == ChallengeKey.ECHO: echo_resp = Response.Echo(response=challenge.challenge, ) response = Response( hw_id=AccessGatewayID(id=self._hw_id), challenge=challenge.challenge, echo_response=echo_resp, csr=csr, ) elif challenge.key_type == ChallengeKey.SOFTWARE_ECDSA_SHA256: r_bytes, s_bytes = self._ecdsa_sha256_response(challenge.challenge) ecdsa_resp = Response.ECDSA(r=r_bytes, s=s_bytes) response = Response( hw_id=AccessGatewayID(id=self._hw_id), challenge=challenge.challenge, ecdsa_response=ecdsa_resp, csr=csr, ) else: raise BootstrapError('Unknown key type: %s' % challenge.key_type) return response
async def _bootstrap_now(self): """Main entrance to bootstrapping 1. set self._state to BOOTSTRAPPING 2. set up a gPRC channel and get a challenge (async) 3. call _get_challenge_done_success to deal with the response If any steps fails, a new _bootstrap_now call will be scheduled. """ assert self._state != BootstrapState.BOOTSTRAPPING, \ 'At most one bootstrap is happening' self._state = BootstrapState.BOOTSTRAPPING try: chan = ServiceRegistry.get_bootstrap_rpc_channel() except ValueError as exp: logging.error('Failed to get rpc channel: %s', exp) self._schedule_next_bootstrap(hard_failure=False) return client = BootstrapperStub(chan) try: result = await grpc_async_wrapper( client.GetChallenge.future(AccessGatewayID(id=self._hw_id)), self._loop) await self._get_challenge_done_success(result) except grpc.RpcError as err: self._get_challenge_done_fail(err)
def _bootstrap_now(self): """Main entrance to bootstrapping 1. set self._state to BOOTSTRAPPING 2. set up a gPRC channel and get a challenge (async) 3. setup _get_challenge_done callback If any steps fails, a new _bootstrap_now call will be scheduled. """ assert self._state != BootstrapState.BOOTSTRAPPING, \ 'At most one bootstrap is happening' self._state = BootstrapState.BOOTSTRAPPING try: chan = ServiceRegistry.get_bootstrap_rpc_channel() except ValueError as exp: logging.error('Failed to get rpc channel: %s', exp) self._retry_bootstrap(hard_failure=False) return logging.info('Beginning bootstrap process') client = BootstrapperStub(chan) future = client.GetChallenge.future(AccessGatewayID(id=self._hw_id)) future.add_done_callback( lambda future: self._loop.call_soon_threadsafe( self._get_challenge_done, future))
def register_handler(client: RegistrationStub, args: List[str]) -> RegisterResponse: """ Register a device and retrieves its control proxy Args: client: Registration stub args: command line arguments Returns: RegisterRequest: register request, used for printing after function returns RegisterResponse: response from gRPC call, either error or the control_proxy """ req = RegisterRequest( token=args.token, hwid=AccessGatewayID( id=snowflake.snowflake(), ), challenge_key=ChallengeKey( key=load_public_key_to_base64der("/var/opt/magma/certs/gw_challenge.key"), key_type=ChallengeKey.KeyType.SOFTWARE_ECDSA_SHA256, ), ) res = client.Register(req) if res.HasField("error"): raise Exception(res.error) return req, res