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,
self.bpa = None
self.bpd = []
self.upd_version = 0
+ self.upa = None
+ self.upd = []
self.product_name = 'pyfints'
self.product_version = '0.2'
)
)
- 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:
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.
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,
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
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
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)
_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]))
_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]))
--- /dev/null
+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
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")
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"
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")
+
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']
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)