Implemented signing messages (but cannot tell yet if it's working)
This commit is contained in:
parent
a6a7930c29
commit
bed585fc04
|
@ -1,12 +1,17 @@
|
||||||
package net.dankito.fints
|
package net.dankito.fints
|
||||||
|
|
||||||
import net.dankito.fints.messages.MessageBuilder
|
import net.dankito.fints.messages.MessageBuilder
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemID
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
|
||||||
|
import net.dankito.fints.model.AccountCredentials
|
||||||
import net.dankito.fints.model.BankInfo
|
import net.dankito.fints.model.BankInfo
|
||||||
import net.dankito.fints.model.ProductInfo
|
import net.dankito.fints.model.ProductInfo
|
||||||
import net.dankito.fints.util.IBase64Service
|
import net.dankito.fints.util.IBase64Service
|
||||||
import net.dankito.utils.web.client.IWebClient
|
import net.dankito.utils.web.client.IWebClient
|
||||||
import net.dankito.utils.web.client.OkHttpWebClient
|
import net.dankito.utils.web.client.OkHttpWebClient
|
||||||
import net.dankito.utils.web.client.RequestParameters
|
import net.dankito.utils.web.client.RequestParameters
|
||||||
|
import net.dankito.utils.web.client.WebClientResponse
|
||||||
|
|
||||||
|
|
||||||
open class FinTsClient(
|
open class FinTsClient(
|
||||||
|
@ -16,15 +21,37 @@ open class FinTsClient(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
fun getBankInfo(bankInfo: BankInfo, productInfo: ProductInfo) {
|
fun getAnonymousBankInfo(bankInfo: BankInfo, productInfo: ProductInfo) {
|
||||||
val requestBody = messageBuilder.createAnonymousDialogInitMessage(bankInfo.countryCode, bankInfo.bankCode,
|
val requestBody = messageBuilder.createAnonymousDialogInitMessage(bankInfo.countryCode, bankInfo.bankCode,
|
||||||
productInfo.productName, productInfo.productVersion)
|
productInfo.productName, productInfo.productVersion)
|
||||||
|
|
||||||
|
val response = getResponseForMessage(requestBody, bankInfo)
|
||||||
|
|
||||||
|
handleResponse(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBankInfo(credentials: AccountCredentials, bankInfo: BankInfo, productInfo: ProductInfo) {
|
||||||
|
val requestBody = messageBuilder.createDialogInitMessage(bankInfo.countryCode, bankInfo.bankCode,
|
||||||
|
credentials.customerId, KundensystemID.PinTan, KundensystemStatusWerte.Benoetigt, 0, 0, Dialogsprache.German,
|
||||||
|
productInfo.productName, productInfo.productVersion)
|
||||||
|
|
||||||
|
val response = getResponseForMessage(requestBody, bankInfo)
|
||||||
|
|
||||||
|
handleResponse(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun getResponseForMessage(requestBody: String, bankInfo: BankInfo): WebClientResponse {
|
||||||
val encodedRequestBody = base64Service.encode(requestBody)
|
val encodedRequestBody = base64Service.encode(requestBody)
|
||||||
|
|
||||||
val response = webClient.post(RequestParameters(bankInfo.finTsServerAddress, encodedRequestBody, "application/octet-stream"))
|
return webClient.post(
|
||||||
|
RequestParameters(bankInfo.finTsServerAddress, encodedRequestBody, "application/octet-stream")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun handleResponse(response: WebClientResponse) {
|
||||||
val responseBody = response.body
|
val responseBody = response.body
|
||||||
|
|
||||||
if (response.isSuccessful && responseBody != null) {
|
if (response.isSuccessful && responseBody != null) {
|
||||||
|
|
||||||
val decodedResponse = decodeBase64Response(responseBody)
|
val decodedResponse = decodeBase64Response(responseBody)
|
||||||
|
|
|
@ -18,7 +18,7 @@ package net.dankito.fints.messages
|
||||||
* nicht den Richtlinien entspricht, so ist dieser abzuweisen. Eine kreditinstitutsseitige Korrektur
|
* nicht den Richtlinien entspricht, so ist dieser abzuweisen. Eine kreditinstitutsseitige Korrektur
|
||||||
* der Auftragsdaten erfolgt nicht.
|
* der Auftragsdaten erfolgt nicht.
|
||||||
*/
|
*/
|
||||||
class HbciCharset {
|
open class HbciCharset {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val DefaultCharset = Charsets.ISO_8859_1
|
val DefaultCharset = Charsets.ISO_8859_1
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
package net.dankito.fints.messages
|
package net.dankito.fints.messages
|
||||||
|
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.*
|
import net.dankito.fints.messages.datenelemente.implementierte.*
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Sicherheitsfunktion
|
||||||
import net.dankito.fints.messages.nachrichten.Nachricht
|
import net.dankito.fints.messages.nachrichten.Nachricht
|
||||||
import net.dankito.fints.messages.segmente.ISegmentNumberGenerator
|
import net.dankito.fints.messages.segmente.ISegmentNumberGenerator
|
||||||
import net.dankito.fints.messages.segmente.Segment
|
import net.dankito.fints.messages.segmente.Segment
|
||||||
import net.dankito.fints.messages.segmente.SegmentNumberGenerator
|
import net.dankito.fints.messages.segmente.SegmentNumberGenerator
|
||||||
import net.dankito.fints.messages.segmente.implementierte.IdentifikationsSegment
|
import net.dankito.fints.messages.segmente.implementierte.*
|
||||||
import net.dankito.fints.messages.segmente.implementierte.Nachrichtenabschluss
|
import net.dankito.fints.util.FinTsUtils
|
||||||
import net.dankito.fints.messages.segmente.implementierte.Nachrichtenkopf
|
|
||||||
import net.dankito.fints.messages.segmente.implementierte.Verarbeitungsvorbereitung
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes the Segments of they payload, may signs and encrypts them, calculates message size,
|
* Takes the Segments of they payload, may signs and encrypts them, calculates message size,
|
||||||
* adds the message header and closing, and formats the whole message to string.
|
* adds the message header and closing, and formats the whole message to string.
|
||||||
*/
|
*/
|
||||||
open class MessageBuilder(protected val generator: ISegmentNumberGenerator = SegmentNumberGenerator()) {
|
open class MessageBuilder(protected val generator: ISegmentNumberGenerator = SegmentNumberGenerator(),
|
||||||
|
protected val utils: FinTsUtils = FinTsUtils()) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MessageHeaderLength = 30
|
const val MessageHeaderLength = 30
|
||||||
|
@ -39,8 +39,8 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
|
||||||
productVersion: String
|
productVersion: String
|
||||||
): String {
|
): String {
|
||||||
|
|
||||||
return createDialogInitMessage(bankCountryCode, bankCode, KundenID.Anonymous, KundensystemID.Anonymous,
|
return createDialogInitMessage(bankCountryCode, bankCode, KundenID.Anonymous, KundensystemID.Anonymous, KundensystemStatusWerte.NichtBenoetigt,
|
||||||
BPDVersion.VersionNotReceivedYet, UPDVersion.VersionNotReceivedYet, Dialogsprache.Default, productName, productVersion)
|
BPDVersion.VersionNotReceivedYet, UPDVersion.VersionNotReceivedYet, Dialogsprache.Default, productName, productVersion, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun createDialogInitMessage(
|
open fun createDialogInitMessage(
|
||||||
|
@ -48,23 +48,29 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
|
||||||
bankCode: String,
|
bankCode: String,
|
||||||
customerId: String,
|
customerId: String,
|
||||||
customerSystemId: String,
|
customerSystemId: String,
|
||||||
|
status: KundensystemStatusWerte,
|
||||||
bpdVersion: Int,
|
bpdVersion: Int,
|
||||||
updVersion: Int,
|
updVersion: Int,
|
||||||
language: Dialogsprache,
|
language: Dialogsprache,
|
||||||
productName: String,
|
productName: String,
|
||||||
productVersion: String
|
productVersion: String,
|
||||||
|
signMessage: Boolean = true
|
||||||
): String {
|
): String {
|
||||||
|
|
||||||
return createMessage(listOf(
|
return createMessage(signMessage, bankCountryCode, bankCode, customerId, listOf(
|
||||||
IdentifikationsSegment(generator.resetSegmentNumber(1), bankCountryCode, bankCode, customerId, customerSystemId),
|
IdentifikationsSegment(generator.resetSegmentNumber(if (signMessage) 2 else 1), bankCountryCode, bankCode, customerId, customerSystemId, status),
|
||||||
Verarbeitungsvorbereitung(generator.getNextSegmentNumber(), bpdVersion, updVersion, language, productName, productVersion)
|
Verarbeitungsvorbereitung(generator.getNextSegmentNumber(), bpdVersion, updVersion, language, productName, productVersion)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun createMessage(payloadSegments: List<Segment>): String {
|
open fun createMessage(signMessage: Boolean, bankCountryCode: Int, bankCode: String, customerId: String,
|
||||||
|
payloadSegments: List<Segment>): String {
|
||||||
|
|
||||||
val payload = payloadSegments.joinToString(Nachricht.SegmentSeparator) { it.format() }
|
val signedPayload = if (signMessage) { signPayload(2, bankCountryCode, bankCode, customerId, payloadSegments) }
|
||||||
|
else { payloadSegments }
|
||||||
|
|
||||||
|
val payload = signedPayload.joinToString(Nachricht.SegmentSeparator) { it.format() }
|
||||||
|
|
||||||
val messageSize = payload.length + MessageHeaderLength + MessageClosingLength + AddedSeparatorsLength
|
val messageSize = payload.length + MessageHeaderLength + MessageClosingLength + AddedSeparatorsLength
|
||||||
val messageNumber = Nachrichtennummer.FirstMessageNumber
|
val messageNumber = Nachrichtennummer.FirstMessageNumber
|
||||||
|
@ -77,4 +83,29 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
|
||||||
.joinToString(Nachricht.SegmentSeparator, postfix = Nachricht.SegmentSeparator)
|
.joinToString(Nachricht.SegmentSeparator, postfix = Nachricht.SegmentSeparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun signPayload(headerSegmentNumber: Int, bankCountryCode: Int, bankCode: String, customerId: String,
|
||||||
|
payloadSegments: List<Segment>): List<Segment> {
|
||||||
|
val controlReference = "1" // TODO
|
||||||
|
|
||||||
|
val signatureHeader = PinTanSignaturkopf(
|
||||||
|
headerSegmentNumber,
|
||||||
|
Sicherheitsfunktion.PIN_TAN_911, // TODO
|
||||||
|
controlReference,
|
||||||
|
"0",
|
||||||
|
utils.formatDateTodayAsInt(),
|
||||||
|
utils.formatTimeNowAsInt(),
|
||||||
|
bankCountryCode,
|
||||||
|
bankCode,
|
||||||
|
customerId
|
||||||
|
)
|
||||||
|
|
||||||
|
val signatureClosing = Signaturabschluss(
|
||||||
|
generator.getNextSegmentNumber(),
|
||||||
|
controlReference,
|
||||||
|
"" // TODO
|
||||||
|
)
|
||||||
|
|
||||||
|
return listOf(signatureHeader, *payloadSegments.toTypedArray(), signatureClosing)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.abgeleiteteformate
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format: JJJJMMTT gemäß ISO 8601
|
||||||
|
*
|
||||||
|
* Erlaubt sind alle existenten Datumsangaben.
|
||||||
|
*/
|
||||||
|
open class Datum(date: Int, existenzstatus: Existenzstatus) : NumerischesDatenelement(date, 8, existenzstatus) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val HbciDateFormat = "yyyyMMdd"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,5 +9,5 @@ import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDat
|
||||||
*
|
*
|
||||||
* Maximal 30 Zeichen
|
* Maximal 30 Zeichen
|
||||||
*/
|
*/
|
||||||
abstract class Identifikation(identifikation: String, existenzstatus: Existenzstatus)
|
abstract class Identifikation(identification: String, existenzstatus: Existenzstatus)
|
||||||
: AlphanumerischesDatenelement(identifikation, existenzstatus, 30)
|
: AlphanumerischesDatenelement(identification, existenzstatus, 30)
|
|
@ -0,0 +1,19 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.abgeleiteteformate
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.ZiffernDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format: hhmmss gemäß ISO 8601
|
||||||
|
*
|
||||||
|
* Gültige Uhrzeit. Es ist immer Ortszeit des sendenden Systems einzustellen.
|
||||||
|
* Unterschiedliche Zeitzonen werden nicht unterstützt
|
||||||
|
*/
|
||||||
|
open class Uhrzeit(time: Int, existenzstatus: Existenzstatus) : ZiffernDatenelement(time, 6, existenzstatus) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val HbciTimeFormat = "HHmmss"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenele
|
||||||
* die im Nachrichtenkopf eingestellt ist und lediglich das syntaktische Format der
|
* die im Nachrichtenkopf eingestellt ist und lediglich das syntaktische Format der
|
||||||
* Nachricht, nicht jedoch deren Inhalt kennzeichnet.
|
* Nachricht, nicht jedoch deren Inhalt kennzeichnet.
|
||||||
*/
|
*/
|
||||||
class BPDVersion(version: Int, existenzstatus: Existenzstatus) : NumerischesDatenelement(version, 3, existenzstatus) {
|
open class BPDVersion(version: Int, existenzstatus: Existenzstatus) : NumerischesDatenelement(version, 3, existenzstatus) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val VersionNotReceivedYet = 0
|
const val VersionNotReceivedYet = 0
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Identifikation
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eindeutig vergebene Kennung, anhand deren die Identifizierung des Benutzers erfolgt.
|
||||||
|
* Die Vergabe obliegt dem Kreditinstitut. Das Kreditinstitut hat zu gewährleisten,
|
||||||
|
* dass die Benutzerkennung institutsweit eindeutig ist. Sie kann beliebige Informationen
|
||||||
|
* enthalten, darf aber bei Verwendung des RAH-Verfahrens aus Sicherheitsgründen nicht aus
|
||||||
|
* benutzer- oder kreditinstitutsspezifischen Merkmalen hergeleitet werden.
|
||||||
|
*/
|
||||||
|
open class Benutzerkennung(identification: String) : Identifikation(identification, Existenzstatus.Mandatory)
|
|
@ -4,4 +4,4 @@ import net.dankito.fints.messages.Existenzstatus
|
||||||
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Identifikation
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Identifikation
|
||||||
|
|
||||||
|
|
||||||
class DialogId(dialogId: String) : Identifikation(dialogId, Existenzstatus.Mandatory)
|
open class DialogId(dialogId: String) : Identifikation(dialogId, Existenzstatus.Mandatory)
|
|
@ -1,7 +1,7 @@
|
||||||
package net.dankito.fints.messages.datenelemente.implementierte
|
package net.dankito.fints.messages.datenelemente.implementierte
|
||||||
|
|
||||||
|
|
||||||
enum class Dialogsprache(val code: String) {
|
enum class Dialogsprache(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
Default("0"),
|
Default("0"),
|
||||||
|
|
||||||
|
|
|
@ -20,16 +20,11 @@ import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
* - 2: Englisch, Code ‚en’ (English), Subset Englisch, Codeset 1 (Latin 1)
|
* - 2: Englisch, Code ‚en’ (English), Subset Englisch, Codeset 1 (Latin 1)
|
||||||
* - 3: Französisch, Code ‚fr’ (French), Subset Französisch, Codeset 1 (Latin 1)
|
* - 3: Französisch, Code ‚fr’ (French), Subset Französisch, Codeset 1 (Latin 1)
|
||||||
*/
|
*/
|
||||||
class DialogspracheDatenelement(language: Dialogsprache, existenzstatus: Existenzstatus)
|
open class DialogspracheDatenelement(language: Dialogsprache, existenzstatus: Existenzstatus)
|
||||||
: Code(language.code, AllowedValues, existenzstatus) {
|
: Code(language.code, AllowedValues, existenzstatus) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val AllowedValues = listOf(
|
val AllowedValues = allCodes<Dialogsprache>()
|
||||||
Dialogsprache.Default.code,
|
|
||||||
Dialogsprache.German.code,
|
|
||||||
Dialogsprache.English.code,
|
|
||||||
Dialogsprache.French.code
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
package net.dankito.fints.messages.datenelemente.implementierte
|
|
||||||
|
|
||||||
import net.dankito.fints.messages.Existenzstatus
|
|
||||||
|
|
||||||
|
|
||||||
open class FinTsKundensystemStatus : KundensystemStatus(KundensystemStatusWerte.NichtBenoetigt, Existenzstatus.Mandatory)
|
|
|
@ -31,4 +31,4 @@ import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenele
|
||||||
* - Version 2.2: 220 (Spezifikationsstatus: obsolet)
|
* - Version 2.2: 220 (Spezifikationsstatus: obsolet)
|
||||||
* - Version 3.0: 300
|
* - Version 3.0: 300
|
||||||
*/
|
*/
|
||||||
class HbciVersionDatenelement(version: HbciVersion) : NumerischesDatenelement(version.versionNumber, 3, Existenzstatus.Mandatory)
|
open class HbciVersionDatenelement(version: HbciVersion) : NumerischesDatenelement(version.versionNumber, 3, Existenzstatus.Mandatory)
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte
|
||||||
|
|
||||||
|
|
||||||
|
inline fun <reified T : Enum<T>> allCodes(): List<String> {
|
||||||
|
return enumValues<T>().map { (it as ICodeEnum).code }
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICodeEnum {
|
||||||
|
|
||||||
|
val code: String
|
||||||
|
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ open class KundensystemID(customerSystemId: String) : Identifikation(customerSys
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val Anonymous = "0"
|
const val Anonymous = "0"
|
||||||
|
|
||||||
|
const val PinTan = Anonymous
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -17,12 +17,7 @@ open class KundensystemStatus(status: KundensystemStatusWerte, existenzstatus: E
|
||||||
: Code(status.code, AllowedValues, existenzstatus) {
|
: Code(status.code, AllowedValues, existenzstatus) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val AllowedValues = listOf(
|
val AllowedValues = allCodes<KundensystemStatusWerte>()
|
||||||
KundensystemStatusWerte.NichtBenoetigt.code,
|
|
||||||
KundensystemStatusWerte.Benoetigt.code
|
|
||||||
)
|
|
||||||
|
|
||||||
val Anonymous = KundensystemStatusWerte.NichtBenoetigt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package net.dankito.fints.messages.datenelemente.implementierte
|
package net.dankito.fints.messages.datenelemente.implementierte
|
||||||
|
|
||||||
|
|
||||||
enum class KundensystemStatusWerte(val code: String) {
|
enum class KundensystemStatusWerte(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
NichtBenoetigt("0"),
|
NichtBenoetigt("0"),
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,4 @@ import net.dankito.fints.messages.datenelemente.basisformate.ZiffernDatenelement
|
||||||
* Das DE ist mit führenden Nullen auf die vorgegebene feste Länge aufzufüllen.
|
* Das DE ist mit führenden Nullen auf die vorgegebene feste Länge aufzufüllen.
|
||||||
* Dies ist erforderlich, damit die Nachrichtenlänge nicht mit der Länge des DE variiert.
|
* Dies ist erforderlich, damit die Nachrichtenlänge nicht mit der Länge des DE variiert.
|
||||||
*/
|
*/
|
||||||
class Nachrichtengroesse(messageSize: Int) : ZiffernDatenelement(messageSize, 12, Existenzstatus.Mandatory)
|
open class Nachrichtengroesse(messageSize: Int) : ZiffernDatenelement(messageSize, 12, Existenzstatus.Mandatory)
|
|
@ -17,7 +17,7 @@ import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenele
|
||||||
* Nachrichten, deren Nummerierung nicht streng monoton aufsteigend erfolgt ist, werden
|
* Nachrichten, deren Nummerierung nicht streng monoton aufsteigend erfolgt ist, werden
|
||||||
* institutsseitig bzw. kundenseitig abgelehnt.
|
* institutsseitig bzw. kundenseitig abgelehnt.
|
||||||
*/
|
*/
|
||||||
class Nachrichtennummer(number: Int) : NumerischesDatenelement(number, 4, Existenzstatus.Mandatory) {
|
open class Nachrichtennummer(number: Int) : NumerischesDatenelement(number, 4, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val FirstMessageNumber = 1
|
const val FirstMessageNumber = 1
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.TextDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
open class NotAllowedDatenelement : TextDatenelement("", Existenzstatus.NotAllowed)
|
|
@ -15,5 +15,5 @@ import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDat
|
||||||
* Kundenprodukte, die nach dem durch die Deutsche Kreditwirtschaft festgelegten Verfahren registriert
|
* Kundenprodukte, die nach dem durch die Deutsche Kreditwirtschaft festgelegten Verfahren registriert
|
||||||
* sind, müssen in dieses DE die vergebene Produktregistrierungsnummer einstellen.
|
* sind, müssen in dieses DE die vergebene Produktregistrierungsnummer einstellen.
|
||||||
*/
|
*/
|
||||||
class Produktbezeichnung(name: String, existenzstatus: Existenzstatus)
|
open class Produktbezeichnung(name: String, existenzstatus: Existenzstatus)
|
||||||
: AlphanumerischesDatenelement(name, existenzstatus, 25)
|
: AlphanumerischesDatenelement(name, existenzstatus, 25)
|
|
@ -11,5 +11,5 @@ import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDat
|
||||||
* Kundenprodukt, nicht eine ggf. verwendete interne FinTS-/HBCI-Bibliothek, zu füllen, um
|
* Kundenprodukt, nicht eine ggf. verwendete interne FinTS-/HBCI-Bibliothek, zu füllen, um
|
||||||
* Support-Anfragen leichter beantworten zu können.
|
* Support-Anfragen leichter beantworten zu können.
|
||||||
*/
|
*/
|
||||||
class Produktversion(version: String, existenzstatus: Existenzstatus)
|
open class Produktversion(version: String, existenzstatus: Existenzstatus)
|
||||||
: AlphanumerischesDatenelement(version, existenzstatus, 5)
|
: AlphanumerischesDatenelement(version, existenzstatus, 5)
|
|
@ -8,7 +8,7 @@ import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenele
|
||||||
* Versionsnummer der Userparameterdaten (UPD). Bei jeder kreditinstitutsseitigen Änderung
|
* Versionsnummer der Userparameterdaten (UPD). Bei jeder kreditinstitutsseitigen Änderung
|
||||||
* wird die Version inkrementiert. (S. auch DE BPD-Version).
|
* wird die Version inkrementiert. (S. auch DE BPD-Version).
|
||||||
*/
|
*/
|
||||||
class UPDVersion(version: Int, existenzstatus: Existenzstatus) : NumerischesDatenelement(version, 3, existenzstatus) {
|
open class UPDVersion(version: Int, existenzstatus: Existenzstatus) : NumerischesDatenelement(version, 3, existenzstatus) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val VersionNotReceivedYet = 0
|
const val VersionNotReceivedYet = 0
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||||
|
|
||||||
|
|
||||||
|
enum class BereichDerSicherheitsapplikation(val abbreviation: String, override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
|
SignaturkopfUndHBCINutzdaten("SHM", "1"),
|
||||||
|
|
||||||
|
VonSignaturkopfBisSignaturabschluss("SHT", "2")
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.allCodes
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information darüber, welche Daten vom kryptographischen Prozess verarbeitet werden.
|
||||||
|
* Diese Information wird benötigt um z. B. zwischen relevanter und belangloser Reihenfolge
|
||||||
|
* von Signaturen zu unterscheiden (vgl. [HBCI], Kapitel VI.4).
|
||||||
|
*
|
||||||
|
* Wenn SHM gewählt wird, so bedeutet dies, dass nur über den eigenen Signaturkopf sowie die
|
||||||
|
* HBCI-Nutzdaten ein Hashwert gebildet wird, der in die Signatur eingeht. Dies entspricht
|
||||||
|
* bei Mehrfachsignaturen einer bedeutungslosen Reihenfolge.
|
||||||
|
*
|
||||||
|
* Wenn SHT gewählt wird, dann werden auch alle schon vorhandenen Signaturköpfe und
|
||||||
|
* -abschlüsse mitsigniert. Das heißt, dass die Reihenfolge der Signaturen relevant ist.
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* - 1: Signaturkopf und HBCI-Nutzdaten (SHM)
|
||||||
|
* - 2: Von Signaturkopf bis Signaturabschluss (SHT)
|
||||||
|
*/
|
||||||
|
open class BereichDerSicherheitsapplikationKodiert(domain: BereichDerSicherheitsapplikation)
|
||||||
|
: Code(domain.code, AllowedValues, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val AllowedValues = allCodes<BereichDerSicherheitsapplikation>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bezeichner für den Hashalgorithmusparameter.
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* 1: IVC (Initialization value, clear text)
|
||||||
|
*/
|
||||||
|
open class BezeichnerFuerHashalgorithmusparameter : AlphanumerischesDatenelement("1", Existenzstatus.Mandatory, 3)
|
|
@ -0,0 +1,14 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifikation der Funktion der beschriebenen Partei, in diesem Falle des Kunden.
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* - 1: Message Sender (MS), wenn ein Kunde etwas an sein Kreditinstitut sendet.
|
||||||
|
* - 2: Message Receiver (MR), wenn das Kreditinstitut etwas an seinen Kunden sendet.
|
||||||
|
*/
|
||||||
|
open class BezeichnerFuerSicherheitspartei : AlphanumerischesDatenelement("1", Existenzstatus.Mandatory, 3)
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||||
|
|
||||||
|
|
||||||
|
enum class DatumUndZeitbezeichner(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
|
Sicherheitszeitstempel("1"),
|
||||||
|
|
||||||
|
CertificateRevocationTime("2")
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.allCodes
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enthält die Bedeutung des Zeitstempels.
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* 1: Sicherheitszeitstempel (STS)
|
||||||
|
* 6: Certificate Revocation Time (CRT)
|
||||||
|
*/
|
||||||
|
open class DatumUndZeitbezeichnerKodiert(identifier: DatumUndZeitbezeichner)
|
||||||
|
: Code(identifier.code, AllowedValues, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val AllowedValues = allCodes<DatumUndZeitbezeichner>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||||
|
|
||||||
|
|
||||||
|
enum class Hashalgorithmus(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
|
SHA_256("3"),
|
||||||
|
|
||||||
|
SHA_384("4"),
|
||||||
|
|
||||||
|
SHA_512("5"),
|
||||||
|
|
||||||
|
SHA_256_SHA_256("6"),
|
||||||
|
|
||||||
|
Gegenseitig_vereinbart("999")
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.allCodes
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code des verwendeten Hash-Algorithmus.
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* 1: SHA-1 (nicht zugelassen)
|
||||||
|
* 2: belegt
|
||||||
|
* 3: SHA-256
|
||||||
|
* 4: SHA-384
|
||||||
|
* 5: SHA-512
|
||||||
|
* 6: SHA-256 / SHA-256
|
||||||
|
* 999: Gegenseitig vereinbart (ZZZ); (nicht zugelassen)
|
||||||
|
*/
|
||||||
|
open class HashalgorithmusKodiert(algorithm: Hashalgorithmus) : Code(algorithm.code, AllowedValues, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val AllowedValues = allCodes<Hashalgorithmus>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Identifikation
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code, welcher die (Kommunikations-)Partei identifiziert. Bei Verwendung des
|
||||||
|
* RAH-Verfahrens ist die Kundensystem-ID einzustellen.
|
||||||
|
*/
|
||||||
|
open class IdentifizierungDerPartei(identification: String) : Identifikation(identification, Existenzstatus.Optional) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SynchronizingCustomerSystemId = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||||
|
|
||||||
|
|
||||||
|
enum class Operationsmodus(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nur für Verschlüsselung erlaubt (vgl. [HBCI], Kapitel VI.2.2)
|
||||||
|
*/
|
||||||
|
Cipher_Block_Chaining("2"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nicht zugelassen
|
||||||
|
*/
|
||||||
|
ISO_9796_1("16"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nicht zugelassen
|
||||||
|
*/
|
||||||
|
ISO_9796_2_mit_Zufallszahl("17"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nicht zugelassen
|
||||||
|
*/
|
||||||
|
RSASSA_PKCS_1_V1_5("18"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nur für Verschlüsselung erlaubt
|
||||||
|
*/
|
||||||
|
RSAES_PKCS_1_V1_5("18"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nur für Signatur erlaubt
|
||||||
|
*/
|
||||||
|
RSASSA_PSS("19"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nicht zugelassen
|
||||||
|
*/
|
||||||
|
Gegenseitig_vereinbart("999")
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.allCodes
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information über den Operationsmodus für den jeweils verwendeten Kryptoalgorithmus
|
||||||
|
* (zur Signaturbildung oder zur Verschlüsselung).
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* Siehe S. 102 oder [Operationsmodus]
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.6 DEG „Signaturalgorithmus“, S. 58):
|
||||||
|
*
|
||||||
|
* Operationsmodus, kodiert
|
||||||
|
* FinTS-Füllwert, z. B. „16“
|
||||||
|
*/
|
||||||
|
open class OperationsmodusKodiert(mode: Operationsmodus) : Code(mode.code, AllowedValues, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val AllowedValues = allCodes<Operationsmodus>()
|
||||||
|
|
||||||
|
val FinTsMockValue = Operationsmodus.ISO_9796_1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
open class PinOrTan(pinOrTan: String) : AlphanumerischesDatenelement(pinOrTan, Existenzstatus.Mandatory)
|
|
@ -0,0 +1,27 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Inhalt dieses Feldes sollte derzeit nicht ausgewertet werden. Optional können aber
|
||||||
|
* die nachfolgenden Festlegungen angewendet werden, sofern dies zwischen Kunde und
|
||||||
|
* Kreditinstitut zuvor vereinbart wurde:
|
||||||
|
*
|
||||||
|
* 1. Dialoginitialisierung und -ende:
|
||||||
|
* Die Rolle wird durch den Dialogführenden bestimmt. Es ist nur eine Signatur erlaubt.
|
||||||
|
* Erlaubt ist nur der Wert ISS/wert12.
|
||||||
|
*
|
||||||
|
* 2. Auftragsnachricht:
|
||||||
|
* Grundsätzlich gilt: Sobald die Rolle „WIT“ verwendet wird, muss dieser Benutzer mit der
|
||||||
|
* Benutzerkennung aus der Dialoginitialisierung arbeiten. Auch der Benutzer „WIT“ muss
|
||||||
|
* bankseitig entsprechend der Auftragsart am Konto des Benutzers „ISS“ berechtigt sein.
|
||||||
|
* Die Reihenfolge der Signaturen ist beliebig.
|
||||||
|
*
|
||||||
|
* [Tabelle mit Werten]
|
||||||
|
*
|
||||||
|
* Auch bei Belegung dieses Feldes kann das Kundenprodukt nicht davon ausgehen, dass das
|
||||||
|
* Feld kreditinstitutsseitig ausgewertet wird.
|
||||||
|
*/
|
||||||
|
open class RolleDesSicherheitslieferantenKodiert : AlphanumerischesDatenelement("1", Existenzstatus.Mandatory, 3)
|
|
@ -0,0 +1,14 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||||
|
|
||||||
|
|
||||||
|
enum class Schluesselart(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
|
SchluesselZurErzeugungDigitalerSignaturen("D"),
|
||||||
|
|
||||||
|
Signierschluessel("S"),
|
||||||
|
|
||||||
|
Chiffrierschluessel("V")
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.allCodes
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information über die Art des Schlüssels.
|
||||||
|
*
|
||||||
|
* Beim Sicherheitsverfahren RAH steht die Schlüsselart in engem Zusammenhang mit dem
|
||||||
|
* Datenelement "Verwendungszweck für öffentlichen Schlüssel". Die Inhalte beider
|
||||||
|
* Datenelemente sind konsistent zu halten.
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* D: Schlüssel zur Erzeugung digitaler Signaturen (DS-Schlüssel)
|
||||||
|
* S: Signierschlüssel
|
||||||
|
* V: Chiffrierschlüssel
|
||||||
|
*
|
||||||
|
* Der DS-Schlüssel steht nur im Zusammenhang mit einer Bankensignaturkarte zur Verfügung.
|
||||||
|
*
|
||||||
|
* Im Falle der Bankensignaturkarte ergibt sich folgende Zuordnung zu den Kartenschlüsseln:
|
||||||
|
* - DS-Schlüssel: SK.CH.DS
|
||||||
|
* - Signierschlüssel: SK.CH.AUT
|
||||||
|
* - Chiffrierschlüssel: SK.CH.KE
|
||||||
|
*/
|
||||||
|
open class SchluesselartDatenelement(key: Schluesselart) : Code(key.code, AllowedValues, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val AllowedValues = allCodes<Schluesselart>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schlüsselnummer des entsprechenden Schlüssels.
|
||||||
|
*/
|
||||||
|
open class Schluesselnummer(number: Int) : NumerischesDatenelement(number, 3, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val FinTsMockValue = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Versionsnummer des entsprechenden Schlüssels.
|
||||||
|
*/
|
||||||
|
open class Schluesselversion(version: Int) : NumerischesDatenelement(version, 3, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val FinTsMockValue = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,214 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||||
|
|
||||||
|
|
||||||
|
enum class Sicherheitsfunktion(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
|
RAH_7_S("2"),
|
||||||
|
|
||||||
|
RAH_7_D("1"),
|
||||||
|
|
||||||
|
RAH_9_S("2"),
|
||||||
|
|
||||||
|
RAH_10_S("2"),
|
||||||
|
|
||||||
|
PIN_TAN_900("900"),
|
||||||
|
|
||||||
|
PIN_TAN_901("901"),
|
||||||
|
|
||||||
|
PIN_TAN_902("902"),
|
||||||
|
|
||||||
|
PIN_TAN_903("903"),
|
||||||
|
|
||||||
|
PIN_TAN_904("904"),
|
||||||
|
|
||||||
|
PIN_TAN_905("905"),
|
||||||
|
|
||||||
|
PIN_TAN_906("906"),
|
||||||
|
|
||||||
|
PIN_TAN_907("907"),
|
||||||
|
|
||||||
|
PIN_TAN_908("908"),
|
||||||
|
|
||||||
|
PIN_TAN_909("909"),
|
||||||
|
|
||||||
|
PIN_TAN_910("910"),
|
||||||
|
|
||||||
|
PIN_TAN_911("911"),
|
||||||
|
|
||||||
|
PIN_TAN_912("912"),
|
||||||
|
|
||||||
|
PIN_TAN_913("913"),
|
||||||
|
|
||||||
|
PIN_TAN_914("914"),
|
||||||
|
|
||||||
|
PIN_TAN_915("915"),
|
||||||
|
|
||||||
|
PIN_TAN_916("916"),
|
||||||
|
|
||||||
|
PIN_TAN_917("917"),
|
||||||
|
|
||||||
|
PIN_TAN_918("918"),
|
||||||
|
|
||||||
|
PIN_TAN_919("919"),
|
||||||
|
|
||||||
|
PIN_TAN_920("920"),
|
||||||
|
|
||||||
|
PIN_TAN_921("921"),
|
||||||
|
|
||||||
|
PIN_TAN_922("922"),
|
||||||
|
|
||||||
|
PIN_TAN_923("923"),
|
||||||
|
|
||||||
|
PIN_TAN_924("924"),
|
||||||
|
|
||||||
|
PIN_TAN_925("925"),
|
||||||
|
|
||||||
|
PIN_TAN_926("926"),
|
||||||
|
|
||||||
|
PIN_TAN_927("927"),
|
||||||
|
|
||||||
|
PIN_TAN_928("928"),
|
||||||
|
|
||||||
|
PIN_TAN_929("929"),
|
||||||
|
|
||||||
|
PIN_TAN_930("930"),
|
||||||
|
|
||||||
|
PIN_TAN_931("931"),
|
||||||
|
|
||||||
|
PIN_TAN_932("932"),
|
||||||
|
|
||||||
|
PIN_TAN_933("933"),
|
||||||
|
|
||||||
|
PIN_TAN_934("934"),
|
||||||
|
|
||||||
|
PIN_TAN_935("935"),
|
||||||
|
|
||||||
|
PIN_TAN_936("936"),
|
||||||
|
|
||||||
|
PIN_TAN_937("937"),
|
||||||
|
|
||||||
|
PIN_TAN_938("938"),
|
||||||
|
|
||||||
|
PIN_TAN_939("939"),
|
||||||
|
|
||||||
|
PIN_TAN_940("940"),
|
||||||
|
|
||||||
|
PIN_TAN_941("941"),
|
||||||
|
|
||||||
|
PIN_TAN_942("942"),
|
||||||
|
|
||||||
|
PIN_TAN_943("943"),
|
||||||
|
|
||||||
|
PIN_TAN_944("944"),
|
||||||
|
|
||||||
|
PIN_TAN_945("945"),
|
||||||
|
|
||||||
|
PIN_TAN_946("946"),
|
||||||
|
|
||||||
|
PIN_TAN_947("947"),
|
||||||
|
|
||||||
|
PIN_TAN_948("948"),
|
||||||
|
|
||||||
|
PIN_TAN_949("949"),
|
||||||
|
|
||||||
|
PIN_TAN_950("950"),
|
||||||
|
|
||||||
|
PIN_TAN_951("951"),
|
||||||
|
|
||||||
|
PIN_TAN_952("952"),
|
||||||
|
|
||||||
|
PIN_TAN_953("953"),
|
||||||
|
|
||||||
|
PIN_TAN_954("954"),
|
||||||
|
|
||||||
|
PIN_TAN_955("955"),
|
||||||
|
|
||||||
|
PIN_TAN_956("956"),
|
||||||
|
|
||||||
|
PIN_TAN_957("957"),
|
||||||
|
|
||||||
|
PIN_TAN_958("958"),
|
||||||
|
|
||||||
|
PIN_TAN_959("959"),
|
||||||
|
|
||||||
|
PIN_TAN_960("960"),
|
||||||
|
|
||||||
|
PIN_TAN_961("961"),
|
||||||
|
|
||||||
|
PIN_TAN_962("962"),
|
||||||
|
|
||||||
|
PIN_TAN_963("963"),
|
||||||
|
|
||||||
|
PIN_TAN_964("964"),
|
||||||
|
|
||||||
|
PIN_TAN_965("965"),
|
||||||
|
|
||||||
|
PIN_TAN_966("966"),
|
||||||
|
|
||||||
|
PIN_TAN_967("967"),
|
||||||
|
|
||||||
|
PIN_TAN_968("968"),
|
||||||
|
|
||||||
|
PIN_TAN_969("969"),
|
||||||
|
|
||||||
|
PIN_TAN_970("970"),
|
||||||
|
|
||||||
|
PIN_TAN_971("971"),
|
||||||
|
|
||||||
|
PIN_TAN_972("972"),
|
||||||
|
|
||||||
|
PIN_TAN_973("973"),
|
||||||
|
|
||||||
|
PIN_TAN_974("974"),
|
||||||
|
|
||||||
|
PIN_TAN_975("975"),
|
||||||
|
|
||||||
|
PIN_TAN_976("976"),
|
||||||
|
|
||||||
|
PIN_TAN_977("977"),
|
||||||
|
|
||||||
|
PIN_TAN_978("978"),
|
||||||
|
|
||||||
|
PIN_TAN_979("979"),
|
||||||
|
|
||||||
|
PIN_TAN_980("980"),
|
||||||
|
|
||||||
|
PIN_TAN_981("981"),
|
||||||
|
|
||||||
|
PIN_TAN_982("982"),
|
||||||
|
|
||||||
|
PIN_TAN_983("983"),
|
||||||
|
|
||||||
|
PIN_TAN_984("984"),
|
||||||
|
|
||||||
|
PIN_TAN_985("985"),
|
||||||
|
|
||||||
|
PIN_TAN_986("986"),
|
||||||
|
|
||||||
|
PIN_TAN_987("987"),
|
||||||
|
|
||||||
|
PIN_TAN_988("988"),
|
||||||
|
|
||||||
|
PIN_TAN_989("989"),
|
||||||
|
|
||||||
|
PIN_TAN_990("990"),
|
||||||
|
|
||||||
|
PIN_TAN_991("991"),
|
||||||
|
|
||||||
|
PIN_TAN_992("992"),
|
||||||
|
|
||||||
|
PIN_TAN_993("993"),
|
||||||
|
|
||||||
|
PIN_TAN_994("994"),
|
||||||
|
|
||||||
|
PIN_TAN_995("995"),
|
||||||
|
|
||||||
|
PIN_TAN_996("996"),
|
||||||
|
|
||||||
|
PIN_TAN_997("997"),
|
||||||
|
|
||||||
|
PIN_TAN_Einschritt_Verfahren("999")
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.allCodes
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abhängig von Sicherheitsprofil und Schlüsseltyp und HBCI-Version ist folgender Wert einzustellen:
|
||||||
|
*
|
||||||
|
* | Sicherheitsprofil | Schlüsseltyp | ab FinTS V3.0 |
|
||||||
|
* | RAH-7 | S | 2 |
|
||||||
|
* | RAH-7 | D | 1 |
|
||||||
|
* | RAH-9 | S | 2 |
|
||||||
|
* | RAH-10 | S | 2 |
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.4 Segment „Signaturkopf“, S. 58):
|
||||||
|
*
|
||||||
|
* Sicherheitsfunktion, kodiert
|
||||||
|
* Beim Ein-Schritt-Verfahren ist der Wert „999“ einzustellen, beim Zwei-Schritt-Verfahren der entsprechende
|
||||||
|
* in der BPD mitgeteilte Wert für das konkrete Verfahren „900“ bis „997“ (vgl. Kapitel B.8.2).
|
||||||
|
*/
|
||||||
|
open class SicherheitsfunktionKodiert(securityFunction: Sicherheitsfunktion)
|
||||||
|
: Code(securityFunction.code, AllowedValues, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val AllowedValues = allCodes<Sicherheitsfunktion>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Referenzinformation, mit der die Verbindung zwischen Signaturkopf und dazu gehörigem
|
||||||
|
* Signaturabschluss hergestellt werden kann. Die Sicherheitskontrollreferenz im
|
||||||
|
* Signaturkopf muss mit der entsprechenden Information im Signaturabschluss übereinstimmen.
|
||||||
|
*/
|
||||||
|
open class Sicherheitskontrollreferenz(reference: String) : AlphanumerischesDatenelement(reference, Existenzstatus.Mandatory, 14)
|
|
@ -0,0 +1,18 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sicherheitsrelevante Nachrichtenidentifikation (Signatur-ID), welche zur Verhinderung der
|
||||||
|
* Doppeleinreichung, respektive Garantie der Nachrichtensequenzintegrität eingesetzt werden kann.
|
||||||
|
*
|
||||||
|
* Bei chipkartenbasierten Verfahren ist der Sequenzzähler der Chipkarte einzustellen. Dies ist
|
||||||
|
* bei Typ-1 Karten der Wert „EF_SEQ“ in der Application DF_BANKING und bei SECCOS Banken-
|
||||||
|
* Signaturkarten der Wert „usage counter“ der beiden Signierschlüssel SK.CH.DS und SK.CH.AUT.
|
||||||
|
*
|
||||||
|
* Bei softwarebasierten Verfahren wird die Sicherheitsreferenznummer auf Basis des DE
|
||||||
|
* Kundensystem-ID und des DE Benutzerkennung der DEG Schlüsselnamen verwaltet.
|
||||||
|
*/
|
||||||
|
open class Sicherheitsreferenznummer(number: Int) : NumerischesDatenelement(number, 16, Existenzstatus.Mandatory)
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||||
|
|
||||||
|
|
||||||
|
enum class Sicherheitsverfahren(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
|
RSA_AES_Hybridverfahren("RAH"),
|
||||||
|
|
||||||
|
PIN_TAN_Verfahren("PIN")
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.allCodes
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code des unterstützten Signatur- bzw. Verschlüsselungsalgorithmus.
|
||||||
|
*
|
||||||
|
* Weitere Informationen zu den Verfahren sind Kapitel B.1 zu entnehmen.
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* - RAH: RSA-AES-Hybridverfahren
|
||||||
|
* - PIN: PIN/TAN-Verfahren
|
||||||
|
*/
|
||||||
|
open class SicherheitsverfahrenCode(method: Sicherheitsverfahren) : Code(method.code, AllowedValues, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val AllowedValues = allCodes<Sicherheitsverfahren>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||||
|
|
||||||
|
|
||||||
|
enum class Signaturalgorithmus(override val code: String) : ICodeEnum {
|
||||||
|
|
||||||
|
NichtZugelassen("1"),
|
||||||
|
|
||||||
|
RSA_Algorithmus("10")
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.allCodes
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kodierte Information über den Signaturalgorithmus.
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* 1: nicht zugelassen
|
||||||
|
* 10: RSA-Algorithmus (bei RAH)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.6 DEG „Signaturalgorithmus“, S. 58):
|
||||||
|
*
|
||||||
|
* Signaturalgorithmus, kodiert
|
||||||
|
* FinTS-Füllwert, z. B. „10“
|
||||||
|
*/
|
||||||
|
open class SignaturalgorithmusKodiert(algorithm: Signaturalgorithmus)
|
||||||
|
: Code(algorithm.code, AllowedValues, Existenzstatus.Mandatory) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val AllowedValues = allCodes<Signaturalgorithmus>()
|
||||||
|
|
||||||
|
val FinTsMockValue = Signaturalgorithmus.RSA_Algorithmus
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
|
||||||
|
enum class VersionDesSicherheitsverfahrens(val methodNumber: Int) {
|
||||||
|
|
||||||
|
PIN_Ein_Schritt(1),
|
||||||
|
|
||||||
|
PIN_Zwei_Schritt(2),
|
||||||
|
|
||||||
|
RAH_7(7),
|
||||||
|
|
||||||
|
RAH_9(9),
|
||||||
|
|
||||||
|
RAH_10(10)
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version des unterstützten Sicherheitsverfahrens (s. „Sicherheitsverfahren, Code“).
|
||||||
|
*
|
||||||
|
* In Kombination mit dem Sicherheitsverfahren RAH sind die folgenden Versionen gültig:
|
||||||
|
*
|
||||||
|
* | Version | Signaturverfahren | Schlüssellänge (bit) | Hashverfahren | Schlüsselart* |
|
||||||
|
* | 7 | PKCS#1 PSS | ..2048 | SHA-256 | D, S, V |
|
||||||
|
* | 9 | PKCS#1 PSS | ..2048 | SHA-256 | S, V |
|
||||||
|
* | 10 | PKCS#1 PSS | ..2048 | SHA-256 | S, V |
|
||||||
|
*
|
||||||
|
* *s. Element „Schlüsselart“
|
||||||
|
*
|
||||||
|
* Andere als die genannten Profile sind nicht zulässig.
|
||||||
|
*
|
||||||
|
* Um Multibankfähigkeit zu gewährleisten, ist die Unterstützung des Verfahrens RAH-9 kundenund
|
||||||
|
* kreditisinstitutsseitig verpflichtend.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.1 DEG „Sicherheitsprofil“, S. 58):
|
||||||
|
*
|
||||||
|
* Version des Sicherheitsverfahrens
|
||||||
|
* - „1“ : bei allen Nachrichten, wenn Dialog im Einschritt-Verfahren
|
||||||
|
* - „2“ : bei allen Nachrichten, wenn Dialog im Zwei-Schritt-Verfahren
|
||||||
|
|
||||||
|
*/
|
||||||
|
open class VersionDesSicherheitsverfahrensDatenelement(version: VersionDesSicherheitsverfahrens)
|
||||||
|
: NumerischesDatenelement(version.methodNumber, 3, Existenzstatus.Mandatory)
|
|
@ -0,0 +1,15 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Code
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kodierte Information über die Verwendung des Hashalgorithmus.
|
||||||
|
*
|
||||||
|
* Im Zusammenhang mit Hash-Funktionen ist derzeit nur folgender Wert möglich:
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* 1: Owner Hashing (OHA)
|
||||||
|
*/
|
||||||
|
open class VerwendungDesHashalgorithmusKodiert: Code("1", listOf("1"), Existenzstatus.Mandatory)
|
|
@ -0,0 +1,15 @@
|
||||||
|
package net.dankito.fints.messages.datenelemente.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kodierte Information über die Verwendung des Signaturalgorithmus.
|
||||||
|
*
|
||||||
|
* Im Zusammenhang mit Signaturbildung ist derzeit nur folgender Wert möglich:
|
||||||
|
*
|
||||||
|
* Codierung:
|
||||||
|
* 6: Owner Signing (OSG)
|
||||||
|
*/
|
||||||
|
open class VerwendungDesSignaturalgorithmusKodiert : AlphanumerischesDatenelement("6", Existenzstatus.Mandatory, 3)
|
|
@ -9,8 +9,8 @@ import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
||||||
|
|
||||||
open class Segmentkopf @JvmOverloads constructor(
|
open class Segmentkopf @JvmOverloads constructor(
|
||||||
identifier: String,
|
identifier: String,
|
||||||
segmentNumber: Int,
|
|
||||||
segmentVersion: Int,
|
segmentVersion: Int,
|
||||||
|
segmentNumber: Int = 0,
|
||||||
bezugssegment: Int? = null
|
bezugssegment: Int? = null
|
||||||
|
|
||||||
) : Datenelementgruppe(listOf(
|
) : Datenelementgruppe(listOf(
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package net.dankito.fints.messages.datenelementgruppen.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.PinOrTan
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bei nicht-schlüsselbasierten Sicherheitsverfahren kann der Benutzer hier Angaben
|
||||||
|
* zur Authentisierung machen. Ob das Feld verpflichtend ist, ist vom jeweiligen
|
||||||
|
* Sicherheitsverfahren abhängig.
|
||||||
|
*
|
||||||
|
* Format: s. Spezifikation „Sicherheitsverfahren PIN/TAN“
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.7 Segment „Signaturabschluss“, S. 59)
|
||||||
|
*
|
||||||
|
* Es ist der Signaturabschluss gemäß [HBCI] ab Segmentversion 2 zu verwenden.
|
||||||
|
*
|
||||||
|
* Validierungsresultat
|
||||||
|
* Dieses Feld darf nicht belegt werden.
|
||||||
|
*
|
||||||
|
* Benutzerdefinierte Signatur
|
||||||
|
* Hier werden bei Verwendung des PIN/TAN-Verfahrens PIN und TAN eingestellt. Bei
|
||||||
|
* Verwendung des Zwei-Schritt-Verfahrens mit Prozessvariante 2 darf eine TAN
|
||||||
|
* ausschließlich über den Geschäftsvorfall HKTAN eingereicht werden, wobei pro
|
||||||
|
* HKTAN nur die Verarbeitung einer einzelnen TAN zulässig ist. Ansonsten darf die
|
||||||
|
* DE „TAN“ im Signaturabschluss nicht belegt werden; ihr Inhalt wird in diesem Fall
|
||||||
|
* ignoriert und die TAN vom Institut entwertet. Gleiches gilt bei der nicht
|
||||||
|
* zulässigen Übermittlung von mehreren TANs mit HKTAN. Bei der Verwendung im Rahmen
|
||||||
|
* des Sicherheitsverfahrens HBCI darf die DEG nicht belegt werden. Ihr Inhalt wird
|
||||||
|
* in diesem Fall ignoriert.
|
||||||
|
*/
|
||||||
|
open class BenutzerdefinierteSignatur(pinOrTan: String)
|
||||||
|
: Datenelementgruppe(listOf(
|
||||||
|
PinOrTan(pinOrTan)
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -0,0 +1,25 @@
|
||||||
|
package net.dankito.fints.messages.datenelementgruppen.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.BezeichnerFuerHashalgorithmusparameter
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Hashalgorithmus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.HashalgorithmusKodiert
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.VerwendungDesHashalgorithmusKodiert
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Angaben zu einem kryptographischen Algorithmus, seinen Operationsmodus, sowie dessen Einsatz.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.5 DEG „Hashalgorithmus“, S. 58):
|
||||||
|
*
|
||||||
|
* Wert des Hashalgorithmusparameters
|
||||||
|
* Dieses Feld darf nicht belegt werden.
|
||||||
|
*/
|
||||||
|
open class HashalgorithmusDatenelementgruppe
|
||||||
|
: Datenelementgruppe(listOf(
|
||||||
|
VerwendungDesHashalgorithmusKodiert(),
|
||||||
|
HashalgorithmusKodiert(Hashalgorithmus.Gegenseitig_vereinbart), // allowed: 3, 4, 5, 6
|
||||||
|
BezeichnerFuerHashalgorithmusparameter()
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -0,0 +1,46 @@
|
||||||
|
package net.dankito.fints.messages.datenelementgruppen.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.Benutzerkennung
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Schluesselart
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.SchluesselartDatenelement
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Schluesselnummer
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Schluesselversion
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.implementierte.Kreditinstitutskennung
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verwendeter Schlüsselname in strukturierter Form. Mit dieser Information kann die Referenz
|
||||||
|
* auf einen Schlüssel hergestellt werden.
|
||||||
|
*
|
||||||
|
* Dabei enthält das DE „Benutzerkennung“ bei Schlüsseln des Kunden die Benutzerkennung, mit
|
||||||
|
* der der Kunde eindeutig identifiziert wird. Bei Schlüsseln des Kreditinstituts ist dagegen
|
||||||
|
* eine beliebige Kennung einzustellen, die dazu dient, den Kreditinstitutsschlüssel eindeutig
|
||||||
|
* zu identifizieren. Diese Kennung darf weder einer anderen gültigen Benutzerkennung des
|
||||||
|
* Kreditinstituts noch der Benutzerkennung für den anonymen Zugang entsprechen.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.2 DEG „Schlüsselname“, S. 58):
|
||||||
|
*
|
||||||
|
* Schlüsselnummer
|
||||||
|
* FinTS-Füllwert, z. B. „0“
|
||||||
|
*
|
||||||
|
* Schlüsselversion
|
||||||
|
* FinTS-Füllwert, z. B. „0“
|
||||||
|
*/
|
||||||
|
open class Schluesselname(
|
||||||
|
bankCountryCode: Int,
|
||||||
|
bankCode: String,
|
||||||
|
userIdentification: String,
|
||||||
|
key: Schluesselart,
|
||||||
|
keyNumber: Int,
|
||||||
|
keyVersion: Int
|
||||||
|
)
|
||||||
|
: Datenelementgruppe(listOf(
|
||||||
|
Kreditinstitutskennung(bankCountryCode, bankCode),
|
||||||
|
Benutzerkennung(userIdentification),
|
||||||
|
SchluesselartDatenelement(key),
|
||||||
|
Schluesselnummer(keyNumber),
|
||||||
|
Schluesselversion(keyVersion)
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -0,0 +1,16 @@
|
||||||
|
package net.dankito.fints.messages.datenelementgruppen.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Datum
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Uhrzeit
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.DatumUndZeitbezeichner
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.DatumUndZeitbezeichnerKodiert
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
||||||
|
|
||||||
|
|
||||||
|
open class SicherheitsdatumUndUhrzeit(date: Int, time: Int)
|
||||||
|
: Datenelementgruppe(listOf(
|
||||||
|
DatumUndZeitbezeichnerKodiert(DatumUndZeitbezeichner.Sicherheitszeitstempel), // Als Bezeichner wird „1“ eingestellt, da es sich um einen Sicherheitszeitstempel handelt.
|
||||||
|
Datum(date, Existenzstatus.Optional),
|
||||||
|
Uhrzeit(time, Existenzstatus.Optional)
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -0,0 +1,32 @@
|
||||||
|
package net.dankito.fints.messages.datenelementgruppen.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.NotAllowedDatenelement
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.BezeichnerFuerSicherheitspartei
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.IdentifizierungDerPartei
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifikation der im Sicherheitsprozess involvierten Parteien. Dient zur Übermittlung
|
||||||
|
* der CID bei kartenbasierten Sicherheitsverfahren bzw. der Kundensystem-ID bei
|
||||||
|
* softwarebasierten Verfahren (z. B. Speicherung der Schlüssel in einer Schlüsseldatei).
|
||||||
|
*
|
||||||
|
* Wenn eine Synchronisierung der Kundensystem-ID durchgeführt wird, ist als Identifizierung der Partei ‚0’ einzustellen.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.3 DEG „Sicherheitsidentifikation, Details“, S. 58):
|
||||||
|
*
|
||||||
|
* CID
|
||||||
|
* Dieses Feld darf nicht belegt werden.
|
||||||
|
*
|
||||||
|
* Identifizierung der Partei
|
||||||
|
* Dieses Feld muss eine gültige, zuvor vom Banksystem angeforderte Kundensystem-ID enthalten
|
||||||
|
* (analog zu RAH-/RDH-Verfahren). Dies gilt auch für Zweit- und Drittsignaturen.
|
||||||
|
*/
|
||||||
|
open class SicherheitsidentifikationDetails(partyIdentification: String)
|
||||||
|
: Datenelementgruppe(listOf(
|
||||||
|
BezeichnerFuerSicherheitspartei(),
|
||||||
|
NotAllowedDatenelement(),
|
||||||
|
IdentifizierungDerPartei(partyIdentification)
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -0,0 +1,33 @@
|
||||||
|
package net.dankito.fints.messages.datenelementgruppen.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Sicherheitsverfahren
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.SicherheitsverfahrenCode
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrensDatenelement
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verfahren zur Absicherung der Transaktionen, das zwischen Kunde und Kreditinstitut
|
||||||
|
* vereinbar wurde. Das Sicherheitsprofil wird anhand der Kombination der beiden Elemente
|
||||||
|
* „Sicherheitsverfahren“ und „Version“ bestimmt (z. B. RDH-9). Für das Sicherheitsverfahren
|
||||||
|
* PINTAN ist als Code der Wert PIN und als Version der Wert 1 einzustellen.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.1 DEG „Sicherheitsprofil“, S. 58):
|
||||||
|
*
|
||||||
|
* Sicherheitsverfahren, Code
|
||||||
|
* - „PIN“ : bei allen Nachrichten
|
||||||
|
*
|
||||||
|
* Version des Sicherheitsverfahrens
|
||||||
|
* - „1“ : bei allen Nachrichten, wenn Dialog im Einschritt-Verfahren
|
||||||
|
* - „2“ : bei allen Nachrichten, wenn Dialog im Zwei-Schritt-Verfahren
|
||||||
|
*/
|
||||||
|
open class Sicherheitsprofil(
|
||||||
|
method: Sicherheitsverfahren,
|
||||||
|
version: VersionDesSicherheitsverfahrens
|
||||||
|
) : Datenelementgruppe(listOf(
|
||||||
|
SicherheitsverfahrenCode(method),
|
||||||
|
VersionDesSicherheitsverfahrensDatenelement(version)
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -0,0 +1,26 @@
|
||||||
|
package net.dankito.fints.messages.datenelementgruppen.implementierte.signatur
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.*
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Angaben zum kryptographischen Algorithmus, zu seinem Operationsmodus,
|
||||||
|
* so wie zu dessen Einsatz, in diesem Fall für die Signaturbildung über RAH.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.6 DEG „Signaturalgorithmus“, S. 58):
|
||||||
|
*
|
||||||
|
* Signaturalgorithmus, kodiert
|
||||||
|
* FinTS-Füllwert, z. B. „10“
|
||||||
|
*
|
||||||
|
* Operationsmodus, kodiert
|
||||||
|
* FinTS-Füllwert, z. B. „16“
|
||||||
|
*/
|
||||||
|
open class SignaturalgorithmusDatenelementgruppe (algorithm: Signaturalgorithmus, mode: Operationsmodus)
|
||||||
|
: Datenelementgruppe(listOf(
|
||||||
|
VerwendungDesSignaturalgorithmusKodiert(),
|
||||||
|
SignaturalgorithmusKodiert(algorithm),
|
||||||
|
OperationsmodusKodiert(mode)
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -1,6 +1,7 @@
|
||||||
package net.dankito.fints.messages.nachrichten.implementierte
|
package net.dankito.fints.messages.nachrichten.implementierte
|
||||||
|
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
|
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.Nachrichtennummer.Companion.FirstMessageNumber
|
import net.dankito.fints.messages.datenelemente.implementierte.Nachrichtennummer.Companion.FirstMessageNumber
|
||||||
import net.dankito.fints.messages.nachrichten.Nachricht
|
import net.dankito.fints.messages.nachrichten.Nachricht
|
||||||
import net.dankito.fints.messages.segmente.implementierte.IdentifikationsSegment
|
import net.dankito.fints.messages.segmente.implementierte.IdentifikationsSegment
|
||||||
|
@ -23,7 +24,7 @@ open class Dialoginitialisierung(
|
||||||
)
|
)
|
||||||
: Nachricht(listOf(
|
: Nachricht(listOf(
|
||||||
Nachrichtenkopf(1, messageSize, "0", FirstMessageNumber),
|
Nachrichtenkopf(1, messageSize, "0", FirstMessageNumber),
|
||||||
IdentifikationsSegment(2, bankCountryCode, bankCode, customerId, customerSystemId),
|
IdentifikationsSegment(2, bankCountryCode, bankCode, customerId, customerSystemId, KundensystemStatusWerte.NichtBenoetigt), // TODO: KundensystemStatusWerte
|
||||||
Verarbeitungsvorbereitung(3, bpdVersion, updVersion, language, productName, productVersion),
|
Verarbeitungsvorbereitung(3, bpdVersion, updVersion, language, productName, productVersion),
|
||||||
Nachrichtenabschluss(4, FirstMessageNumber)
|
Nachrichtenabschluss(4, FirstMessageNumber)
|
||||||
))
|
))
|
|
@ -1,9 +1,10 @@
|
||||||
package net.dankito.fints.messages.segmente.implementierte
|
package net.dankito.fints.messages.segmente.implementierte
|
||||||
|
|
||||||
import net.dankito.fints.messages.Existenzstatus
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.FinTsKundensystemStatus
|
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.KundenID
|
import net.dankito.fints.messages.datenelemente.implementierte.KundenID
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemID
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemID
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
|
||||||
import net.dankito.fints.messages.datenelementgruppen.implementierte.Kreditinstitutskennung
|
import net.dankito.fints.messages.datenelementgruppen.implementierte.Kreditinstitutskennung
|
||||||
import net.dankito.fints.messages.datenelementgruppen.implementierte.Segmentkopf
|
import net.dankito.fints.messages.datenelementgruppen.implementierte.Segmentkopf
|
||||||
import net.dankito.fints.messages.segmente.Segment
|
import net.dankito.fints.messages.segmente.Segment
|
||||||
|
@ -14,12 +15,13 @@ open class IdentifikationsSegment(
|
||||||
bankCountryCode: Int,
|
bankCountryCode: Int,
|
||||||
bankCode: String,
|
bankCode: String,
|
||||||
customerId: String,
|
customerId: String,
|
||||||
customerSystemId: String
|
customerSystemId: String,
|
||||||
|
status: KundensystemStatusWerte
|
||||||
|
|
||||||
) : Segment(listOf(
|
) : Segment(listOf(
|
||||||
Segmentkopf("HKIDN", segmentNumber, 2),
|
Segmentkopf("HKIDN", 2, segmentNumber),
|
||||||
Kreditinstitutskennung(bankCountryCode, bankCode),
|
Kreditinstitutskennung(bankCountryCode, bankCode),
|
||||||
KundenID(customerId),
|
KundenID(customerId),
|
||||||
KundensystemID(customerSystemId),
|
KundensystemID(customerSystemId),
|
||||||
FinTsKundensystemStatus()
|
KundensystemStatus(status, Existenzstatus.Mandatory)
|
||||||
), Existenzstatus.Mandatory)
|
), Existenzstatus.Mandatory)
|
|
@ -9,10 +9,10 @@ import net.dankito.fints.messages.segmente.Segment
|
||||||
/**
|
/**
|
||||||
* Dieses Segment beendet alle Kunden- und Kreditinstitutsnachrichten.
|
* Dieses Segment beendet alle Kunden- und Kreditinstitutsnachrichten.
|
||||||
*/
|
*/
|
||||||
class Nachrichtenabschluss(
|
open class Nachrichtenabschluss(
|
||||||
segmentNumber: Int,
|
segmentNumber: Int,
|
||||||
messageNumber: Int
|
messageNumber: Int
|
||||||
) : Segment(listOf(
|
) : Segment(listOf(
|
||||||
Segmentkopf("HNHBS", segmentNumber, 1),
|
Segmentkopf("HNHBS", 1, segmentNumber),
|
||||||
Nachrichtennummer(messageNumber)
|
Nachrichtennummer(messageNumber)
|
||||||
), Existenzstatus.Mandatory)
|
), Existenzstatus.Mandatory)
|
|
@ -13,7 +13,7 @@ open class Nachrichtenkopf(
|
||||||
messageNumber: Int
|
messageNumber: Int
|
||||||
|
|
||||||
) : Segment(listOf(
|
) : Segment(listOf(
|
||||||
Segmentkopf("HNHBK", segmentNumber, 3),
|
Segmentkopf("HNHBK", 3, segmentNumber),
|
||||||
Nachrichtengroesse(messageSize),
|
Nachrichtengroesse(messageSize),
|
||||||
HbciVersionDatenelement(HbciVersion.FinTs_3_0_0),
|
HbciVersionDatenelement(HbciVersion.FinTs_3_0_0),
|
||||||
DialogId(dialogId),
|
DialogId(dialogId),
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package net.dankito.fints.messages.segmente.implementierte
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.*
|
||||||
|
|
||||||
|
|
||||||
|
class PinTanSignaturkopf(
|
||||||
|
segmentNumber: Int,
|
||||||
|
securityFunction: Sicherheitsfunktion,
|
||||||
|
securityControlReference: String,
|
||||||
|
/**
|
||||||
|
* Wenn eine Synchronisierung der Kundensystem-ID durchgeführt wird, ist als Identifizierung der Partei ‚0’ einzustellen.
|
||||||
|
*/
|
||||||
|
partyIdentification: String,
|
||||||
|
date: Int,
|
||||||
|
time: Int,
|
||||||
|
bankCountryCode: Int,
|
||||||
|
bankCode: String,
|
||||||
|
userIdentification: String
|
||||||
|
|
||||||
|
) : Signaturkopf(
|
||||||
|
segmentNumber,
|
||||||
|
Sicherheitsverfahren.PIN_TAN_Verfahren,
|
||||||
|
VersionDesSicherheitsverfahrens.PIN_Zwei_Schritt,
|
||||||
|
securityFunction,
|
||||||
|
securityControlReference,
|
||||||
|
partyIdentification,
|
||||||
|
date,
|
||||||
|
time,
|
||||||
|
SignaturalgorithmusKodiert.FinTsMockValue,
|
||||||
|
OperationsmodusKodiert.FinTsMockValue,
|
||||||
|
bankCountryCode,
|
||||||
|
bankCode,
|
||||||
|
userIdentification,
|
||||||
|
Schluesselnummer.FinTsMockValue,
|
||||||
|
Schluesselversion.FinTsMockValue
|
||||||
|
)
|
|
@ -0,0 +1,25 @@
|
||||||
|
package net.dankito.fints.messages.segmente.implementierte
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.NotAllowedDatenelement
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Sicherheitskontrollreferenz
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.implementierte.Segmentkopf
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.implementierte.signatur.BenutzerdefinierteSignatur
|
||||||
|
import net.dankito.fints.messages.segmente.Segment
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Signaturabschluss stellt die Verbindung mit dem dazugehörigen Signaturkopf
|
||||||
|
* her und enthält als "Validierungsresultat" die elektronische Signatur.
|
||||||
|
*/
|
||||||
|
open class Signaturabschluss(
|
||||||
|
segmentNumber: Int,
|
||||||
|
securityControlReference: String,
|
||||||
|
pinOrTan: String
|
||||||
|
)
|
||||||
|
: Segment(listOf(
|
||||||
|
Segmentkopf("HNSHA", 2, segmentNumber),
|
||||||
|
Sicherheitskontrollreferenz(securityControlReference), // has to be the same as in Signaturkopf
|
||||||
|
NotAllowedDatenelement(), // only used for HBCI, not allowed for PIN/TAN
|
||||||
|
BenutzerdefinierteSignatur(pinOrTan)
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -0,0 +1,56 @@
|
||||||
|
package net.dankito.fints.messages.segmente.implementierte
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.Existenzstatus
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.*
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.implementierte.Segmentkopf
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.implementierte.signatur.*
|
||||||
|
import net.dankito.fints.messages.segmente.Segment
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Signaturkopf enthält Informationen über den damit verbundenen Sicherheitsservice, sowie über den Absender.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Abweichende Belegung für PIN/TAN Verfahren (Dokument Sicherheitsverfahren PIN/TAN, B.9.4 Segment „Signaturkopf“, S. 58):
|
||||||
|
*
|
||||||
|
* Sicherheitsfunktion, kodiert
|
||||||
|
* Beim Ein-Schritt-Verfahren ist der Wert „999“ einzustellen, beim Zwei-Schritt-Verfahren der entsprechende
|
||||||
|
* in der BPD mitgeteilte Wert für das konkrete Verfahren „900“ bis „997“ (vgl. Kapitel B.8.2).
|
||||||
|
*
|
||||||
|
* Zertifikat
|
||||||
|
* Dieses Feld darf nicht belegt werden.
|
||||||
|
*/
|
||||||
|
open class Signaturkopf(
|
||||||
|
segmentNumber: Int,
|
||||||
|
method: Sicherheitsverfahren,
|
||||||
|
version: VersionDesSicherheitsverfahrens,
|
||||||
|
securityFunction: Sicherheitsfunktion,
|
||||||
|
securityControlReference: String,
|
||||||
|
/**
|
||||||
|
* Wenn eine Synchronisierung der Kundensystem-ID durchgeführt wird, ist als Identifizierung der Partei ‚0’ einzustellen.
|
||||||
|
*/
|
||||||
|
partyIdentification: String,
|
||||||
|
date: Int,
|
||||||
|
time: Int,
|
||||||
|
algorithm: Signaturalgorithmus,
|
||||||
|
mode: Operationsmodus,
|
||||||
|
bankCountryCode: Int,
|
||||||
|
bankCode: String,
|
||||||
|
userIdentification: String,
|
||||||
|
keyNumber: Int,
|
||||||
|
keyVersion: Int
|
||||||
|
|
||||||
|
) : Segment(listOf(
|
||||||
|
Segmentkopf("HNSHK", 4, segmentNumber), // allowed
|
||||||
|
Sicherheitsprofil(method, version), // allowed: method: RAH, PIN;
|
||||||
|
SicherheitsfunktionKodiert(securityFunction), // allowed: 1, 2
|
||||||
|
Sicherheitskontrollreferenz(securityControlReference), // allowed: <>0
|
||||||
|
BereichDerSicherheitsapplikationKodiert(BereichDerSicherheitsapplikation.SignaturkopfUndHBCINutzdaten), // allowed: 1 ?
|
||||||
|
RolleDesSicherheitslieferantenKodiert(), // allowed: 1
|
||||||
|
SicherheitsidentifikationDetails(partyIdentification),
|
||||||
|
Sicherheitsreferenznummer(1), // TODO: is this always 1?
|
||||||
|
SicherheitsdatumUndUhrzeit(date, time),
|
||||||
|
HashalgorithmusDatenelementgruppe(),
|
||||||
|
SignaturalgorithmusDatenelementgruppe(algorithm, mode),
|
||||||
|
Schluesselname(bankCountryCode, bankCode, userIdentification, Schluesselart.Signierschluessel, keyNumber, keyVersion)
|
||||||
|
), Existenzstatus.Mandatory)
|
|
@ -6,7 +6,7 @@ import net.dankito.fints.messages.datenelementgruppen.implementierte.Segmentkopf
|
||||||
import net.dankito.fints.messages.segmente.Segment
|
import net.dankito.fints.messages.segmente.Segment
|
||||||
|
|
||||||
|
|
||||||
class Verarbeitungsvorbereitung(
|
open class Verarbeitungsvorbereitung(
|
||||||
segmentNumber: Int,
|
segmentNumber: Int,
|
||||||
bpdVersion: Int,
|
bpdVersion: Int,
|
||||||
updVersion: Int,
|
updVersion: Int,
|
||||||
|
@ -14,7 +14,7 @@ class Verarbeitungsvorbereitung(
|
||||||
productName: String,
|
productName: String,
|
||||||
productVersion: String
|
productVersion: String
|
||||||
) : Segment(listOf(
|
) : Segment(listOf(
|
||||||
Segmentkopf("HKVVB", segmentNumber, 3),
|
Segmentkopf("HKVVB", 3, segmentNumber),
|
||||||
BPDVersion(bpdVersion, Existenzstatus.Mandatory),
|
BPDVersion(bpdVersion, Existenzstatus.Mandatory),
|
||||||
UPDVersion(updVersion, Existenzstatus.Mandatory),
|
UPDVersion(updVersion, Existenzstatus.Mandatory),
|
||||||
DialogspracheDatenelement(language, Existenzstatus.Mandatory),
|
DialogspracheDatenelement(language, Existenzstatus.Mandatory),
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package net.dankito.fints.util
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Datum
|
||||||
|
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Uhrzeit
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
open class FinTsUtils {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val HbciDateFormat = SimpleDateFormat(Datum.HbciDateFormat)
|
||||||
|
|
||||||
|
val HbciTimeFormat = SimpleDateFormat(Uhrzeit.HbciTimeFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun formatDateToday(): String {
|
||||||
|
return formatDate(Date())
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun formatDate(date: Date): String {
|
||||||
|
return HbciDateFormat.format(date)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun formatDateTodayAsInt(): Int {
|
||||||
|
return convertToInt(formatDateToday())
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun formatDateAsInt(date: Date): Int {
|
||||||
|
return convertToInt(formatDate(date))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun formatTimeNow(): String {
|
||||||
|
return formatTime(Date())
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun formatTime(time: Date): String {
|
||||||
|
return HbciTimeFormat.format(time)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun formatTimeNowAsInt(): Int {
|
||||||
|
return convertToInt(formatTimeNow())
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun formatTimeAsInt(time: Date): Int {
|
||||||
|
return convertToInt(formatTime(time))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected fun convertToInt(string: String): Int {
|
||||||
|
return string.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package net.dankito.fints.messages.segmente.implementierte
|
||||||
|
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.KundenID
|
import net.dankito.fints.messages.datenelemente.implementierte.KundenID
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemID
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemID
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.Laenderkennzeichen
|
import net.dankito.fints.messages.datenelemente.implementierte.Laenderkennzeichen
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
@ -13,7 +14,7 @@ class IdentifikationsSegmentTest {
|
||||||
fun format() {
|
fun format() {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
val underTest = IdentifikationsSegment(2, Laenderkennzeichen.Germany, "12345678", KundenID.Anonymous, KundensystemID.Anonymous)
|
val underTest = IdentifikationsSegment(2, Laenderkennzeichen.Germany, "12345678", KundenID.Anonymous, KundensystemID.Anonymous, KundensystemStatusWerte.NichtBenoetigt)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
val result = underTest.format()
|
val result = underTest.format()
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package net.dankito.fints.messages.segmente.implementierte
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class SignaturabschlussTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun format() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
val segmentNumber = 7
|
||||||
|
val controlReference = "1902675680"
|
||||||
|
val pin = "MyPin"
|
||||||
|
|
||||||
|
val underTest = Signaturabschluss(segmentNumber, controlReference, pin)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.format()
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo("HNSHA:$segmentNumber:2+$controlReference++$pin")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package net.dankito.fints.messages.segmente.implementierte
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.Laenderkennzeichen
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.IdentifizierungDerPartei
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Sicherheitsfunktion
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
|
class SignaturkopfTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun format() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
val securityFunction = Sicherheitsfunktion.PIN_TAN_911
|
||||||
|
val controlReference = "1902675680"
|
||||||
|
val partyIdentification = IdentifizierungDerPartei.SynchronizingCustomerSystemId
|
||||||
|
val date = 20191002
|
||||||
|
val time = 212757
|
||||||
|
val bankCode = "12345678"
|
||||||
|
val customerId = "0987654321"
|
||||||
|
val keyNumber = 0
|
||||||
|
val keyVersion = 0
|
||||||
|
|
||||||
|
val underTest = PinTanSignaturkopf(2, securityFunction, controlReference, partyIdentification,
|
||||||
|
date, time, Laenderkennzeichen.Germany, bankCode, customerId)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.format()
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo("HNSHK:2:4+PIN:2+${securityFunction.code}+$controlReference+1+1+1::0+1+1:$date:$time+1:999:1+6:10:16+280:$bankCode:$customerId:S:$keyNumber:$keyVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package net.dankito.fints.util
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.Test
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class FinTsUtilsTest {
|
||||||
|
|
||||||
|
private val underTest = FinTsUtils()
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun formatDate() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
val date = Date(88, 2, 27)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.formatDate(date)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo("19880327")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun formatDateAsInt() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
val date = Date(88, 2, 27)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.formatDateAsInt(date)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo(19880327)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun formatTime_AM() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
val date = Date(119, 9, 1, 8, 2, 1)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.formatTime(date)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo("080201")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun formatTime_PM() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
val date = Date(119, 9, 1, 18, 22, 51)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.formatTime(date)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo("182251")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun formatTimeAsInt_AM() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
val date = Date(119, 9, 1, 8, 2, 1)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.formatTimeAsInt(date)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo(80201)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun formatTimeAsInt_PM() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
val date = Date(119, 9, 1, 18, 22, 51)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.formatTimeAsInt(date)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo(182251)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue