def _inject_error_encrypted(self, error_id, cmd_id=0xFFFF, auth_id=0xFFFFFFFF): error = error_id cmd_id = cmd_id message = cmd.error_bridge(error, cmd_id) decrypted = utils.pack_u32(auth_id) + message decrypted = utils.add_crc(decrypted) return auth_id, message, decrypted
def _inject_error_unencrypted(self, error_id, cmd_id=0xFFFF): error = error_id message = cmd.error_bridge(error, cmd_id) message = utils.add_crc(message) return message
def authorize(self): retval = True auth_id = 0 uuid = '' key = '' nonce_abf = None bt = BLEClient(port=self.port, bgapi=self.bgapi) bt.connect(self.mac_addr) #============================================================================== # Authentication process #============================================================================== # request sl public key log.debug('request SL public key') message = cmd.public_key_request() bt.send_unencrypted(message) # receive sl public key message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) if ((0x0003 == cmd_id) and (True == retval)): log.debug('SL public key received') sl_public_k = cmd.public_key_decode(message) # generate keys log.debug('generating key') cl_public_k, cl_private_k = self._generate_keypair() self.key = self._generate_kdf1(cl_private_k, sl_public_k) # send own public key log.debug('send own public key') message = cmd.public_key(cl_public_k) bt.send_unencrypted(message) # receive sl challenge 1 message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no public key received') retval = False if ((0x0004 == cmd_id) and (True == retval)): log.debug('SL nonce_k received') nonce_k = cmd.challenge_decode(message) #send authenticator log.debug('send authenticator') message = cmd.authenticator(cl_public_k, sl_public_k, nonce_k, self.key) bt.send_unencrypted(message) # receive sl challenge 2 message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no nonce nonce_k received') retval = False if ((0x0004 == cmd_id) and (True == retval)): log.debug('SL nonce_k received') nonce_k = cmd.challenge_decode(message) # send authorization data log.debug('send authorization data') nonce_abf = nacl.utils.random(32) message = cmd.authorization_data(self.id_type, self.bridge_id, self.name, nonce_abf, nonce_k, self.key) bt.send_unencrypted(message) # receive authorization id message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no nonce_k received') retval = False if ((0x0007 == cmd_id) and (True == retval)): # cl verifies authorization id log.debug('SL authorization id received') verify = self._auth_message(message, nonce_abf, self.key) if (0 != verify): error_code = 0x11 command = cmd.get_cmd_id(message) message = cmd.error_bridge(error_code, command) cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no authorization id received') retval = False if ((0x0007 == cmd_id) and (True == retval)): log.debug('SL authorization id verified') self.auth_id, uuid, nonce_k = cmd.authorization_id_decode(message) self.uuid = uuid log.debug('Authentication ID: ' + hex(self.auth_id)) log.debug('UUID: ' + hexlify(self.uuid)) # send authorization id confirmation log.debug('send authorization id confirmation') message = cmd.authorization_id_confirmation( self.auth_id, nonce_k, self.key) bt.send_unencrypted(message) # receive status ok message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: authorization id verification') retval = False if ((0x000E == cmd_id) and (True == retval)): # Nuki states received log.debug('SL status received') status = cmd.status_decode(message) log.debug('status: ' + str(hex(status))) else: log.debug('Nuki error: no status received') retval = False if (False == retval): # error handler log.debug('Nuki error handler') self._err_handler(cmd_id, message) bt.stop() retval, id, name = self.get_config() return retval, self.auth_id, uuid, self.key, id, name