def scan_result_response(security_ctx, response_data): # Interpret protobuf response packet from ScanResult command dec_resp = security_ctx.decrypt_data(tobytes(response_data)) resp = proto.wifi_scan_pb2.WiFiScanPayload() resp.ParseFromString(dec_resp) print_verbose(security_ctx, "ScanResult status " + str(resp.status)) if resp.status != 0: raise RuntimeError authmode_str = [ "Open", "WEP", "WPA_PSK", "WPA2_PSK", "WPA_WPA2_PSK", "WPA2_ENTERPRISE" ] results = [] for entry in resp.resp_scan_result.entries: results += [{ "ssid": entry.ssid.decode('latin-1').rstrip('\x00'), "bssid": utils.str_to_hexstr(entry.bssid.decode('latin-1')), "channel": entry.channel, "rssi": entry.rssi, "auth": authmode_str[entry.auth] }] print_verbose(security_ctx, "ScanResult SSID : " + str(results[-1]["ssid"])) print_verbose(security_ctx, "ScanResult BSSID : " + str(results[-1]["bssid"])) print_verbose(security_ctx, "ScanResult Channel : " + str(results[-1]["channel"])) print_verbose(security_ctx, "ScanResult RSSI : " + str(results[-1]["rssi"])) print_verbose(security_ctx, "ScanResult AUTH : " + str(results[-1]["auth"])) return results
def custom_config_request(security_ctx, info, version): # Form protobuf request packet from custom-config data cmd = proto.custom_config_pb2.CustomConfigRequest() cmd.info = tobytes(info) cmd.version = version enc_cmd = security_ctx.encrypt_data(cmd.SerializeToString()).decode('latin-1') print_verbose(security_ctx, "Client -> Device (CustomConfig cmd) " + utils.str_to_hexstr(enc_cmd)) return enc_cmd
def send_data(self, path, data, session_id=0): print("Client->Device msg :", path, session_id, utils.str_to_hexstr(data)) try: resp = input("Enter device->client msg : ") except Exception as err: print("error:", err) return None return utils.hexstr_to_str(resp)
def scan_status_request(security_ctx): # Form protobuf request packet for ScanStatus command cmd = proto.wifi_scan_pb2.WiFiScanPayload() cmd.msg = proto.wifi_scan_pb2.TypeCmdScanStatus enc_cmd = security_ctx.encrypt_data( cmd.SerializeToString()).decode('latin-1') print_verbose( security_ctx, "Client -> Device (Encrypted CmdScanStatus) " + utils.str_to_hexstr(enc_cmd)) return enc_cmd
def setup0_request(self): # Form SessionCmd0 request packet using client public key setup_req = session_pb2.SessionData() setup_req.sec_ver = session_pb2.SecScheme1 self.__generate_key() setup_req.sec1.sc0.client_pubkey = self.client_public_key self._print_verbose( "Client Public Key:\t" + utils.str_to_hexstr(self.client_public_key.decode('latin-1'))) return setup_req.SerializeToString().decode('latin-1')
def config_apply_config_request(security_ctx): # Form protobuf request packet for ApplyConfig command cmd = proto.wifi_config_pb2.WiFiConfigPayload() cmd.msg = proto.wifi_config_pb2.TypeCmdApplyConfig enc_cmd = security_ctx.encrypt_data( cmd.SerializeToString()).decode('latin-1') print_verbose( security_ctx, "Client -> Device (ApplyConfig cmd) " + utils.str_to_hexstr(enc_cmd)) return enc_cmd
def scan_result_request(security_ctx, index, count): # Form protobuf request packet for ScanResult command cmd = proto.wifi_scan_pb2.WiFiScanPayload() cmd.msg = proto.wifi_scan_pb2.TypeCmdScanResult cmd.cmd_scan_result.start_index = index cmd.cmd_scan_result.count = count enc_cmd = security_ctx.encrypt_data( cmd.SerializeToString()).decode('latin-1') print_verbose( security_ctx, "Client -> Device (Encrypted CmdScanResult) " + utils.str_to_hexstr(enc_cmd)) return enc_cmd
def setup1_request(self): # Form SessionCmd1 request packet using encrypted device public key setup_req = proto.session_pb2.SessionData() setup_req.sec_ver = session_pb2.SecScheme1 setup_req.sec1.msg = proto.sec1_pb2.Session_Command1 # Encrypt device public key and attach to the request packet client_verify = self.cipher.update(self.device_public_key) self._print_verbose( "Client Verify:\t" + utils.str_to_hexstr(client_verify.decode('latin-1'))) setup_req.sec1.sc1.client_verify_data = client_verify return setup_req.SerializeToString().decode('latin-1')
def config_set_config_request(security_ctx, ssid, passphrase): # Form protobuf request packet for SetConfig command cmd = proto.wifi_config_pb2.WiFiConfigPayload() cmd.msg = proto.wifi_config_pb2.TypeCmdSetConfig cmd.cmd_set_config.ssid = tobytes(ssid) cmd.cmd_set_config.passphrase = tobytes(passphrase) enc_cmd = security_ctx.encrypt_data( cmd.SerializeToString()).decode('latin-1') print_verbose( security_ctx, "Client -> Device (SetConfig cmd) " + utils.str_to_hexstr(enc_cmd)) return enc_cmd
def config_get_status_request(security_ctx): # Form protobuf request packet for GetStatus command cfg1 = proto.wifi_config_pb2.WiFiConfigPayload() cfg1.msg = proto.wifi_config_pb2.TypeCmdGetStatus cmd_get_status = proto.wifi_config_pb2.CmdGetStatus() cfg1.cmd_get_status.MergeFrom(cmd_get_status) encrypted_cfg = security_ctx.encrypt_data( cfg1.SerializeToString()).decode('latin-1') print_verbose( security_ctx, "Client -> Device (Encrypted CmdGetStatus) " + utils.str_to_hexstr(encrypted_cfg)) return encrypted_cfg
def setup0_response(self, response_data): # Interpret SessionResp0 response packet setup_resp = proto.session_pb2.SessionData() setup_resp.ParseFromString(tobytes(response_data)) self._print_verbose("Security version:\t" + str(setup_resp.sec_ver)) if setup_resp.sec_ver != session_pb2.SecScheme1: print("Incorrect sec scheme") exit(1) self.device_public_key = setup_resp.sec1.sr0.device_pubkey # Device random is the initialization vector device_random = setup_resp.sec1.sr0.device_random self._print_verbose( "Device Public Key:\t" + utils.str_to_hexstr(self.device_public_key.decode('latin-1'))) self._print_verbose( "Device Random:\t" + utils.str_to_hexstr(device_random.decode('latin-1'))) # Calculate Curve25519 shared key using Client private key and Device public key sharedK = self.client_private_key.exchange( X25519PublicKey.from_public_bytes(self.device_public_key)) self._print_verbose("Shared Key:\t" + utils.str_to_hexstr(sharedK.decode('latin-1'))) # If PoP is provided, XOR SHA256 of PoP with the previously # calculated Shared Key to form the actual Shared Key if len(self.pop) > 0: # Calculate SHA256 of PoP h = hashes.Hash(hashes.SHA256(), backend=default_backend()) h.update(self.pop) digest = h.finalize() # XOR with and update Shared Key sharedK = xor(sharedK, digest) self._print_verbose("New Shared Key XORed with PoP:\t" + utils.str_to_hexstr(sharedK.decode('latin-1'))) # Initialize the encryption engine with Shared Key and initialization vector cipher = Cipher(algorithms.AES(sharedK), modes.CTR(device_random), backend=default_backend()) self.cipher = cipher.encryptor()
def setup1_response(self, response_data): # Interpret SessionResp1 response packet setup_resp = proto.session_pb2.SessionData() setup_resp.ParseFromString(tobytes(response_data)) # Ensure security scheme matches if setup_resp.sec_ver == session_pb2.SecScheme1: # Read encrypyed device verify string device_verify = setup_resp.sec1.sr1.device_verify_data self._print_verbose( "Device verify:\t" + utils.str_to_hexstr(device_verify.decode('latin-1'))) # Decrypt the device verify string enc_client_pubkey = self.cipher.update( setup_resp.sec1.sr1.device_verify_data) self._print_verbose( "Enc client pubkey:\t " + utils.str_to_hexstr(enc_client_pubkey.decode('latin-1'))) # Match decryped string with client public key if enc_client_pubkey != self.client_public_key: print("Mismatch in device verify") return -2 else: print("Unsupported security protocol") return -1
def scan_start_request(security_ctx, blocking=True, passive=False, group_channels=5, period_ms=120): # Form protobuf request packet for ScanStart command cmd = proto.wifi_scan_pb2.WiFiScanPayload() cmd.msg = proto.wifi_scan_pb2.TypeCmdScanStart cmd.cmd_scan_start.blocking = blocking cmd.cmd_scan_start.passive = passive cmd.cmd_scan_start.group_channels = group_channels cmd.cmd_scan_start.period_ms = period_ms enc_cmd = security_ctx.encrypt_data( cmd.SerializeToString()).decode('latin-1') print_verbose( security_ctx, "Client -> Device (Encrypted CmdScanStart) " + utils.str_to_hexstr(enc_cmd)) return enc_cmd
def custom_data_request(security_ctx, data): # Encrypt the custom data enc_cmd = security_ctx.encrypt_data(data) print_verbose(security_ctx, "Client -> Device (CustomData cmd) " + utils.str_to_hexstr(enc_cmd)) return enc_cmd
def send_data(self, characteristic_uuid, data): print("BLECLI >> Write following data to characteristic with UUID '" + characteristic_uuid + "' :") print("\t>> " + utils.str_to_hexstr(data)) print("BLECLI >> Enter data read from characteristic (in hex) :") resp = input("\t<< ") return utils.hexstr_to_str(resp)