def __init__(self, cert_file, password, provozovna=1, pokladna='lidicka', testing=True, eet_url='https://pg.eet.cz:443/eet/services/EETServiceSOAP/v3'): self._cert_file = cert_file self._testing = testing self._pokladna = pokladna self._provozovna = provozovna self._eet_url = eet_url self._signing = Signing(cert_file, password) components = self._signing.get_cert_subject().get_components() cn = [x for x in components if x[0] == b'CN'] assert(len(cn) == 1) self._dic = cn[0][1].decode('utf8') print('DIC: %s' % self._dic)
def hbs_taskAgent(self, toAgent, task, key, id, expiry=None, investigationId=None): # Make sure it's a valid agentid a = AgentId(toAgent) if not type(task) is rSequence: return None s = Signing(key) r = rpcm(isHumanReadable=True, isDebug=True) tags = Symbols() if investigationId is not None and '' != investigationId: task.addStringA(tags.hbs.INVESTIGATION_ID, investigationId) toSign = (rSequence().addSequence( tags.base.HCP_IDENT, rSequence().addBuffer( tags.base.HCP_SENSOR_ID, (a.sensor_id if a.sensor_id is not None else self.empty_uuid).bytes).addBuffer( tags.base.HCP_ORG_ID, (a.org_id if a.org_id is not None else self.empty_uuid).bytes).addBuffer( tags.base.HCP_INSTALLER_ID, (a.ins_id if a.ins_id is not None else self.empty_uuid).bytes).addInt32( tags.base.HCP_ARCHITECTURE, a.architecture if a.architecture is not None else 0).addInt32( tags.base.HCP_PLATFORM, a.platform if a.platform is not None else 0)).addSequence( tags.hbs.NOTIFICATION, task).addInt32(tags.hbs.NOTIFICATION_ID, id)) if None != expiry: toSign.addTimestamp(tags.base.EXPIRY, int(expiry)) toSign = r.serialise(toSign) sig = s.sign(toSign) final = r.serialise(rSequence().addBuffer( tags.base.BINARY, toSign).addBuffer(tags.base.SIGNATURE, sig)) return self._query('hbs.task_agent', { 'task': final, 'aid': str(a), 'expiry': expiry })
def hbs_taskAgent(self, toAgent, task, key, id, expiry=None, investigationId=None): # Make sure it's a valid agentid a = AgentId(toAgent) if not a.isValid: return None if not type(task) is rSequence: return None s = Signing(key) r = rpcm(isHumanReadable=True, isDebug=True) tags = Symbols() if investigationId is not None and '' != investigationId: task.addStringA(tags.hbs.INVESTIGATION_ID, investigationId) toSign = (rSequence().addSequence( tags.base.HCP_ID, rSequence().addInt8(tags.base.HCP_ID_ORG, a.org).addInt8( tags.base.HCP_ID_SUBNET, a.subnet).addInt32(tags.base.HCP_ID_UNIQUE, a.unique).addInt8( tags.base.HCP_ID_PLATFORM, a.platform).addInt8( tags.base.HCP_ID_CONFIG, a.config)).addSequence( tags.hbs.NOTIFICATION, task).addInt32(tags.hbs.NOTIFICATION_ID, id)) if None != expiry: toSign.addTimestamp(tags.base.EXPIRY, int(expiry)) toSign = r.serialise(toSign) sig = s.sign(toSign) final = r.serialise(rSequence().addBuffer( tags.base.BINARY, toSign).addBuffer(tags.base.SIGNATURE, sig)) return self._query('hbs.task_agent', { 'task': final, 'agentid': str(a), 'expiry': expiry })
def generate_package(self, filename, preserve_work_directory=False): """ Generates a Nordic DFU package. The package is a zip file containing firmware(s) and metadata required for Nordic DFU applications to perform DFU onn nRF5X devices. :param str filename: Filename for generated package. :param bool preserve_work_directory: True to preserve the temporary working directory. Useful for debugging of a package, and if the user wants to look at the generated package without having to unzip it. :return: None """ work_directory = self.__create_temp_workspace() if Package._is_bootloader_softdevice_combination(self.firmwares_data): # Removing softdevice and bootloader data from dictionary and adding the combined later softdevice_fw_data = self.firmwares_data.pop(HexType.SOFTDEVICE) bootloader_fw_data = self.firmwares_data.pop(HexType.BOOTLOADER) softdevice_fw_name = softdevice_fw_data[ FirmwareKeys.FIRMWARE_FILENAME] bootloader_fw_name = bootloader_fw_data[ FirmwareKeys.FIRMWARE_FILENAME] new_filename = "sd_bl.bin" sd_bl_file_path = os.path.join(work_directory, new_filename) nrf_hex = nRFHex(softdevice_fw_name, bootloader_fw_name) nrf_hex.tobinfile(sd_bl_file_path) softdevice_size = nrf_hex.size() bootloader_size = nrf_hex.bootloadersize() self.__add_firmware_info( HexType.SD_BL, sd_bl_file_path, softdevice_fw_data[FirmwareKeys.INIT_PACKET_DATA], softdevice_size, bootloader_size) for key, firmware_data in self.firmwares_data.iteritems(): # Normalize the firmware file and store it in the work directory firmware_data[FirmwareKeys.BIN_FILENAME] = \ Package.normalize_firmware_to_bin(work_directory, firmware_data[FirmwareKeys.FIRMWARE_FILENAME]) # Calculate the hash for the .bin file located in the work directory bin_file_path = os.path.join( work_directory, firmware_data[FirmwareKeys.BIN_FILENAME]) firmware_hash = Package.calculate_sha256_hash(bin_file_path) bin_length = int(Package.calculate_file_size(bin_file_path)) sd_size = 0 bl_size = 0 app_size = 0 if key == HexType.APPLICATION: app_size = bin_length elif key == HexType.SOFTDEVICE: sd_size = bin_length elif key == HexType.BOOTLOADER: bl_size = bin_length elif key == HexType.SD_BL: bl_size = firmware_data[FirmwareKeys.BL_SIZE] sd_size = firmware_data[FirmwareKeys.SD_SIZE] init_packet = InitPacketPB( hash_bytes=firmware_hash, dfu_type=HexTypeToInitPacketFwTypemap[key], hash_type=HashTypes.SHA256, app_size=app_size, sd_size=sd_size, bl_size=bl_size, fw_version=firmware_data[FirmwareKeys.INIT_PACKET_DATA][ PacketField.APP_VERSION], hw_version=firmware_data[FirmwareKeys.INIT_PACKET_DATA][ PacketField.DEVICE_REVISION], sd_req=firmware_data[FirmwareKeys.INIT_PACKET_DATA][ PacketField.REQUIRED_SOFTDEVICES_ARRAY]) signer = Signing() signer.load_key(self.key_file) signature = signer.sign(init_packet.get_init_command_bytes()) init_packet.set_signature(signature, SigningTypes.ECDSA_P256_SHA256) # Store the .dat file in the work directory init_packet_filename = firmware_data[ FirmwareKeys.BIN_FILENAME].replace(".bin", ".dat") with open(os.path.join(work_directory, init_packet_filename), 'wb') as init_packet_file: init_packet_file.write(init_packet.get_init_packet_pb_bytes()) firmware_data[FirmwareKeys.DAT_FILENAME] = \ init_packet_filename # Store the manifest to manifest.json manifest = self.create_manifest() with open(os.path.join(work_directory, Package.MANIFEST_FILENAME), "w") as manifest_file: manifest_file.write(manifest) # Package the work_directory to a zip file Package.create_zip_package(work_directory, filename) # Delete the temporary directory if not preserve_work_directory: shutil.rmtree(work_directory)
def do_login( self, s ): '''Login to the BE using credentials stored in a config file.''' parser = self.getParser( 'login' ) parser.add_argument( 'configFile', type = argparse.FileType( 'r' ), help = 'config file specifying the endpoint and token to use' ) parser.add_argument( '-k', '--key', required = False, default = None, #type = argparse.FileType( 'r' ), type = str, help = 'key to use to sign hbs tasks', dest = 'key' ) arguments = self.parse( parser, s ) if arguments is not None: try: config = json.loads( arguments.configFile.read() ) except: print( "Invalid config file format (JSON): %s" % traceback.format_exc() ) return if 'beach_config' not in config or 'token' not in config: print( "Missing endpoint or token in config." ) return _ = os.getcwd() os.chdir( os.path.dirname( __file__ ) ) self.be = BEAdmin( config[ 'beach_config' ], config[ 'token' ] ) os.chdir( _ ) remoteTime = self.be.testConnection() if remoteTime.isTimedOut: print( "Endpoint did not respond." ) return if 'pong' not in remoteTime.data: print( "Endpoint responded with invalid data." ) return if arguments.key is not None: if os.path.isfile( arguments.key ): try: password = getpass.getpass() print( "...decrypting key..." ) # There are weird problems with pexpect and newlines and binary, so # we have to brute force it a bit for i in range( 0, 30 ): proc = pexpect.spawn( 'openssl aes-256-cbc -d -in %s' % arguments.key ) proc.expect( [ 'enter aes-256-cbc decryption password: *' ] ) proc.sendline( password ) proc.expect( "\r\n" ) proc.expect( ".*" ) self.hbsKey = proc.match.group( 0 ).replace( "\r\n", "\n" ) try: testSign = Signing( self.hbsKey ) testSig = testSign.sign( 'a' ) if testSig is not None: break except: self.hbsKey = None if self.hbsKey is not None: print( "success, authenticated!" ) else: print( "error loading key, bad key format or password?" ) except: self.hbsKey = None print( "error getting cloud key: %s" % traceback.format_exc() ) if self.hbsKey is not None and 'bad decrypt' in self.hbsKey: print( "Invalid password" ) self.hbsKey = None else: print( "Invalid key file: %s." % arguments.key ) self.hbsKey = None else: self.hbsKey = None remoteTime = remoteTime.data.get( 'pong', 0 ) print( "Successfully logged in." ) print( "Remote endpoint time: %s." % remoteTime ) self.user = config[ 'token' ].split( '/' )[ 0 ] self.updatePrompt()
def generate_package(self, filename, preserve_work_directory=False): """ Generates a Nordic DFU package. The package is a zip file containing firmware(s) and metadata required for Nordic DFU applications to perform DFU onn nRF5X devices. :param str filename: Filename for generated package. :param bool preserve_work_directory: True to preserve the temporary working directory. Useful for debugging of a package, and if the user wants to look at the generated package without having to unzip it. :return: None """ work_directory = self.__create_temp_workspace() if Package._is_bootloader_softdevice_combination(self.firmwares_data): # Removing softdevice and bootloader data from dictionary and adding the combined later softdevice_fw_data = self.firmwares_data.pop(HexType.SOFTDEVICE) bootloader_fw_data = self.firmwares_data.pop(HexType.BOOTLOADER) softdevice_fw_name = softdevice_fw_data[ FirmwareKeys.FIRMWARE_FILENAME] bootloader_fw_name = bootloader_fw_data[ FirmwareKeys.FIRMWARE_FILENAME] new_filename = "sd_bl.bin" sd_bl_file_path = os.path.join(work_directory, new_filename) nrf_hex = nRFHex(softdevice_fw_name, bootloader_fw_name) nrf_hex.tobinfile(sd_bl_file_path) softdevice_size = nrf_hex.size() bootloader_size = nrf_hex.bootloadersize() self.__add_firmware_info( HexType.SD_BL, sd_bl_file_path, softdevice_fw_data[FirmwareKeys.INIT_PACKET_DATA], softdevice_size, bootloader_size) for key in self.firmwares_data: firmware = self.firmwares_data[key] # Normalize the firmware file and store it in the work directory firmware[FirmwareKeys.BIN_FILENAME] = \ Package.normalize_firmware_to_bin(work_directory, firmware[FirmwareKeys.FIRMWARE_FILENAME]) # Calculate the hash for the .bin file located in the work directory bin_file_path = os.path.join(work_directory, firmware[FirmwareKeys.BIN_FILENAME]) init_packet_data = firmware[FirmwareKeys.INIT_PACKET_DATA] if self.dfu_ver <= 0.5: firmware_hash = Package.calculate_crc16(bin_file_path) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16] = firmware_hash elif self.dfu_ver == 0.6: init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_USES_CRC16 firmware_hash = Package.calculate_crc16(bin_file_path) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16] = firmware_hash elif self.dfu_ver == 0.7: init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_USES_HASH init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH] = int( Package.calculate_file_size(bin_file_path)) firmware_hash = Package.calculate_sha256_hash(bin_file_path) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH] = firmware_hash elif self.dfu_ver == 0.8: init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_EXT_USES_ECDS firmware_hash = Package.calculate_sha256_hash(bin_file_path) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH] = int( Package.calculate_file_size(bin_file_path)) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH] = firmware_hash temp_packet = self._create_init_packet(firmware) signer = Signing() signer.load_key(self.key_file) signature = signer.sign(temp_packet) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS] = signature # Store the .dat file in the work directory init_packet = self._create_init_packet(firmware) init_packet_filename = firmware[FirmwareKeys.BIN_FILENAME].replace( ".bin", ".dat") with open(os.path.join(work_directory, init_packet_filename), 'wb') as init_packet_file: init_packet_file.write(init_packet) firmware[FirmwareKeys.DAT_FILENAME] = \ init_packet_filename # Store the manifest to manifest.json manifest = self.create_manifest() with open(os.path.join(work_directory, Package.MANIFEST_FILENAME), "w") as manifest_file: manifest_file.write(manifest) # Package the work_directory to a zip file Package.create_zip_package(work_directory, filename) # Delete the temporary directory if not preserve_work_directory: shutil.rmtree(work_directory)