def aarq(): return acse.ApplicationAssociationRequest( ciphered=False, system_title=None, public_cert=None, authentication=None, authentication_value=None, user_information=acse.UserInformation(content=xdlms.InitiateRequest( proposed_conformance=xdlms.Conformance( general_protection=False, general_block_transfer=False, delta_value_encoding=False, attribute_0_supported_with_set=False, priority_management_supported=False, attribute_0_supported_with_get=False, block_transfer_with_get_or_read=True, block_transfer_with_set_or_write=True, block_transfer_with_action=True, multiple_references=True, data_notification=False, access=False, get=True, set=True, selective_access=True, event_notification=False, action=True, ), proposed_quality_of_service=0, client_max_receive_pdu_size=65535, proposed_dlms_version_number=6, response_allowed=True, dedicated_key=None, )), )
def get_rlrq(self) -> acse.ReleaseRequest: """ Returns a ReleaseRequestApdu to release the current association. """ initiate_request = xdlms.InitiateRequest( proposed_conformance=self.conformance, client_max_receive_pdu_size=self.max_pdu_size, ) return acse.ReleaseRequest( reason=enums.ReleaseRequestReason.NORMAL, user_information=acse.UserInformation(content=initiate_request), )
def test_no_ciphering_no_security_app_context_name_wrong(self): data = bytes.fromhex( "6129A109060760857405080101A203020101A305A103020102BE10040E0800065F1F040000501F01F40007" ) aare = acse.ApplicationAssociationResponse( result=enumerations.AssociationResult.REJECTED_PERMANENT, result_source_diagnostics=enumerations.AcseServiceUserDiagnostics.APPLICATION_CONTEXT_NAME_NOT_SUPPORTED, ciphered=False, authentication=None, system_title=None, public_cert=None, authentication_value=None, user_information=acse.UserInformation( content=InitiateResponse( negotiated_conformance=Conformance( general_protection=False, general_block_transfer=False, delta_value_encoding=False, attribute_0_supported_with_set=False, priority_management_supported=True, attribute_0_supported_with_get=False, block_transfer_with_get_or_read=True, block_transfer_with_set_or_write=False, block_transfer_with_action=False, multiple_references=False, data_notification=False, access=False, get=True, set=True, selective_access=True, event_notification=True, action=True, ), server_max_receive_pdu_size=500, negotiated_dlms_version_number=6, negotiated_quality_of_service=0, ) ), implementation_information=None, responding_ap_invocation_id=None, responding_ae_invocation_id=None, ) assert aare.to_bytes() == data
def aare(): from dlms_cosem import enumerations from dlms_cosem.protocol import acse from dlms_cosem.protocol.xdlms import Conformance, InitiateResponse return acse.ApplicationAssociationResponse( result=enumerations.AssociationResult.ACCEPTED, result_source_diagnostics=enumerations.AcseServiceUserDiagnostics.NULL, ciphered=False, authentication=None, system_title=None, public_cert=None, authentication_value=None, user_information=acse.UserInformation( content=InitiateResponse( negotiated_conformance=Conformance( general_protection=False, general_block_transfer=False, delta_value_encoding=False, attribute_0_supported_with_set=False, priority_management_supported=True, attribute_0_supported_with_get=False, block_transfer_with_get_or_read=True, block_transfer_with_set_or_write=False, block_transfer_with_action=False, multiple_references=False, data_notification=False, access=False, get=True, set=True, selective_access=True, event_notification=True, action=True, ), server_max_receive_pdu_size=500, negotiated_dlms_version_number=6, negotiated_quality_of_service=0, ) ), implementation_information=None, responding_ap_invocation_id=None, responding_ae_invocation_id=None, )
def test_negotiated_conformance_is_updated(): c = DlmsConnection(client_system_title=b"12345678") c.send(c.get_aarq()) c.receive_data( acse.ApplicationAssociationResponseApdu( result=enumerations.AssociationResult.ACCEPTED, result_source_diagnostics=enumerations.AcseServiceUserDiagnostics. NULL, user_information=acse.UserInformation( content=xdlms.InitiateResponseApdu( negotiated_conformance=Conformance( general_protection=True, general_block_transfer=True), server_max_receive_pdu_size=500, )), ).to_bytes()) c.next_event() assert c.conformance.general_protection assert c.conformance.general_block_transfer assert c.max_pdu_size == 500 assert c.state.current_state == state.READY
def protect(self, event) -> Any: """ Will apply the correct protection to apdus depending on the security context """ # ASCE have different rules about protection if isinstance( event, (acse.ApplicationAssociationRequestApdu, acse.ReleaseRequestApdu)): # TODO: Not sure if it is needed to encrypt the IniateRequest when # you are not sending a dedicated_key. if event.user_information: ciphered_initiate_text = self.encrypt( event.user_information.content.to_bytes()) event.user_information = acse.UserInformation( content=xdlms.GlobalCipherInitiateRequest( security_control=self.security_control, invocation_counter=self.client_invocation_counter, ciphered_text=ciphered_initiate_text, )) # XDLMS apdus should be protected with general-glo-cihpering elif isinstance(event, AbstractXDlmsApdu): ciphered_text = self.encrypt(event.to_bytes()) LOG.info(f"Protecting a {type(event)} with GlobalCiphering") event = xdlms.GeneralGlobalCipherApdu( system_title=self.client_system_title, security_control=self.security_control, invocation_counter=self.client_invocation_counter, ciphered_text=ciphered_text, ) else: raise RuntimeError( f"Unable to handle ecryption/protection of {event}") # updated the client_invocation_counter self.client_invocation_counter += 1 return event
def get_aarq(self) -> acse.ApplicationAssociationRequest: """ Returns an AARQ with the appropriate information for setting up the connection. """ if self.global_encryption_key: ciphered_apdus = True else: ciphered_apdus = False initiate_request = xdlms.InitiateRequest( proposed_conformance=self.conformance, client_max_receive_pdu_size=self.max_pdu_size, ) return acse.ApplicationAssociationRequest( ciphered=ciphered_apdus, system_title=self.client_system_title, authentication=self.authentication_method, authentication_value=self.authentication_value, user_information=acse.UserInformation(content=initiate_request), )
def test_no_cipher_no_security_incorrect_dlms_version(self): data = bytes.fromhex( "611FA109060760857405080101A203020101A305A103020101BE0604040E010601" ) aare = acse.ApplicationAssociationResponse( result=enumerations.AssociationResult.REJECTED_PERMANENT, result_source_diagnostics=enumerations.AcseServiceUserDiagnostics.NO_REASON_GIVEN, ciphered=False, authentication=None, system_title=None, public_cert=None, authentication_value=None, user_information=acse.UserInformation( content=ConfirmedServiceError( error=enumerations.InitiateError.DLMS_VERSION_TOO_LOW ) ), implementation_information=None, responding_ap_invocation_id=None, responding_ae_invocation_id=None, ) assert aare.to_bytes() == data