]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
(Re-)Add one step PIN mechanism
authorHenryk Plötz <henryk@ploetzli.ch>
Sun, 19 Aug 2018 23:15:23 +0000 (01:15 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Mon, 3 Dec 2018 18:34:29 +0000 (19:34 +0100)
fints/client.py
fints/dialog.py
fints/fields.py
fints/security.py [new file with mode: 0644]
fints/segments/__init__.py
fints/segments/message.py
tests/test_message_serializer.py
tests/test_models.py

index 7bd9df0cc1fe4ccfe56ad50536e88e5d3666cfdf..00aee6630335d228f1443514435446f8160c688e 100644 (file)
@@ -10,6 +10,7 @@ from .connection import FinTSHTTPSConnection
 from .dialog import FinTSDialogOLD, FinTSDialog
 from .formals import TwoStepParametersCommon
 from .message import FinTSMessageOLD
+from .security import PinTanDummyEncryptionMechanism, PinTanOneStepAuthenticationMechanism
 from .models import (
     SEPAAccount, TANChallenge, TANChallenge3,
     TANChallenge4, TANChallenge5, TANChallenge6,
@@ -47,6 +48,8 @@ class FinTS3Client:
         self.bpa = None
         self.bpd = []
         self.upd_version = 0
+        self.upa = None
+        self.upd = []
         self.product_name = 'pyfints'
         self.product_version = '0.2'
 
@@ -70,8 +73,13 @@ class FinTS3Client:
                 )
             )
 
-        for seg in message.find_segments(HIUPA4):
-            self.upd_version = seg.upd_version
+        upa = message.find_segment_first(HIUPA4)
+        if upa:
+            self.upa = upa
+            self.upd_version = upa.upd_version
+            self.upd = list(
+                message.find_segments('HIUPD')
+            )
 
     def find_bpd(self, type):
         for seg in self.bpd:
@@ -209,28 +217,6 @@ class FinTS3Client:
         if seg:
             return seg.balance_booked.as_mt940_Balance()
 
