[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: implement HPB
From: |
gnunet |
Subject: |
[libeufin] branch master updated: implement HPB |
Date: |
Tue, 05 Nov 2019 00:23:40 +0100 |
This is an automated email from the git hooks/post-receive script.
dold pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new 197e690 implement HPB
197e690 is described below
commit 197e69071b66347e4eccab3a6bba72eaef50826d
Author: Florian Dold <address@hidden>
AuthorDate: Tue Nov 5 00:23:35 2019 +0100
implement HPB
---
.../kotlin/tech/libeufin/sandbox/EbicsOrderUtil.kt | 44 +++
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 402 ++++++++++-----------
.../libeufin/schema/ebics_h004/EbicsMessages.kt | 36 +-
3 files changed, 276 insertions(+), 206 deletions(-)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsOrderUtil.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsOrderUtil.kt
new file mode 100644
index 0000000..2763afe
--- /dev/null
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsOrderUtil.kt
@@ -0,0 +1,44 @@
+/*
+ * This file is part of LibEuFin.
+ * Copyright (C) 2019 Stanisci and Dold.
+
+ * LibEuFin is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation; either version 3, or
+ * (at your option) any later version.
+
+ * LibEuFin is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+ * Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public
+ * License along with LibEuFin; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>
+ */
+
+package tech.libeufin.sandbox
+
+import java.util.zip.DeflaterInputStream
+import java.util.zip.InflaterInputStream
+
+/**
+ * Helpers for dealing with order compression, encryption, decryption,
chunking and re-assembly.
+ */
+class EbicsOrderUtil private constructor() {
+ companion object {
+ inline fun <reified T> decodeOrderDataXml(encodedOrderData:
ByteArray): T {
+ return InflaterInputStream(encodedOrderData.inputStream()).use {
+ val bytes = it.readAllBytes()
+
XMLUtil.convertStringToJaxb<T>(bytes.toString(Charsets.UTF_8)).value
+ }
+ }
+
+ inline fun <reified T>encodeOrderDataXml(obj: T): ByteArray {
+ val bytes = XMLUtil.convertJaxbToString(obj).toByteArray()
+ return DeflaterInputStream(bytes.inputStream()).use {
+ it.readAllBytes()
+ }
+ }
+ }
+}
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index eecfa42..16635bb 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -39,34 +39,36 @@ import io.ktor.routing.post
import io.ktor.routing.routing
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
+import org.apache.xml.security.binding.xmldsig.RSAKeyValueType
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.transactions.transaction
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.w3c.dom.Document
-import tech.libeufin.schema.ebics_h004.EbicsKeyManagementResponse
-import tech.libeufin.schema.ebics_h004.EbicsNoPubKeyDigestsRequest
-import tech.libeufin.schema.ebics_h004.EbicsUnsecuredRequest
-import tech.libeufin.schema.ebics_h004.HIARequestOrderDataType
+import tech.libeufin.schema.ebics_h004.*
import tech.libeufin.schema.ebics_hev.HEVResponse
import tech.libeufin.schema.ebics_hev.SystemReturnCodeType
import tech.libeufin.schema.ebics_s001.SignaturePubKeyOrderData
-import java.nio.charset.StandardCharsets.US_ASCII
-import java.nio.charset.StandardCharsets.UTF_8
import java.security.interfaces.RSAPublicKey
import java.text.DateFormat
-import java.util.zip.InflaterInputStream
import javax.sql.rowset.serial.SerialBlob
+import javax.xml.bind.JAXBContext
+import javax.xml.datatype.XMLGregorianCalendar
val logger: Logger = LoggerFactory.getLogger("tech.libeufin.sandbox")
data class EbicsRequestError(val statusCode: HttpStatusCode) :
Exception("Ebics request error")
+open class EbicsKeyManagementError(val errorText: String, val errorCode:
String) :
+ Exception("EBICS key management error: $errorText ($errorCode)")
+
+class EbicsInvalidXmlError : EbicsKeyManagementError("[EBICS_INVALID_XML]",
"091010")
+
private suspend fun ApplicationCall.respondEbicsKeyManagement(
errorText: String,
errorCode: String,
- statusCode: HttpStatusCode,
bankReturnCode: String,
+ dataTransfer: CryptoUtil.EncryptionResult? = null,
orderId: String? = null
) {
val responseXml = EbicsKeyManagementResponse().apply {
@@ -87,16 +89,27 @@ private suspend fun
ApplicationCall.respondEbicsKeyManagement(
this.authenticate = true
this.value = bankReturnCode
}
+ if (dataTransfer != null) {
+ this.dataTransfer =
EbicsKeyManagementResponse.Body.DataTransfer().apply {
+ this.dataEncryptionInfo = DataEncryptionInfo().apply {
+ this.authenticate = true
+ this.transactionKey =
dataTransfer.encryptedTransactionKey
+ this.encryptionPubKeyDigest =
DataEncryptionInfo.EncryptionPubKeyDigest().apply {
+ this.algorithm =
"http://www.w3.org/2001/04/xmlenc#sha256"
+ this.version = "E002"
+ this.value = dataTransfer.pubKeyDigest
+ }
+ }
+ this.orderData =
EbicsResponse.Body.DataTransferResponseType.OrderData().apply {
+ this.value = dataTransfer.encryptedData
+ }
+ }
+ }
}
}
val text = XMLUtil.convertJaxbToString(responseXml)
logger.info("responding with:\n${text}")
- respondText(text, ContentType.Application.Xml, statusCode)
-}
-
-
-private suspend fun ApplicationCall.respondEbicsInvalidXml() {
- respondEbicsKeyManagement("[EBICS_INVALID_XML]", "091010",
HttpStatusCode.BadRequest, "000000")
+ respondText(text, ContentType.Application.Xml, HttpStatusCode.OK)
}
@@ -114,196 +127,200 @@ fun findEbicsSubscriber(partnerID: String, userID:
String, systemID: String?): E
}.firstOrNull()
}
+
+data class Subscriber(
+ val partnerID: String,
+ val userID: String,
+ val systemID: String?
+)
+
data class SubscriberKeys(
val authenticationPublicKey: RSAPublicKey,
val encryptionPublicKey: RSAPublicKey,
val signaturePublicKey: RSAPublicKey
)
-private suspend fun ApplicationCall.ebicsweb() {
- val body: String = receiveText()
- logger.debug("Data received: $body")
-
- val bodyDocument: Document? = XMLUtil.parseStringIntoDom(body)
- if (bodyDocument == null || (!XMLUtil.validateFromDom(bodyDocument))) {
- respondEbicsInvalidXml()
- return
- }
+data class EbicsHostInfo(
+ val hostID: String,
+ val encryptionPublicKey: RSAPublicKey,
+ val authenticationPublicKey: RSAPublicKey
+)
- logger.info("Processing ${bodyDocument.documentElement.localName}")
- when (bodyDocument.documentElement.localName) {
- "ebicsUnsecuredRequest" -> {
+private suspend fun ApplicationCall.handleEbicsHia(header:
EbicsUnsecuredRequest.Header, orderData: ByteArray) {
+ val keyObject =
EbicsOrderUtil.decodeOrderDataXml<HIARequestOrderDataType>(orderData)
+ val encPubXml = keyObject.encryptionPubKeyInfo.pubKeyValue.rsaKeyValue
+ val authPubXml = keyObject.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue
+ val encPub = CryptoUtil.loadRsaPublicKeyFromComponents(encPubXml.modulus,
encPubXml.exponent)
+ val authPub =
CryptoUtil.loadRsaPublicKeyFromComponents(authPubXml.modulus,
authPubXml.exponent)
- val bodyJaxb = XMLUtil.convertDomToJaxb(
- EbicsUnsecuredRequest::class.java,
- bodyDocument
- )
+ transaction {
+ val ebicsSubscriber = findEbicsSubscriber(header.static.partnerID,
header.static.userID, header.static.systemID)
+ if (ebicsSubscriber == null) {
+ logger.warn("ebics subscriber not found")
+ throw EbicsRequestError(HttpStatusCode.NotFound)
+ }
+ ebicsSubscriber.authenticationKey = EbicsPublicKey.new {
+ this.rsaPublicKey = SerialBlob(authPub.encoded)
+ state = KeyState.NEW
+ }
+ ebicsSubscriber.encryptionKey = EbicsPublicKey.new {
+ this.rsaPublicKey = SerialBlob(encPub.encoded)
+ state = KeyState.NEW
+ }
+ ebicsSubscriber.state = when (ebicsSubscriber.state) {
+ SubscriberState.NEW -> SubscriberState.PARTIALLY_INITIALIZED_HIA
+ SubscriberState.PARTIALLY_INITIALIZED_INI ->
SubscriberState.INITIALIZED
+ else -> ebicsSubscriber.state
+ }
+ }
+ respondEbicsKeyManagement("[EBICS_OK]", "000000", "000000")
+}
- val staticHeader = bodyJaxb.value.header.static
- val requestHostID = bodyJaxb.value.header.static.hostID
- val ebicsHost = transaction {
- EbicsHost.find { EbicsHosts.hostID eq requestHostID
}.firstOrNull()
- }
+private suspend fun ApplicationCall.handleEbicsIni(header:
EbicsUnsecuredRequest.Header, orderData: ByteArray) {
+ val keyObject =
EbicsOrderUtil.decodeOrderDataXml<SignaturePubKeyOrderData>(orderData)
+ val sigPubXml = keyObject.signaturePubKeyInfo.pubKeyValue.rsaKeyValue
+ val sigPub = CryptoUtil.loadRsaPublicKeyFromComponents(sigPubXml.modulus,
sigPubXml.exponent)
- if (ebicsHost == null) {
- logger.warn("client requested unknown HostID")
- respondEbicsKeyManagement("[EBICS_INVALID_HOST_ID]", "091011",
HttpStatusCode.NotFound, "000000")
- return
- }
+ transaction {
+ val ebicsSubscriber =
+ findEbicsSubscriber(header.static.partnerID, header.static.userID,
header.static.systemID)
+ if (ebicsSubscriber == null) {
+ logger.warn("ebics subscriber ('${header.static.partnerID}' /
'${header.static.userID}' / '${header.static.systemID}') not found")
+ throw EbicsRequestError(HttpStatusCode.NotFound)
+ }
+ ebicsSubscriber.signatureKey = EbicsPublicKey.new {
+ this.rsaPublicKey = SerialBlob(sigPub.encoded)
+ state = KeyState.NEW
+ }
+ ebicsSubscriber.state = when (ebicsSubscriber.state) {
+ SubscriberState.NEW -> SubscriberState.PARTIALLY_INITIALIZED_INI
+ SubscriberState.PARTIALLY_INITIALIZED_HIA ->
SubscriberState.INITIALIZED
+ else -> ebicsSubscriber.state
+ }
+ }
+ logger.info("Signature key inserted in database _and_ subscriber state
changed accordingly")
+ respondEbicsKeyManagement("[EBICS_OK]", "000000", bankReturnCode =
"000000", orderId = "OR01")
+}
- logger.info("Serving a
${bodyJaxb.value.header.static.orderDetails.orderType} request")
-
- /**
- * NOTE: the JAXB interface has some automagic mechanism that
decodes
- * the Base64 string into its byte[] form _at the same time_ it
instantiates
- * the object; in other words, there is no need to perform here
the decoding.
- */
- val zkey = bodyJaxb.value.body.dataTransfer.orderData.value
-
- /**
- * The validation enforces zkey to be a base64 value, but does not
check
- * whether it is given _empty_ or not; will check explicitly here.
FIXME:
- * shall the schema be patched to avoid having this if-block here?
- */
- if (zkey.isEmpty()) {
- logger.info("0-length key element given, invalid request")
- respondEbicsInvalidXml()
- return
+private suspend fun ApplicationCall.handleEbicsHpb(
+ ebicsHostInfo: EbicsHostInfo,
+ requestDocument: Document,
+ header: EbicsNoPubKeyDigestsRequest.Header
+) {
+ val subscriberKeys = transaction {
+ val ebicsSubscriber =
+ findEbicsSubscriber(header.static.partnerID, header.static.userID,
header.static.systemID)
+ if (ebicsSubscriber == null) {
+ throw EbicsRequestError(HttpStatusCode.Unauthorized)
+ }
+ if (ebicsSubscriber.state != SubscriberState.INITIALIZED) {
+ throw EbicsRequestError(HttpStatusCode.Forbidden)
+ }
+ val authPubBlob = ebicsSubscriber.authenticationKey!!.rsaPublicKey
+ val encPubBlob = ebicsSubscriber.encryptionKey!!.rsaPublicKey
+ val sigPubBlob = ebicsSubscriber.signatureKey!!.rsaPublicKey
+ SubscriberKeys(
+ CryptoUtil.loadRsaPublicKey(authPubBlob.toByteArray()),
+ CryptoUtil.loadRsaPublicKey(encPubBlob.toByteArray()),
+ CryptoUtil.loadRsaPublicKey(sigPubBlob.toByteArray())
+ )
+ }
+ val validationResult =
+ XMLUtil.verifyEbicsDocument(requestDocument,
subscriberKeys.authenticationPublicKey)
+ logger.info("validationResult: $validationResult")
+ if (!validationResult) {
+ throw EbicsKeyManagementError("invalid signature", "90000");
+ }
+ val hpbRespondeData = HPBResponseOrderData().apply {
+ this.authenticationPubKeyInfo = AuthenticationPubKeyInfoType().apply {
+ this.authenticationVersion = "X002"
+ this.pubKeyValue = PubKeyValueType().apply {
+ this.rsaKeyValue = RSAKeyValueType().apply {
+ this.exponent =
ebicsHostInfo.authenticationPublicKey.publicExponent.toByteArray()
+ this.modulus =
ebicsHostInfo.authenticationPublicKey.modulus.toByteArray()
+ }
}
-
- /**
- * This value holds the bytes[] of a XML
"SignaturePubKeyOrderData" document
- * and at this point is valid and _never_ empty.
- */
- val inflater = InflaterInputStream(zkey.inputStream())
-
- var payload = try {
- ByteArray(1) { inflater.read().toByte() }
- } catch (e: Exception) {
- e.printStackTrace()
- respondEbicsInvalidXml()
- return
+ }
+ this.encryptionPubKeyInfo = EncryptionPubKeyInfoType().apply {
+ this.encryptionVersion = "E002"
+ this.pubKeyValue = PubKeyValueType().apply {
+ this.rsaKeyValue = RSAKeyValueType().apply {
+ this.exponent =
ebicsHostInfo.encryptionPublicKey.publicExponent.toByteArray()
+ this.modulus =
ebicsHostInfo.encryptionPublicKey.modulus.toByteArray()
+ }
}
+ }
+ this.hostID = ebicsHostInfo.hostID
+ }
- while (inflater.available() == 1) {
- payload += inflater.read().toByte()
- }
+ val compressedOrderData =
EbicsOrderUtil.encodeOrderDataXml(hpbRespondeData)
- inflater.close()
+ val encryptionResult = CryptoUtil.encryptEbicsE002(compressedOrderData,
subscriberKeys.encryptionPublicKey)
- logger.debug("Found payload: ${payload.toString(US_ASCII)}")
+ respondEbicsKeyManagement("[EBICS_OK]", "000000", "000000",
encryptionResult, "OR01")
+}
- when (bodyJaxb.value.header.static.orderDetails.orderType) {
- "INI" -> {
- val keyObject =
XMLUtil.convertStringToJaxb<SignaturePubKeyOrderData>(payload.toString(UTF_8))
+/**
+ * Find the ebics host corresponding to the one specified in the header.
+ */
+private fun ApplicationCall.ensureEbicsHost(requestHostID: String):
EbicsHostInfo {
+ return transaction {
+ val ebicsHost = EbicsHost.find { EbicsHosts.hostID eq requestHostID
}.firstOrNull()
+ if (ebicsHost == null) {
+ logger.warn("client requested unknown HostID")
+ throw EbicsKeyManagementError("[EBICS_INVALID_HOST_ID]", "091011")
+ }
+ val encryptionPrivateKey =
CryptoUtil.loadRsaPrivateKey(ebicsHost.encryptionPrivateKey.toByteArray())
+ val authenticationPrivateKey =
CryptoUtil.loadRsaPrivateKey(ebicsHost.authenticationPrivateKey.toByteArray())
+ EbicsHostInfo(
+ requestHostID,
+ CryptoUtil.getRsaPublicFromPrivate(encryptionPrivateKey),
+ CryptoUtil.getRsaPublicFromPrivate(authenticationPrivateKey)
+ )
+ }
+}
- val rsaPublicKey: RSAPublicKey = try {
- CryptoUtil.loadRsaPublicKeyFromComponents(
-
keyObject.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
-
keyObject.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.exponent
- )
- } catch (e: Exception) {
- logger.info("User gave bad key, not storing it")
- e.printStackTrace()
- respondEbicsInvalidXml()
- return
- }
- // put try-catch block here? (FIXME)
- transaction {
- val ebicsSubscriber =
- findEbicsSubscriber(staticHeader.partnerID,
staticHeader.userID, staticHeader.systemID)
- if (ebicsSubscriber == null) {
- logger.warn("ebics subscriber
('${staticHeader.partnerID}' / '${staticHeader.userID}' /
'${staticHeader.systemID}') not found")
- throw EbicsRequestError(HttpStatusCode.NotFound)
- }
- ebicsSubscriber.signatureKey = EbicsPublicKey.new {
- this.rsaPublicKey =
SerialBlob(rsaPublicKey.encoded)
- state = KeyState.NEW
- }
+private suspend fun ApplicationCall.receiveEbicsXml(): Document {
+ val body: String = receiveText()
+ logger.debug("Data received: $body")
+ val requestDocument: Document? = XMLUtil.parseStringIntoDom(body)
+ if (requestDocument == null ||
(!XMLUtil.validateFromDom(requestDocument))) {
+ throw EbicsInvalidXmlError()
+ }
+ return requestDocument
+}
- if (ebicsSubscriber.state == SubscriberState.NEW) {
- ebicsSubscriber.state =
SubscriberState.PARTIALLY_INITIALIZED_INI
- }
- if (ebicsSubscriber.state ==
SubscriberState.PARTIALLY_INITIALIZED_HIA) {
- ebicsSubscriber.state = SubscriberState.INITIALIZED
- }
- }
+inline fun <reified T> Document.toObject(): T {
+ val jc = JAXBContext.newInstance(T::class.java)
+ val m = jc.createUnmarshaller()
+ return m.unmarshal(this, T::class.java).value
+}
- logger.info("Signature key inserted in database _and_
subscriber state changed accordingly")
- respondEbicsKeyManagement(
- "[EBICS_OK]",
- "000000",
- HttpStatusCode.OK,
- bankReturnCode = "000000",
- orderId = "OR01"
- )
- return
- }
- "HIA" -> {
- val keyObject =
XMLUtil.convertStringToJaxb<HIARequestOrderDataType>(payload.toString(US_ASCII))
-
- val authenticationPublicKey = try {
- CryptoUtil.loadRsaPublicKeyFromComponents(
-
keyObject.value.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
-
keyObject.value.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
- )
- } catch (e: Exception) {
- logger.info("auth public key invalid")
- e.printStackTrace()
- respondEbicsInvalidXml()
- return
- }
+private suspend fun ApplicationCall.ebicsweb() {
+ val requestDocument = receiveEbicsXml()
- val encryptionPublicKey = try {
- CryptoUtil.loadRsaPublicKeyFromComponents(
-
keyObject.value.encryptionPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
-
keyObject.value.encryptionPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
- )
- } catch (e: Exception) {
- logger.info("auth public key invalid")
- e.printStackTrace()
- respondEbicsInvalidXml()
- return
- }
+ logger.info("Processing ${requestDocument.documentElement.localName}")
- transaction {
- val ebicsSubscriber =
- findEbicsSubscriber(staticHeader.partnerID,
staticHeader.userID, staticHeader.systemID)
- if (ebicsSubscriber == null) {
- logger.warn("ebics subscriber not found")
- throw EbicsRequestError(HttpStatusCode.NotFound)
- }
- ebicsSubscriber.authenticationKey = EbicsPublicKey.new
{
- this.rsaPublicKey =
SerialBlob(authenticationPublicKey.encoded)
- state = KeyState.NEW
- }
- ebicsSubscriber.encryptionKey = EbicsPublicKey.new {
- this.rsaPublicKey =
SerialBlob(encryptionPublicKey.encoded)
- state = KeyState.NEW
- }
+ when (requestDocument.documentElement.localName) {
+ "ebicsUnsecuredRequest" -> {
+ val requestObject =
requestDocument.toObject<EbicsUnsecuredRequest>()
+ logger.info("Serving a
${requestObject.header.static.orderDetails.orderType} request")
- if (ebicsSubscriber.state == SubscriberState.NEW) {
- ebicsSubscriber.state =
SubscriberState.PARTIALLY_INITIALIZED_HIA
- }
+ val orderData = requestObject.body.dataTransfer.orderData.value
+ val header = requestObject.header
- if (ebicsSubscriber.state ==
SubscriberState.PARTIALLY_INITIALIZED_INI) {
- ebicsSubscriber.state = SubscriberState.INITIALIZED
- }
- }
- respondEbicsKeyManagement("[EBICS_OK]", "000000",
HttpStatusCode.OK, "000000")
- return
- }
+ when (header.static.orderDetails.orderType) {
+ "INI" -> handleEbicsIni(header, orderData)
+ "HIA" -> handleEbicsHia(header, orderData)
+ else -> throw EbicsInvalidXmlError()
}
-
- throw AssertionError("not reached")
}
-
"ebicsHEVRequest" -> {
val hevResponse = HEVResponse().apply {
this.systemReturnCode = SystemReturnCodeType().apply {
@@ -315,41 +332,17 @@ private suspend fun ApplicationCall.ebicsweb() {
val strResp = XMLUtil.convertJaxbToString(hevResponse)
respondText(strResp, ContentType.Application.Xml,
HttpStatusCode.OK)
- return
}
"ebicsNoPubKeyDigestsRequest" -> {
- val requestJaxb =
XMLUtil.convertDomToJaxb(EbicsNoPubKeyDigestsRequest::class.java, bodyDocument)
- val staticHeader = requestJaxb.value.header.static
- when (val orderType = staticHeader.orderDetails.orderType) {
- "HPB" -> {
- val subscriberKeys = transaction {
- val ebicsSubscriber =
- findEbicsSubscriber(staticHeader.partnerID,
staticHeader.userID, staticHeader.systemID)
- if (ebicsSubscriber == null) {
- throw
EbicsRequestError(HttpStatusCode.Unauthorized)
- }
- if (ebicsSubscriber.state !=
SubscriberState.INITIALIZED) {
- throw EbicsRequestError(HttpStatusCode.Forbidden)
- }
- val authPubBlob =
ebicsSubscriber.authenticationKey!!.rsaPublicKey
- val encPubBlob =
ebicsSubscriber.encryptionKey!!.rsaPublicKey
- val sigPubBlob =
ebicsSubscriber.signatureKey!!.rsaPublicKey
- SubscriberKeys(
-
CryptoUtil.loadRsaPublicKey(authPubBlob.toByteArray()),
-
CryptoUtil.loadRsaPublicKey(encPubBlob.toByteArray()),
-
CryptoUtil.loadRsaPublicKey(sigPubBlob.toByteArray())
- )
- }
- val validationResult =
- XMLUtil.verifyEbicsDocument(bodyDocument,
subscriberKeys.authenticationPublicKey)
- logger.info("validationResult: $validationResult")
- }
- else -> {
- logger.warn("order type '${orderType}' not supported for
ebicsNoPubKeyDigestsRequest")
- respondEbicsInvalidXml()
- }
+ val requestObject =
requestDocument.toObject<EbicsNoPubKeyDigestsRequest>()
+ val hostInfo = ensureEbicsHost(requestObject.header.static.hostID)
+ when (requestObject.header.static.orderDetails.orderType) {
+ "HPB" -> handleEbicsHpb(hostInfo, requestDocument,
requestObject.header)
+ else -> throw EbicsInvalidXmlError()
}
}
+ "ebicsRequest" -> {
+ }
else -> {
/* Log to console and return "unknown type" */
logger.info("Unknown message, just logging it!")
@@ -357,7 +350,6 @@ private suspend fun ApplicationCall.ebicsweb() {
HttpStatusCode.NotImplemented,
SandboxError("Not Implemented")
)
- return
}
}
}
@@ -396,7 +388,7 @@ fun main() {
}
install(StatusPages) {
exception<Throwable> { cause ->
- logger.error("Exception while handling
'${call.request.uri.toString()}'", cause)
+ logger.error("Exception while handling '${call.request.uri}'",
cause)
call.respondText("Internal server error.",
ContentType.Text.Plain, HttpStatusCode.InternalServerError)
}
}
diff --git
a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt
b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt
index 2b33ec6..964fdc7 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt
@@ -182,6 +182,9 @@ class DataEncryptionInfo {
@XmlAccessorType(XmlAccessType.NONE)
class EncryptionPubKeyDigest {
+ /**
+ * Version of the *digest* of the public key.
+ */
@get:XmlAttribute(name = "Version", required = true)
@get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
lateinit var version: String
@@ -511,7 +514,7 @@ class EbicsKeyManagementResponse {
@XmlType(name = "", propOrder = ["dataTransfer", "returnCode",
"timestampBankParameter"])
class Body {
@get:XmlElement(name = "DataTransfer")
- val dataTransfer: DataTransfer? = null
+ var dataTransfer: DataTransfer? = null
@get:XmlElement(name = "ReturnCode", required = true)
lateinit var returnCode: ReturnCode
@@ -597,4 +600,35 @@ class HPBResponseOrderData {
@get:XmlElement(name = "HostID", required = true)
@get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
lateinit var hostID: String
+}
+
+
+@XmlAccessorType(XmlAccessType.NONE)
+@XmlType(name = "", propOrder = ["partnerInfo", "userInfo"])
+@XmlRootElement(name = "HTDResponseOrderData")
+class HTDesponseOrderData {
+ @get:XmlElement(name = "PartnerInfo", required = true)
+ lateinit var partnerInfo: PartnerInfo
+
+ @get:XmlElement(name = "UserInfo", required = true)
+ lateinit var userInfo: UserInfo
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ class PartnerInfo {
+
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ class UserInfo {
+
+ @get:XmlElement(name = "AddressInfo", required = true)
+ lateinit var addressInfo: AddressInfo
+
+ @get:XmlElement(name = "BankInfo", required = true)
+ lateinit var bankInfo: BankInfo
+
+ class AddressInfo
+ class BankInfo
+
+ }
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
address@hidden.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: implement HPB,
gnunet <=