-    def _create_balance_message(self, dialog: FinTSDialogOLD, account: SEPAAccount):
-        hversion = dialog.hksalversion
-
-        if hversion in (1, 2, 3, 4, 5, 6):
-            acc = ':'.join([
-                account.accountnumber, account.subaccount or '', str(280), account.blz
-            ])
-        elif hversion == 7:
-            acc = ':'.join([
-                account.iban, account.bic, account.accountnumber, account.subaccount or '', str(280), account.blz
-            ])
-        else:
-            raise ValueError('Unsupported HKSAL version {}'.format(hversion))
-
-        return self._new_message(dialog, [
-            HKSAL(
-                3,
-                hversion,
-                acc
-            )
-        ])
-
     def get_holdings(self, account: SEPAAccount):
         """
         Retrieve holdings of an account.
@@ -520,11 +506,11 @@ class FinTS3PinTanClient(FinTS3Client):
         if not lazy_init:
             self._ensure_system_id()
 
-        return FinTSDialog(self, lazy_init=lazy_init)
-
-        # FIXME
-        # dialog = FinTSDialogOLD(self.blz, self.username, self.pin, self.systemid, self.connection)
-        # return dialog
+        return FinTSDialog(self, 
+            lazy_init=lazy_init,
+            enc_mechanism=PinTanDummyEncryptionMechanism(1),
+            auth_mechanisms=[PinTanOneStepAuthenticationMechanism(self.pin)],
+        )
 
     def _new_message(self, dialog: FinTSDialogOLD, segments, tan=None):
         return FinTSMessageOLD(self.blz, self.username, self.pin, dialog.systemid, dialog.dialogid, dialog.msgno,
index f6f358d65d9bcb02cd893575b7c9004f2a513afa..8092457648c019e8a1642ff5c58ae714e7c1e61e 100644 (file)
@@ -16,12 +16,12 @@ class FinTSDialogError(Exception):
 
 
 class FinTSDialog:
-    def __init__(self, client=None, lazy_init=False):
+    def __init__(self, client=None, lazy_init=False, enc_mechanism=None, auth_mechanisms=[]):
         self.client = client
         self.next_message_number = dict((v, 1) for v in  MessageDirection)
         self.messages = dict((v, {}) for v in MessageDirection)
-        self.auth_mechanisms = []
-        self.enc_mechanism = None
+        self.auth_mechanisms = auth_mechanisms
+        self.enc_mechanism = enc_mechanism
         self.open = False
         self.need_init = True
         self.lazy_init = lazy_init
@@ -91,7 +91,7 @@ class FinTSDialog:
         response = self.client.connection.send(message)
 
         ##assert response.segments[0].message_number == self.next_message_number[response.DIRECTION]
-        # FIXME Better handling
+        # FIXME Better handling of HKEND in exception case
         self.messages[response.segments[0].message_number] = message
         self.next_message_number[response.DIRECTION] += 1
 
@@ -121,12 +121,12 @@ class FinTSDialog:
         return message
 
     def finish_message(self, message):
-        message += HNHBS1(message.segments[0].message_number)
-
         # Create signature(s) in reverse order: from inner to outer
         for auth_mech in reversed(self.auth_mechanisms):
             auth_mech.sign_commit(message)
 
+        message += HNHBS1(message.segments[0].message_number)
+
         if self.enc_mechanism:
             self.enc_mechanism.encrypt(message)
 
index 39e64001daa25252c8cd3d178d19fc3aa9757fb0..ef6dad8685301442a49d9e6e0c41cc72318a72b7 100644 (file)
@@ -333,6 +333,8 @@ class DateField(FixedLengthMixin, NumericField):
     _FIXED_LENGTH = [8]
 
     def _parse_value(self, value):
+        if isinstance(value, datetime.date):
+            return value
         val = super()._parse_value(value)
         val = str(val)
         return datetime.date(int(val[0:4]), int(val[4:6]), int(val[6:8]))
@@ -348,6 +350,8 @@ class TimeField(FixedLengthMixin, DigitsField):
     _FIXED_LENGTH = [6]
 
     def _parse_value(self, value):
+        if isinstance(value, datetime.time):
+            return value
         val = super()._parse_value(value)
         return datetime.time(int(val[0:2]), int(val[2:4]), int(val[4:6]))
 
diff --git a/fints/security.py b/fints/security.py
new file mode 100644 (file)
index 0000000..dd2b685
--- /dev/null
@@ -0,0 +1,150 @@
+import datetime, random
+
+from .message import FinTSMessage
+from .types import SegmentSequence
+from .formals import SecurityProfile, SecurityRole, IdentifiedRole, DateTimeType, UsageEncryption, SecurityIdentificationDetails, SecurityDateTime, EncryptionAlgorithm, KeyName, CompressionFunction, OperationMode, EncryptionAlgorithmCoded, AlgorithmParameterName, AlgorithmParameterIVName, KeyType, SecurityMethod, SecurityApplicationArea, UserDefinedSignature, HashAlgorithm, SignatureAlgorithm, UserDefinedSignature
+from .segments.message import HNVSK3, HNVSD1, HNSHK4, HNSHA2
+
+class EncryptionMechanism:
+    def encrypt(self, message: FinTSMessage):
+        raise NotImplemented()
+
+    def decrypt(self, message: FinTSMessage):
+        raise NotImplemented()
+
+class AuthenticationMechanism:
+    def sign_prepare(self, message: FinTSMessage):
+        raise NotImplemented()
+    
+    def sign_commit(self, message: FinTSMessage):
+        raise NotImplemented()
+    
+    def verify(self, message: FinTSMessage):
+        raise NotImplemented()
+
+class PinTanDummyEncryptionMechanism(EncryptionMechanism):
+    def __init__(self, security_method_version=1):
+        super().__init__()
+        self.security_method_version = security_method_version
+
+    def encrypt(self, message: FinTSMessage):
+        assert message.segments[0].header.type == 'HNHBK'
+        assert message.segments[-1].header.type == 'HNHBS'
+
+        plain_segments = message.segments[1:-1]
+        del message.segments[1:-1]
+
+        _now = datetime.datetime.now()
+
+        message.segments.insert(1,
+            HNVSK3(
+                security_profile=SecurityProfile(SecurityMethod.PIN, self.security_method_version),
+                security_function='998',
+                security_role=SecurityRole.ISS,
+                security_identification_details=SecurityIdentificationDetails(
+                    IdentifiedRole.MS,
+                    identifier=message.dialog.client.system_id,
+                ),
+                security_datetime=SecurityDateTime(
+                    DateTimeType.STS,
+                    _now.date(),
+                    _now.time(),
+                ),
+                encryption_algorithm=EncryptionAlgorithm(
+                    UsageEncryption.OSY,
+                    OperationMode.CBC,
+                    EncryptionAlgorithmCoded.TWOKEY3DES,
+                    b'\x00'*8,
+                    AlgorithmParameterName.KYE,
+                    AlgorithmParameterIVName.IVC,
+                ),
+                key_name=KeyName(
+                    message.dialog.client.bank_identifier,
+                    message.dialog.client.user_id,
+                    KeyType.V,
+                    0,
+                    0,
+                ),
+                compression_function=CompressionFunction.NULL,
+            )
+        )
+        message.segments[1].header.number = 998
+        message.segments.insert(2,
+            HNVSD1(
+                data=SegmentSequence(segments=plain_segments)
+            )
+        )
+        message.segments[2].header.number = 999
+
+    def decrypt(self, message: FinTSMessage):
+        pass
+
+
+class PinTanOneStepAuthenticationMechanism(AuthenticationMechanism):
+    def __init__(self, pin, tan=None):
+        self.pin=pin
+        self.tan=tan
+        self.pending_signature=None
+
+    def sign_prepare(self, message: FinTSMessage):
+        _now = datetime.datetime.now()
+        rand = random.SystemRandom()
+
+        self.pending_signature = HNSHK4(
+            security_profile = SecurityProfile(SecurityMethod.PIN, 1),
+            security_function = '999',
+            security_reference = rand.randint(1000000, 9999999),
+            security_application_area = SecurityApplicationArea.SHM,
+            security_role = SecurityRole.ISS,
+            security_identification_details = SecurityIdentificationDetails(
+                    IdentifiedRole.MS,
+                    identifier=message.dialog.client.system_id,
+                ),
+            security_reference_number = 1,  ## FIXME
+            security_datetime = SecurityDateTime(
+                    DateTimeType.STS,
+                    _now.date(),
+                    _now.time(),
+                ),
+            hash_algorithm = HashAlgorithm(
+                    usage_hash = '1',
+                    hash_algorithm = '999',
+                    algorithm_parameter_name = '1',
+                ),
+            signature_algorithm = SignatureAlgorithm(
+                    usage_signature = '6',
+                    signature_algorithm = '10',
+                    operation_mode = '16',
+                ),
+            key_name = KeyName(
+                    message.dialog.client.bank_identifier,
+                    message.dialog.client.user_id,
+                    KeyType.S,
+                    0,
+                    0,
+                ),
+
+        )
+
+        message += self.pending_signature
+
+    def sign_commit(self, message: FinTSMessage):
+        if not self.pending_signature:
+            raise Error("No signature is pending")
+
+        if self.pending_signature not in message.segments:
+            raise Error("Cannot sign a message that was not prepared")
+    
+        signature = HNSHA2(
+            security_reference = self.pending_signature.security_reference,
+            user_defined_signature = UserDefinedSignature(
+                pin=self.pin,
+                tan=self.tan,
+            ),
+        )
+
+        self.pending_signature = None
+        message += signature
+
+    def verify(self, message: FinTSMessage):
+        pass
index 9d66c602c37424e166cbaf56cba41e98f70d6450..4f018fad8846c704eeb03eed4ccccf7bc77c9857 100644 (file)
@@ -82,43 +82,6 @@ class FinTS3Segment(Container, SubclassesMixin, metaclass=FinTS3SegmentMeta):
         return target_cls
 
 
-class HNVSD1(FinTS3Segment):
-    "Verschlüsselte Daten"
-    data = SegmentSequenceField(_d="Daten, verschlüsselt")
-
-class HNVSK3(FinTS3Segment):
-    "Verschlüsselungskopf"
-    security_profile = DataElementGroupField(type=SecurityProfile, _d="Sicherheitsprofil")
-    security_function = DataElementField(type='code', max_length=3, _d="Sicherheitsfunktion, kodiert")
-    security_role = CodeField(SecurityRole, max_length=3, _d="Rolle des Sicherheitslieferanten, kodiert")
-    security_identification_details = DataElementGroupField(type=SecurityIdentificationDetails, _d="Sicherheitsidentifikation, Details")
-    security_datetime = DataElementGroupField(type=SecurityDateTime, _d="Sicherheitsdatum und -uhrzeit")
-    encryption_algorithm = DataElementGroupField(type=EncryptionAlgorithm, _d="Verschlüsselungsalgorithmus")
-    key_name = DataElementGroupField(type=KeyName, _d="Schlüsselname")
-    compression_function = CodeField(CompressionFunction, max_length=3, _d="Komprimierungsfunktion")
-    certificate = DataElementGroupField(type=Certificate, required=False, _d="Zertifikat")
-
-class HNSHK4(FinTS3Segment):
-    "Signaturkopf"
-    security_profile = DataElementGroupField(type=SecurityProfile, _d="Sicherheitsprofil")
-    security_function = DataElementField(type='code', max_length=3, _d="Sicherheitsfunktion, kodiert")
-    security_reference = DataElementField(type='an', max_length=14, _d="Sicherheitskontrollreferenz")
-    security_application_area = CodeField(SecurityApplicationArea, max_length=3, _d="Bereich der Sicherheitsapplikation, kodiert")
-    security_role = CodeField(SecurityRole, max_length=3, _d="Rolle des Sicherheitslieferanten, kodiert")
-    security_identification_details = DataElementGroupField(type=SecurityIdentificationDetails, _d="Sicherheitsidentifikation, Details")
-    security_reference_number = DataElementField(type='num', max_length=16, _d="Sicherheitsreferenznummer")
-    security_datetime = DataElementGroupField(type=SecurityDateTime, _d="Sicherheitsdatum und -uhrzeit")
-    hash_algorithm = DataElementGroupField(type=HashAlgorithm, _d="Hashalgorithmus")
-    signature_algorithm = DataElementGroupField(type=SignatureAlgorithm, _d="Signaturalgorithmus")
-    key_name = DataElementGroupField(type=KeyName, _d="Schlüsselname")
-    certificate = DataElementGroupField(type=Certificate, required=False, _d="Zertifikat")
-
-class HNSHA2(FinTS3Segment):
-    "Signaturabschluss"
-    security_reference = DataElementField(type='an', max_length=14, _d="Sicherheitskontrollreferenz")
-    validation_result = DataElementField(type='bin', max_length=512, required=False, _d="Validierungsresultat")
-    user_defined_signature = DataElementGroupField(type=UserDefinedSignature, required=False, _d="Benutzerdefinierte Signatur")
-
 class HIRMG2(FinTS3Segment):
     "Rückmeldungen zur Gesamtnachricht"
     responses = DataElementGroupField(type=Response, min_count=1, max_count=99, _d="Rückmeldung")
index 81801847700cb6829a437101cbf37afff587cac4..71cb1f9433eb3c7569447ff66b6f294ee2272f75 100644 (file)
@@ -3,8 +3,8 @@ import time
 from fints.utils import fints_escape
 
 from . import FinTS3SegmentOLD, FinTS3Segment
-from fints.formals import ReferenceMessage
-from fints.fields import DataElementGroupField, DataElementField, ZeroPaddedNumericField
+from fints.formals import ReferenceMessage, SecurityProfile, SecurityRole, SecurityIdentificationDetails, SecurityDateTime, EncryptionAlgorithm, KeyName, CompressionFunction, Certificate, SecurityApplicationArea, HashAlgorithm, SignatureAlgorithm, UserDefinedSignature
+from fints.fields import DataElementGroupField, DataElementField, ZeroPaddedNumericField, CodeField, SegmentSequenceField
 
 class HNHBK3(FinTS3Segment):
     "Nachrichtenkopf"
@@ -157,3 +157,49 @@ class HNHBS(FinTS3SegmentOLD):
             str(msgno)
         ]
         super().__init__(segno, data)
+
+class HNVSK3(FinTS3Segment):
+    """Verschlüsselungskopf, version 3
+
+    Source: FinTS Financial Transaction Services, Sicherheitsverfahren HBCI"""
+    security_profile = DataElementGroupField(type=SecurityProfile, _d="Sicherheitsprofil")
+    security_function = DataElementField(type='code', max_length=3, _d="Sicherheitsfunktion, kodiert")
+    security_role = CodeField(SecurityRole, max_length=3, _d="Rolle des Sicherheitslieferanten, kodiert")
+    security_identification_details = DataElementGroupField(type=SecurityIdentificationDetails, _d="Sicherheitsidentifikation, Details")
+    security_datetime = DataElementGroupField(type=SecurityDateTime, _d="Sicherheitsdatum und -uhrzeit")
+    encryption_algorithm = DataElementGroupField(type=EncryptionAlgorithm, _d="Verschlüsselungsalgorithmus")
+    key_name = DataElementGroupField(type=KeyName, _d="Schlüsselname")
+    compression_function = CodeField(CompressionFunction, max_length=3, _d="Komprimierungsfunktion")
+    certificate = DataElementGroupField(type=Certificate, required=False, _d="Zertifikat")
+
+class HNVSD1(FinTS3Segment):
+    """Verschlüsselte Daten, version 1
+
+    Source: FinTS Financial Transaction Services, Sicherheitsverfahren HBCI"""
+    data = SegmentSequenceField(_d="Daten, verschlüsselt")
+
+class HNSHK4(FinTS3Segment):
+    """Signaturkopf, version 4
+
+    Source: FinTS Financial Transaction Services, Sicherheitsverfahren HBCI"""
+    security_profile = DataElementGroupField(type=SecurityProfile, _d="Sicherheitsprofil")
+    security_function = DataElementField(type='code', max_length=3, _d="Sicherheitsfunktion, kodiert")
+    security_reference = DataElementField(type='an', max_length=14, _d="Sicherheitskontrollreferenz")
+    security_application_area = CodeField(SecurityApplicationArea, max_length=3, _d="Bereich der Sicherheitsapplikation, kodiert")
+    security_role = CodeField(SecurityRole, max_length=3, _d="Rolle des Sicherheitslieferanten, kodiert")
+    security_identification_details = DataElementGroupField(type=SecurityIdentificationDetails, _d="Sicherheitsidentifikation, Details")
+    security_reference_number = DataElementField(type='num', max_length=16, _d="Sicherheitsreferenznummer")
+    security_datetime = DataElementGroupField(type=SecurityDateTime, _d="Sicherheitsdatum und -uhrzeit")
+    hash_algorithm = DataElementGroupField(type=HashAlgorithm, _d="Hashalgorithmus")
+    signature_algorithm = DataElementGroupField(type=SignatureAlgorithm, _d="Signaturalgorithmus")
+    key_name = DataElementGroupField(type=KeyName, _d="Schlüsselname")
+    certificate = DataElementGroupField(type=Certificate, required=False, _d="Zertifikat")
+
+class HNSHA2(FinTS3Segment):
+    """Signaturabschluss, version 2
+
+    Source: FinTS Financial Transaction Services, Sicherheitsverfahren HBCI"""
+    security_reference = DataElementField(type='an', max_length=14, _d="Sicherheitskontrollreferenz")
+    validation_result = DataElementField(type='bin', max_length=512, required=False, _d="Validierungsresultat")
+    user_defined_signature = DataElementGroupField(type=UserDefinedSignature, required=False, _d="Benutzerdefinierte Signatur")
+
index 661fedbe2631016a6128d95a27e018bccff3a11e..4f585ed5c207818a192f367e9ccabe1654eac834 100644 (file)
@@ -63,6 +63,6 @@ def test_escape():
 def test_serialize_2():
     from fints.formals import SegmentSequence
     import fints.formals, fints.segments
-    s = SegmentSequence([fints.segments.message.HNHBK3(header=fints.formals.SegmentHeader('HNHBK', 1, 3), message_size='000000000428', hbci_version=300, dialogue_id='430711670077=043999659571CN9D=', message_number=2, reference_message=fints.formals.ReferenceMessage(dialogue_id='430711670077=043999659571CN9D=', message_number=2)), fints.segments.HNVSK3(header=fints.formals.SegmentHeader('HNVSK', 998, 3), security_profile=fints.formals.SecurityProfile(security_method='PIN', security_method_version=1), security_function='998', security_role='1', security_identification_details=fints.formals.SecurityIdentificationDetails(identified_role='2', cid=None, identifier='oIm3BlHv6mQBAADYgbPpp+kWrAQA'), security_datetime=fints.formals.SecurityDateTime(date_time_type='1'), encryption_algorithm=fints.formals.EncryptionAlgorithm(usage_encryption='2', operation_mode='2', encryption_algorithm='13', algorithm_parameter_value=b'00000000', algorithm_parameter_name='5', algorithm_parameter_iv_name='1'), key_name=fints.formals.KeyName(bank_identifier=fints.formals.BankIdentifier(country_identifier='280', bank_code='15050500'), user_id='hermes', key_type='S', key_number=0, key_version=0), compression_function='0'), fints.segments.HNVSD1(header=fints.formals.SegmentHeader('HNVSD', 999, 1), data=SegmentSequence([fints.segments.HNSHK4(header=fints.formals.SegmentHeader('HNSHK', 2, 4), security_profile=fints.formals.SecurityProfile(security_method='PIN', security_method_version=1), security_function='999', security_reference='9166926', security_application_area='1', security_role='1', security_identification_details=fints.formals.SecurityIdentificationDetails(identified_role='2', cid=None, identifier='oIm3BlHv6mQBAADYgbPpp+kWrAQA'), security_reference_number=1, security_datetime=fints.formals.SecurityDateTime(date_time_type='1'), hash_algorithm=fints.formals.HashAlgorithm(usage_hash='1', hash_algorithm='999', algorithm_parameter_name='1'), signature_algorithm=fints.formals.SignatureAlgorithm(usage_signature='6', signature_algorithm='10', operation_mode='16'), key_name=fints.formals.KeyName(bank_identifier=fints.formals.BankIdentifier(country_identifier='280', bank_code='15050500'), user_id='hermes', key_type='S', key_number=0, key_version=0)), fints.segments.HIRMG2(header=fints.formals.SegmentHeader('HIRMG', 3, 2), responses=[fints.formals.Response(code='0010', reference_element=None, text='Nachricht entgegengenommen.'), fints.formals.Response(code='0100', reference_element=None, text='Dialog beendet.')]), fints.segments.HNSHA2(header=fints.formals.SegmentHeader('HNSHA', 4, 2), security_reference='9166926')])), fints.segments.message.HNHBS1(header=fints.formals.SegmentHeader('HNHBS', 5, 1), message_number=2)])
+    s = SegmentSequence([fints.segments.message.HNHBK3(header=fints.formals.SegmentHeader('HNHBK', 1, 3), message_size='000000000428', hbci_version=300, dialogue_id='430711670077=043999659571CN9D=', message_number=2, reference_message=fints.formals.ReferenceMessage(dialogue_id='430711670077=043999659571CN9D=', message_number=2)), fints.segments.message.HNVSK3(header=fints.formals.SegmentHeader('HNVSK', 998, 3), security_profile=fints.formals.SecurityProfile(security_method='PIN', security_method_version=1), security_function='998', security_role='1', security_identification_details=fints.formals.SecurityIdentificationDetails(identified_role='2', cid=None, identifier='oIm3BlHv6mQBAADYgbPpp+kWrAQA'), security_datetime=fints.formals.SecurityDateTime(date_time_type='1'), encryption_algorithm=fints.formals.EncryptionAlgorithm(usage_encryption='2', operation_mode='2', encryption_algorithm='13', algorithm_parameter_value=b'00000000', algorithm_parameter_name='5', algorithm_parameter_iv_name='1'), key_name=fints.formals.KeyName(bank_identifier=fints.formals.BankIdentifier(country_identifier='280', bank_code='15050500'), user_id='hermes', key_type='S', key_number=0, key_version=0), compression_function='0'), fints.segments.message.HNVSD1(header=fints.formals.SegmentHeader('HNVSD', 999, 1), data=SegmentSequence([fints.segments.message.HNSHK4(header=fints.formals.SegmentHeader('HNSHK', 2, 4), security_profile=fints.formals.SecurityProfile(security_method='PIN', security_method_version=1), security_function='999', security_reference='9166926', security_application_area='1', security_role='1', security_identification_details=fints.formals.SecurityIdentificationDetails(identified_role='2', cid=None, identifier='oIm3BlHv6mQBAADYgbPpp+kWrAQA'), security_reference_number=1, security_datetime=fints.formals.SecurityDateTime(date_time_type='1'), hash_algorithm=fints.formals.HashAlgorithm(usage_hash='1', hash_algorithm='999', algorithm_parameter_name='1'), signature_algorithm=fints.formals.SignatureAlgorithm(usage_signature='6', signature_algorithm='10', operation_mode='16'), key_name=fints.formals.KeyName(bank_identifier=fints.formals.BankIdentifier(country_identifier='280', bank_code='15050500'), user_id='hermes', key_type='S', key_number=0, key_version=0)), fints.segments.HIRMG2(header=fints.formals.SegmentHeader('HIRMG', 3, 2), responses=[fints.formals.Response(code='0010', reference_element=None, text='Nachricht entgegengenommen.'), fints.formals.Response(code='0100', reference_element=None, text='Dialog beendet.')]), fints.segments.message.HNSHA2(header=fints.formals.SegmentHeader('HNSHA', 4, 2), security_reference='9166926')])), fints.segments.message.HNHBS1(header=fints.formals.SegmentHeader('HNHBS', 5, 1), message_number=2)])
     
     assert FinTS3Serializer().serialize_message(s) == TEST_MESSAGES['basic_simple']
index 10fa2f639f6603603e0b672ddb780904201f9875..7ca30101554d252049cff17d4b4c28073208ba39 100644 (file)
@@ -120,7 +120,7 @@ def test_find_subclass():
 def test_nested_output_evalable():
     import fints.segments, fints.formals
 
-    a = SegmentSequence([fints.segments.message.HNHBK3(header=fints.formals.SegmentHeader('HNHBK', 1, 3, None), message_size='000000000428', hbci_version=300, dialogue_id='430711670077=043999659571CN9D=', message_number=2, reference_message=fints.formals.ReferenceMessage(dialogue_id='430711670077=043999659571CN9D=', message_number=2)), fints.segments.HNVSK3(header=fints.formals.SegmentHeader('HNVSK', 998, 3, None), security_profile=fints.formals.SecurityProfile(security_method='PIN', security_method_version=1), security_function='998', security_role='1', security_identification_details=fints.formals.SecurityIdentificationDetails(identified_role='2', cid=None, identifier='oIm3BlHv6mQBAADYgbPpp+kWrAQA'), security_datetime=fints.formals.SecurityDateTime(date_time_type='1', date=None, time=None), encryption_algorithm=fints.formals.EncryptionAlgorithm(usage_encryption='2', operation_mode='2', encryption_algorithm='13', algorithm_parameter_value=b'00000000', algorithm_parameter_name='5', algorithm_parameter_iv_name='1', algorithm_parameter_iv_value=None), key_name=fints.formals.KeyName(bank_identifier=fints.formals.BankIdentifier(country_identifier='280', bank_code='15050500'), user_id='hermes', key_type='S', key_number=0, key_version=0), compression_function='0', certificate=fints.formals.Certificate(certificate_type=None, certificate_content=None)), fints.segments.HNVSD1(header=fints.formals.SegmentHeader('HNVSD', 999, 1, None), data=SegmentSequence([fints.segments.HNSHK4(header=fints.formals.SegmentHeader('HNSHK', 2, 4, None), security_profile=fints.formals.SecurityProfile(security_method='PIN', security_method_version=1), security_function='999', security_reference='9166926', security_application_area='1', security_role='1', security_identification_details=fints.formals.SecurityIdentificationDetails(identified_role='2', cid=None, identifier='oIm3BlHv6mQBAADYgbPpp+kWrAQA'), security_reference_number=1, security_datetime=fints.formals.SecurityDateTime(date_time_type='1', date=None, time=None), hash_algorithm=fints.formals.HashAlgorithm(usage_hash='1', hash_algorithm='999', algorithm_parameter_name='1', algorithm_parameter_value=None), signature_algorithm=fints.formals.SignatureAlgorithm(usage_signature='6', signature_algorithm='10', operation_mode='16'), key_name=fints.formals.KeyName(bank_identifier=fints.formals.BankIdentifier(country_identifier='280', bank_code='15050500'), user_id='hermes', key_type='S', key_number=0, key_version=0), certificate=fints.formals.Certificate(certificate_type=None, certificate_content=None)), fints.segments.FinTS3Segment(header=fints.formals.SegmentHeader('HIRMG', 3, 2, None), _additional_data=[['0010', None, 'Nachricht entgegengenommen.'], ['0100', None, 'Dialog beendet.']]), fints.segments.FinTS3Segment(header=fints.formals.SegmentHeader('HNSHA', 4, 2, None), _additional_data=['9166926'])])), fints.segments.message.HNHBS1(header=fints.formals.SegmentHeader('HNHBS', 5, 1, None), message_number=2)])
+    a = SegmentSequence([fints.segments.message.HNHBK3(header=fints.formals.SegmentHeader('HNHBK', 1, 3, None), message_size='000000000428', hbci_version=300, dialogue_id='430711670077=043999659571CN9D=', message_number=2, reference_message=fints.formals.ReferenceMessage(dialogue_id='430711670077=043999659571CN9D=', message_number=2)), fints.segments.message.HNVSK3(header=fints.formals.SegmentHeader('HNVSK', 998, 3, None), security_profile=fints.formals.SecurityProfile(security_method='PIN', security_method_version=1), security_function='998', security_role='1', security_identification_details=fints.formals.SecurityIdentificationDetails(identified_role='2', cid=None, identifier='oIm3BlHv6mQBAADYgbPpp+kWrAQA'), security_datetime=fints.formals.SecurityDateTime(date_time_type='1', date=None, time=None), encryption_algorithm=fints.formals.EncryptionAlgorithm(usage_encryption='2', operation_mode='2', encryption_algorithm='13', algorithm_parameter_value=b'00000000', algorithm_parameter_name='5', algorithm_parameter_iv_name='1', algorithm_parameter_iv_value=None), key_name=fints.formals.KeyName(bank_identifier=fints.formals.BankIdentifier(country_identifier='280', bank_code='15050500'), user_id='hermes', key_type='S', key_number=0, key_version=0), compression_function='0', certificate=fints.formals.Certificate(certificate_type=None, certificate_content=None)), fints.segments.message.HNVSD1(header=fints.formals.SegmentHeader('HNVSD', 999, 1, None), data=SegmentSequence([fints.segments.message.HNSHK4(header=fints.formals.SegmentHeader('HNSHK', 2, 4, None), security_profile=fints.formals.SecurityProfile(security_method='PIN', security_method_version=1), security_function='999', security_reference='9166926', security_application_area='1', security_role='1', security_identification_details=fints.formals.SecurityIdentificationDetails(identified_role='2', cid=None, identifier='oIm3BlHv6mQBAADYgbPpp+kWrAQA'), security_reference_number=1, security_datetime=fints.formals.SecurityDateTime(date_time_type='1', date=None, time=None), hash_algorithm=fints.formals.HashAlgorithm(usage_hash='1', hash_algorithm='999', algorithm_parameter_name='1', algorithm_parameter_value=None), signature_algorithm=fints.formals.SignatureAlgorithm(usage_signature='6', signature_algorithm='10', operation_mode='16'), key_name=fints.formals.KeyName(bank_identifier=fints.formals.BankIdentifier(country_identifier='280', bank_code='15050500'), user_id='hermes', key_type='S', key_number=0, key_version=0), certificate=fints.formals.Certificate(certificate_type=None, certificate_content=None)), fints.segments.FinTS3Segment(header=fints.formals.SegmentHeader('HIRMG', 3, 2, None), _additional_data=[['0010', None, 'Nachricht entgegengenommen.'], ['0100', None, 'Dialog beendet.']]), fints.segments.FinTS3Segment(header=fints.formals.SegmentHeader('HNSHA', 4, 2, None), _additional_data=['9166926'])])), fints.segments.message.HNHBS1(header=fints.formals.SegmentHeader('HNHBS', 5, 1, None), message_number=2)])
 
     output = StringIO()
     a.print_nested(stream=output)