commit a168b4ec790f898e7f260ee64658b35639020a09
parent dcac56ce7860a880f7c54b3e9a2275c16e37f700
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date: Mon, 25 Nov 2019 22:07:40 +0100
Move request constructors into companion objects.
Diffstat:
5 files changed, 407 insertions(+), 340 deletions(-)
diff --git a/nexus/src/main/kotlin/Containers.kt b/nexus/src/main/kotlin/Containers.kt
@@ -14,27 +14,27 @@ import javax.xml.bind.JAXBElement
* / make messages. And not all the values are needed all
* the time.
*/
-data class EbicsContainer<T>(
+data class EbicsContainer(
- // needed to verify responses
- val bankAuthPub: RSAPublicKey? = null,
+ val partnerId: String,
- val bankEncPub: RSAPublicKey? = null,
+ val userId: String,
+
+
+ var bankAuthPub: RSAPublicKey?,
+ var bankEncPub: RSAPublicKey?,
// needed to send the message
- val ebicsUrl: String? = null,
+ val ebicsUrl: String,
// needed to craft further messages
- val hostId: String? = null,
-
- // needed to encrypt order data during all the phases
- val plainTransactionKey: SecretKey? = null,
+ val hostId: String,
// needed to decrypt data coming from the bank
- val customerEncPriv: RSAPrivateCrtKey? = null,
+ val customerEncPriv: RSAPrivateCrtKey,
// needed to sign documents
- val customerAuthPriv: RSAPrivateCrtKey? = null,
+ val customerAuthPriv: RSAPrivateCrtKey,
- val jaxb: T? = null
+ val customerSignPriv: RSAPrivateCrtKey
)
\ No newline at end of file
diff --git a/nexus/src/main/kotlin/Main.kt b/nexus/src/main/kotlin/Main.kt
@@ -82,6 +82,39 @@ fun testData() {
}
}
+fun containerInit(subscriber: EbicsSubscriberEntity): EbicsContainer {
+
+ var bankAuthPubValue: RSAPublicKey? = null
+ if (subscriber.bankAuthenticationPublicKey != null) {
+ bankAuthPubValue = CryptoUtil.loadRsaPublicKey(
+ subscriber.bankAuthenticationPublicKey?.toByteArray()!!
+ )
+ }
+ var bankEncPubValue: RSAPublicKey? = null
+ if (subscriber.bankEncryptionPublicKey != null) {
+ bankEncPubValue = CryptoUtil.loadRsaPublicKey(
+ subscriber.bankEncryptionPublicKey?.toByteArray()!!
+ )
+ }
+
+ return EbicsContainer(
+
+
+ bankAuthPub = bankAuthPubValue,
+ bankEncPub = bankEncPubValue,
+
+ ebicsUrl = subscriber.ebicsURL,
+ hostId = subscriber.hostID,
+ userId = subscriber.userID,
+ partnerId = subscriber.partnerID,
+
+ customerSignPriv = CryptoUtil.loadRsaPrivateKey(subscriber.signaturePrivateKey.toByteArray()),
+ customerAuthPriv = CryptoUtil.loadRsaPrivateKey(subscriber.authenticationPrivateKey.toByteArray()),
+ customerEncPriv = CryptoUtil.loadRsaPrivateKey(subscriber.authenticationPrivateKey.toByteArray())
+ )
+
+}
+
/**
* Inserts spaces every 2 characters, and a newline after 8 pairs.
*/
@@ -122,14 +155,14 @@ fun expectId(param: String?): Int {
fun signOrder(
orderBlob: ByteArray,
- signKey: ByteArray,
+ signKey: RSAPrivateCrtKey,
partnerId: String,
userId: String
): UserSignatureData {
val ES_signature = CryptoUtil.signEbicsA006(
- CryptoUtil.digestEbicsOrderA006(orderBlob),
- CryptoUtil.loadRsaPrivateKey(signKey)
+ CryptoUtil.digestEbicsOrderA006(orderBlob),
+ signKey
)
val userSignatureData = UserSignatureData().apply {
orderSignatureList = listOf(
@@ -142,7 +175,7 @@ fun signOrder(
)
}
- return userSignatureData
+ return userSignatureData
}
@@ -263,6 +296,7 @@ data class UnparsableResponse(val statusCode: HttpStatusCode, val rawResponse: S
data class EbicsError(val codeError: String) : Exception("Bank did not accepted EBICS request, error is: ${codeError}")
data class BadSignature(val statusCode: HttpStatusCode) : Exception("Signature verification unsuccessful")
data class BadBackup(val statusCode: HttpStatusCode) : Exception("Could not restore backed up keys")
+data class BankInvalidResponse(val statusCode: HttpStatusCode) : Exception("Missing data from bank response")
@@ -366,66 +400,24 @@ fun main() {
get("/ebics/subscribers/{id}/sendHtd") {
val id = expectId(call.parameters["id"])
- val bundle = transaction {
- val subscriber = EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
- val request = EbicsRequest().apply {
- version = "H004"
- revision = 1
- header = EbicsRequest.Header().apply {
- authenticate = true
- static = EbicsRequest.StaticHeaderType().apply {
- userID = subscriber.userID
- partnerID = subscriber.partnerID
- hostID = subscriber.hostID
- nonce = getNonce(128)
- timestamp = getGregorianDate()
- partnerID = subscriber.partnerID
- orderDetails = EbicsRequest.OrderDetails().apply {
- orderType = "HTD"
- orderAttribute = "DZHNN"
- orderParams = EbicsRequest.StandardOrderParams()
- }
- bankPubKeyDigests = EbicsRequest.BankPubKeyDigests().apply {
- authentication = EbicsTypes.PubKeyDigest().apply {
- algorithm = "http://www.w3.org/2001/04/xmlenc#sha256"
- version = "X002"
- value = CryptoUtil.getEbicsPublicKeyHash(
- CryptoUtil.loadRsaPublicKey(
- (subscriber.bankAuthenticationPublicKey ?: throw BankKeyMissing(HttpStatusCode.NotAcceptable)).toByteArray()
- )
- )
- }
- encryption = EbicsTypes.PubKeyDigest().apply {
- algorithm = "http://www.w3.org/2001/04/xmlenc#sha256"
- version = "E002"
- value = CryptoUtil.getEbicsPublicKeyHash(
- CryptoUtil.loadRsaPublicKey(
- (subscriber.bankEncryptionPublicKey ?: throw BankKeyMissing(HttpStatusCode.NotAcceptable)).toByteArray()
- )
- )
- }
- securityMedium = "0000"
- }
- mutable = EbicsRequest.MutableHeader().apply {
- transactionPhase = EbicsTypes.TransactionPhaseType.INITIALISATION
- }
- authSignature = SignatureType()
- }
- }
- body = EbicsRequest.Body()
- }
+ val subscriberData = transaction {
+ containerInit(EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound))
+ }
- EbicsContainer(
- ebicsUrl = subscriber.ebicsURL,
- customerEncPriv = CryptoUtil.loadRsaPrivateKey(subscriber.encryptionPrivateKey.toByteArray()),
- customerAuthPriv = CryptoUtil.loadRsaPrivateKey(subscriber.authenticationPrivateKey.toByteArray()),
- jaxb = request,
- hostId = subscriber.hostID
+ val response = client.postToBankUnsigned<EbicsRequest, EbicsResponse>(
+ subscriberData.ebicsUrl,
+ EbicsRequest.createForDownloadInitializationPhase(
+ subscriberData.userId,
+ subscriberData.partnerId,
+ subscriberData.hostId,
+ getNonce(128),
+ getGregorianDate(),
+ subscriberData.bankEncPub ?: throw BankKeyMissing(HttpStatusCode.PreconditionFailed),
+ subscriberData.bankAuthPub ?: throw BankKeyMissing(HttpStatusCode.PreconditionFailed),
+ "HTD"
)
- }
-
- val response = client.postToBankUnsigned<EbicsRequest, EbicsResponse>(bundle.ebicsUrl!!, bundle.jaxb!!)
+ )
logger.debug("HTD response: " + XMLUtil.convertJaxbToString<EbicsResponse>(response.value))
if (response.value.body.returnCode.value != "000000") {
@@ -443,42 +435,23 @@ fun main() {
val dataCompr = CryptoUtil.decryptEbicsE002(
er,
- bundle.customerEncPriv!!
+ subscriberData.customerEncPriv
)
val data = EbicsOrderUtil.decodeOrderDataXml<HTDResponseOrderData>(dataCompr)
logger.debug("HTD payload is: ${XMLUtil.convertJaxbToString(data)}")
-
- val ackRequest = EbicsRequest().apply {
- header = EbicsRequest.Header().apply {
- version = "H004"
- revision = 1
- authenticate = true
- static = EbicsRequest.StaticHeaderType().apply {
- hostID = bundle.hostId!!
- transactionID = response.value.header._static.transactionID
- }
- mutable = EbicsRequest.MutableHeader().apply {
- transactionPhase = EbicsTypes.TransactionPhaseType.RECEIPT
- }
- }
- authSignature = SignatureType()
-
- body = EbicsRequest.Body().apply {
- transferReceipt = EbicsRequest.TransferReceipt().apply {
- authenticate = true
- receiptCode = 0 // always true at this point.
- }
- }
- }
+ val ackRequest = EbicsRequest.createForDownloadReceiptPhase(
+ response.value.header._static.transactionID ?: throw BankInvalidResponse(HttpStatusCode.ExpectationFailed),
+ subscriberData.userId
+ )
val ackResponse = client.postToBankSignedAndVerify<EbicsRequest, EbicsResponse>(
- bundle.ebicsUrl,
+ subscriberData.ebicsUrl,
ackRequest,
- bundle.bankAuthPub!!,
- bundle.customerAuthPriv!!
+ subscriberData.bankAuthPub ?: throw BankKeyMissing(HttpStatusCode.PreconditionFailed),
+ subscriberData.customerAuthPriv
)
logger.debug("HTD final response: " + XMLUtil.convertJaxbToString<EbicsResponse>(response.value))
@@ -706,58 +679,22 @@ fun main() {
val id = expectId(call.parameters["id"]) // caught above
val iniRequest = EbicsUnsecuredRequest()
- val url = transaction {
- val subscriber = EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
- val tmpKey = CryptoUtil.loadRsaPrivateKey(subscriber.signaturePrivateKey.toByteArray())
-
- iniRequest.apply {
- version = "H004"
- revision = 1
- header = EbicsUnsecuredRequest.Header().apply {
- authenticate = true
- static = EbicsUnsecuredRequest.StaticHeaderType().apply {
- orderDetails = EbicsUnsecuredRequest.OrderDetails().apply {
- orderAttribute = "DZNNN"
- orderType = "INI"
- securityMedium = "0000"
- hostID = subscriber.hostID
- userID = subscriber.userID
- partnerID = subscriber.partnerID
- systemID = subscriber.systemID
- }
-
- }
- mutable = EbicsUnsecuredRequest.Header.EmptyMutableHeader()
- }
- body = EbicsUnsecuredRequest.Body().apply {
- dataTransfer = EbicsUnsecuredRequest.UnsecuredDataTransfer().apply {
- orderData = EbicsUnsecuredRequest.OrderData().apply {
- value = EbicsOrderUtil.encodeOrderDataXml(
- SignatureTypes.SignaturePubKeyOrderData().apply {
- signaturePubKeyInfo = SignatureTypes.SignaturePubKeyInfoType().apply {
- signatureVersion = "A006"
- pubKeyValue = SignatureTypes.PubKeyValueType().apply {
- rsaKeyValue = org.apache.xml.security.binding.xmldsig.RSAKeyValueType().apply {
- exponent = tmpKey.publicExponent.toByteArray()
- modulus = tmpKey.modulus.toByteArray()
- }
- }
- }
- userID = subscriber.userID
- partnerID = subscriber.partnerID
-
- }
- )
- }
- }
- }
- }
- subscriber.ebicsURL
+ val subscriberData = transaction {
+ containerInit(
+ EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
+ )
}
+ val theRequest = EbicsUnsecuredRequest.createIni(
+ subscriberData.hostId,
+ subscriberData.userId,
+ subscriberData.partnerId,
+ subscriberData.customerSignPriv
+ )
+
val responseJaxb = client.postToBankUnsigned<EbicsUnsecuredRequest, EbicsKeyManagementResponse>(
- url,
- iniRequest
+ subscriberData.ebicsUrl,
+ theRequest
)
if (responseJaxb.value.body.returnCode.value != "000000") {
@@ -849,97 +786,74 @@ fun main() {
val id = expectId(call.parameters["id"])
- val innerPayload = "ES-PAYLOAD"
- val container = transaction {
- val subscriber = EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
+ val subscriberData = transaction {
+ containerInit(
+ EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
+ )
+ }
- val usd_compressed = EbicsOrderUtil.encodeOrderDataXml(
+ val payload = "PAYLOAD"
+ val usd_encrypted = CryptoUtil.encryptEbicsE002(
+ EbicsOrderUtil.encodeOrderDataXml(
signOrder(
- innerPayload.toByteArray(),
- subscriber.signaturePrivateKey.toByteArray(),
- subscriber.partnerID,
- subscriber.userID
- )
-
- )
- val usd_encrypted = CryptoUtil.encryptEbicsE002(
- usd_compressed,
- CryptoUtil.loadRsaPublicKey(
- subscriber.bankEncryptionPublicKey?.toByteArray() ?: throw BankKeyMissing(HttpStatusCode.NotFound)
+ payload.toByteArray(),
+ subscriberData.customerSignPriv,
+ subscriberData.partnerId,
+ subscriberData.userId
)
- )
-
- EbicsContainer(
- jaxb = EbicsRequest.createForUploadInitializationPhase(
- usd_encrypted,
- subscriber.hostID,
- getNonce(128),
- subscriber.partnerID,
- subscriber.userID,
- getGregorianDate(),
- CryptoUtil.loadRsaPublicKey(subscriber.bankAuthenticationPublicKey?.toByteArray() ?: throw BankKeyMissing(
- HttpStatusCode.PreconditionFailed
- )),
- CryptoUtil.loadRsaPublicKey(subscriber.bankEncryptionPublicKey?.toByteArray() ?: throw BankKeyMissing(
- HttpStatusCode.PreconditionFailed
- )),
- BigInteger.ONE
- ),
-
- ebicsUrl = subscriber.ebicsURL,
- bankAuthPub = CryptoUtil.loadRsaPublicKey(
- subscriber.bankAuthenticationPublicKey?.toByteArray() ?: throw BankKeyMissing(HttpStatusCode.PreconditionFailed)
- ),
-
- plainTransactionKey = usd_encrypted.plainTransactionKey,
- customerAuthPriv = CryptoUtil.loadRsaPrivateKey(
- subscriber.authenticationPrivateKey.toByteArray()
- ),
-
- bankEncPub = CryptoUtil.loadRsaPublicKey(
- subscriber.bankEncryptionPublicKey?.toByteArray() ?: throw BankKeyMissing(
- HttpStatusCode.PreconditionFailed)
- ),
+ ),
+ subscriberData.bankEncPub!!
+ )
- hostId = subscriber.hostID
- )
- }
val response = client.postToBankSignedAndVerify<EbicsRequest, EbicsResponse>(
- container.ebicsUrl!!,
- container.jaxb!!,
- container.bankAuthPub!!,
- container.customerAuthPriv!!
+ subscriberData.ebicsUrl,
+ EbicsRequest.createForUploadInitializationPhase(
+ usd_encrypted,
+ subscriberData.hostId,
+ getNonce(128),
+ subscriberData.partnerId,
+ subscriberData.userId,
+ getGregorianDate(),
+ subscriberData.bankAuthPub!!,
+ subscriberData.bankEncPub!!,
+ BigInteger.ONE,
+ "TST"
+ ),
+ subscriberData.bankAuthPub!!,
+ subscriberData.customerAuthPriv
)
if (response.value.body.returnCode.value != "000000") {
throw EbicsError(response.value.body.returnCode.value)
}
+ logger.debug("INIT phase passed!")
+
/* now send actual payload */
val compressedInnerPayload = DeflaterInputStream(
- innerPayload.toByteArray().inputStream()
+ payload.toByteArray().inputStream()
).use { it.readAllBytes() }
val encryptedPayload = CryptoUtil.encryptEbicsE002withTransactionKey(
compressedInnerPayload,
- container.bankEncPub!!,
- container.plainTransactionKey!!
+ subscriberData.bankEncPub!!,
+ usd_encrypted.plainTransactionKey!!
)
- val tmpTmp = EbicsRequest.createForUploadTransferPhase(
- container.hostId!!,
+ val tmp = EbicsRequest.createForUploadTransferPhase(
+ subscriberData.hostId,
response.value.header._static.transactionID!!,
BigInteger.ONE,
encryptedPayload.encryptedData
)
val responseTransaction = client.postToBankSignedAndVerify<EbicsRequest, EbicsResponse>(
- container.ebicsUrl,
- tmpTmp,
- container.bankAuthPub,
- container.customerAuthPriv
+ subscriberData.ebicsUrl,
+ tmp,
+ subscriberData.bankAuthPub!!,
+ subscriberData.customerAuthPriv
)
if (responseTransaction.value.body.returnCode.value != "000000") {
@@ -957,46 +871,21 @@ fun main() {
post("/ebics/subscribers/{id}/sync") {
val id = expectId(call.parameters["id"])
val bundle = transaction {
- val subscriber = EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
- val hpbRequest = EbicsNpkdRequest().apply {
- version = "H004"
- revision = 1
- header = EbicsNpkdRequest.Header().apply {
- authenticate = true
- mutable = EbicsNpkdRequest.EmptyMutableHeader()
- static = EbicsNpkdRequest.StaticHeaderType().apply {
- hostID = subscriber.hostID
- partnerID = subscriber.partnerID
- userID = subscriber.userID
- securityMedium = "0000"
- orderDetails = EbicsNpkdRequest.OrderDetails()
- orderDetails.orderType = "HPB"
- orderDetails.orderAttribute = "DZHNN"
- nonce = getNonce(128)
- timestamp = getGregorianDate()
- }
- }
- body = EbicsNpkdRequest.EmptyBody()
- authSignature = SignatureType()
- }
-
- EbicsContainer(
- ebicsUrl = subscriber.ebicsURL,
- customerEncPriv = CryptoUtil.loadRsaPrivateKey(
- subscriber.encryptionPrivateKey.toByteArray()
- ),
- customerAuthPriv = CryptoUtil.loadRsaPrivateKey(
- subscriber.authenticationPrivateKey.toByteArray()
- ),
-
- jaxb = hpbRequest
+ containerInit(
+ EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
)
}
val response = client.postToBankSigned<EbicsNpkdRequest, EbicsKeyManagementResponse>(
bundle.ebicsUrl!!,
- bundle.jaxb!!,
- bundle.customerAuthPriv!!
+ EbicsNpkdRequest.createRequest(
+ bundle.hostId,
+ bundle.partnerId,
+ bundle.userId,
+ getNonce(128),
+ getGregorianDate()
+ ),
+ bundle.customerAuthPriv
)
if (response.value.body.returnCode.value != "000000") {
@@ -1012,25 +901,28 @@ fun main() {
val dataCompr = CryptoUtil.decryptEbicsE002(
er,
- bundle.customerEncPriv!!
+ bundle.customerEncPriv
)
val data = EbicsOrderUtil.decodeOrderDataXml<HPBResponseOrderData>(dataCompr)
- val bankAuthPubBlob = CryptoUtil.loadRsaPublicKeyFromComponents(
- data.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
- data.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
- )
-
- val bankEncPubBlob = CryptoUtil.loadRsaPublicKeyFromComponents(
- data.encryptionPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
- data.encryptionPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
- )
-
// put bank's keys into database.
transaction {
val subscriber = EbicsSubscriberEntity.findById(id)
- subscriber!!.bankAuthenticationPublicKey = SerialBlob(bankAuthPubBlob.encoded)
- subscriber!!.bankEncryptionPublicKey = SerialBlob(bankEncPubBlob.encoded)
+
+ subscriber!!.bankAuthenticationPublicKey = SerialBlob(
+
+ CryptoUtil.loadRsaPublicKeyFromComponents(
+ data.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
+ data.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
+ ).encoded
+ )
+
+ subscriber!!.bankEncryptionPublicKey = SerialBlob(
+ CryptoUtil.loadRsaPublicKeyFromComponents(
+ data.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
+ data.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
+ ).encoded
+ )
}
call.respondText("Bank keys stored in database\n", ContentType.Text.Plain, HttpStatusCode.OK)
@@ -1039,72 +931,23 @@ fun main() {
post("/ebics/subscribers/{id}/sendHia") {
- val id = expectId(call.parameters["id"]) // caught above
+ val id = expectId(call.parameters["id"])
- val bundle = transaction {
- val subscriber = EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
- val tmpAiKey = CryptoUtil.loadRsaPrivateKey(subscriber.authenticationPrivateKey.toByteArray())
- val tmpEncKey = CryptoUtil.loadRsaPrivateKey(subscriber.encryptionPrivateKey.toByteArray())
-
- val hiaRequest = EbicsUnsecuredRequest().apply {
- version = "H004"
- revision = 1
- header = EbicsUnsecuredRequest.Header().apply {
- authenticate = true
- static = EbicsUnsecuredRequest.StaticHeaderType().apply {
- orderDetails = EbicsUnsecuredRequest.OrderDetails().apply {
- orderAttribute = "DZNNN"
- orderType = "HIA"
- securityMedium = "0000"
- hostID = subscriber.hostID
- userID = subscriber.userID
- partnerID = subscriber.partnerID
- systemID = subscriber.systemID
- }
- }
- mutable = EbicsUnsecuredRequest.Header.EmptyMutableHeader()
- }
- body = EbicsUnsecuredRequest.Body().apply {
- dataTransfer = EbicsUnsecuredRequest.UnsecuredDataTransfer().apply {
- orderData = EbicsUnsecuredRequest.OrderData().apply {
- value = EbicsOrderUtil.encodeOrderDataXml(
- HIARequestOrderData().apply {
- authenticationPubKeyInfo = EbicsTypes.AuthenticationPubKeyInfoType().apply {
- pubKeyValue = EbicsTypes.PubKeyValueType().apply {
- rsaKeyValue = RSAKeyValueType().apply {
- exponent = tmpAiKey.publicExponent.toByteArray()
- modulus = tmpAiKey.modulus.toByteArray()
- }
- }
- authenticationVersion = "X002"
- }
- encryptionPubKeyInfo = EbicsTypes.EncryptionPubKeyInfoType().apply {
- pubKeyValue = EbicsTypes.PubKeyValueType().apply {
- rsaKeyValue = RSAKeyValueType().apply {
- exponent = tmpEncKey.publicExponent.toByteArray()
- modulus = tmpEncKey.modulus.toByteArray()
- }
- }
- encryptionVersion = "E002"
-
- }
- partnerID = subscriber.partnerID
- userID = subscriber.userID
- }
- )
- }
- }
- }
- }
- EbicsContainer<EbicsUnsecuredRequest>(
- ebicsUrl = subscriber.ebicsURL,
- jaxb = hiaRequest
+ val subscriberData = transaction {
+ containerInit(
+ EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound)
)
}
val responseJaxb = client.postToBankUnsigned<EbicsUnsecuredRequest, EbicsKeyManagementResponse>(
- bundle.ebicsUrl!!,
- bundle.jaxb!!
+ subscriberData.ebicsUrl,
+ EbicsUnsecuredRequest.createHia(
+ subscriberData.hostId,
+ subscriberData.userId,
+ subscriberData.partnerId,
+ subscriberData.customerAuthPriv,
+ subscriberData.customerEncPriv
+ )
)
if (responseJaxb.value.body.returnCode.value != "000000") {
@@ -1114,7 +957,8 @@ fun main() {
call.respondText(
"Bank accepted authentication and encryption keys\n",
ContentType.Text.Plain,
- HttpStatusCode.OK)
+ HttpStatusCode.OK
+ )
return@post
}
diff --git a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsNpkdRequest.kt b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsNpkdRequest.kt
@@ -100,4 +100,36 @@ class EbicsNpkdRequest {
@XmlAccessorType(XmlAccessType.NONE)
class EmptyBody
+
+ companion object {
+ fun createRequest(
+ hostId: String,
+ partnerId: String,
+ userId: String,
+ aNonce: ByteArray,
+ date: XMLGregorianCalendar
+ ): EbicsNpkdRequest {
+ return EbicsNpkdRequest().apply {
+ version = "H004"
+ revision = 1
+ header = EbicsNpkdRequest.Header().apply {
+ authenticate = true
+ mutable = EbicsNpkdRequest.EmptyMutableHeader()
+ static = EbicsNpkdRequest.StaticHeaderType().apply {
+ hostID = hostId
+ partnerID = partnerId
+ userID = userId
+ securityMedium = "0000"
+ orderDetails = EbicsNpkdRequest.OrderDetails()
+ orderDetails.orderType = "HPB"
+ orderDetails.orderAttribute = "DZHNN"
+ nonce = aNonce
+ timestamp = date
+ }
+ }
+ body = EbicsNpkdRequest.EmptyBody()
+ authSignature = SignatureType()
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsRequest.kt b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsRequest.kt
@@ -153,7 +153,8 @@ class EbicsRequest {
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(
name = "",
- propOrder = ["orderType", "orderID", "orderAttribute", "orderParams"])
+ propOrder = ["orderType", "orderID", "orderAttribute", "orderParams"]
+ )
class OrderDetails {
@get:XmlElement(name = "OrderType", required = true)
@get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
@@ -177,7 +178,9 @@ class EbicsRequest {
@get:XmlElements(
XmlElement(
name = "StandardOrderParams",
- type = StandardOrderParams::class))
+ type = StandardOrderParams::class
+ )
+ )
var orderParams: OrderParams? = null
}
@@ -272,6 +275,88 @@ class EbicsRequest {
companion object {
+ fun createForDownloadReceiptPhase(
+ transactionId: String,
+ hostId: String
+
+ ): EbicsRequest {
+ return EbicsRequest().apply {
+ header = Header().apply {
+ version = "H004"
+ revision = 1
+ authenticate = true
+ static = StaticHeaderType().apply {
+ hostID = hostId
+ transactionID = transactionId
+ }
+ mutable = MutableHeader().apply {
+ transactionPhase = EbicsTypes.TransactionPhaseType.RECEIPT
+ }
+ }
+ authSignature = SignatureType()
+
+ body = Body().apply {
+ transferReceipt = TransferReceipt().apply {
+ authenticate = true
+ receiptCode = 0 // always true at this point.
+ }
+ }
+ }
+
+ }
+
+ fun createForDownloadInitializationPhase(
+ userId: String,
+ partnerId: String,
+ hostId: String,
+ nonceArg: ByteArray,
+ date: XMLGregorianCalendar,
+ bankEncPub: RSAPublicKey,
+ bankAuthPub: RSAPublicKey,
+ aOrderType: String
+
+ ): EbicsRequest {
+
+ return EbicsRequest().apply {
+ version = "H004"
+ revision = 1
+ authSignature = SignatureType()
+ body = Body()
+ header = Header().apply {
+ authenticate = true
+ static = EbicsRequest.StaticHeaderType().apply {
+ userID = userId
+ partnerID = partnerId
+ hostID = hostId
+ nonce = nonceArg
+ timestamp = date
+ partnerID = partnerId
+ orderDetails = EbicsRequest.OrderDetails().apply {
+ orderType = aOrderType
+ orderAttribute = "DZHNN"
+ orderParams = EbicsRequest.StandardOrderParams()
+ }
+ bankPubKeyDigests = EbicsRequest.BankPubKeyDigests().apply {
+ authentication = EbicsTypes.PubKeyDigest().apply {
+ algorithm = "http://www.w3.org/2001/04/xmlenc#sha256"
+ version = "X002"
+ value = CryptoUtil.getEbicsPublicKeyHash(bankAuthPub)
+ }
+ encryption = EbicsTypes.PubKeyDigest().apply {
+ algorithm = "http://www.w3.org/2001/04/xmlenc#sha256"
+ version = "E002"
+ value = CryptoUtil.getEbicsPublicKeyHash(bankEncPub)
+ }
+ securityMedium = "0000"
+ }
+ mutable = EbicsRequest.MutableHeader().apply {
+ transactionPhase = EbicsTypes.TransactionPhaseType.INITIALISATION
+ }
+ }
+ }
+ }
+ }
+
fun createForUploadInitializationPhase(
cryptoBundle: CryptoUtil.EncryptionResult,
hostId: String,
@@ -281,7 +366,8 @@ class EbicsRequest {
date: XMLGregorianCalendar,
bankAuthPub: RSAPublicKey,
bankEncPub: RSAPublicKey,
- segmentsNumber: BigInteger
+ segmentsNumber: BigInteger,
+ aOrderType: String
): EbicsRequest {
return EbicsRequest().apply {
@@ -296,7 +382,7 @@ class EbicsRequest {
partnerID = partnerId
userID = userId
orderDetails = EbicsRequest.OrderDetails().apply {
- orderType = "TST"
+ orderType = aOrderType
orderAttribute = "OZHNN"
orderParams = EbicsRequest.StandardOrderParams()
}
@@ -375,18 +461,6 @@ class EbicsRequest {
}
}
}
-
- fun createForDownloadInitializationPhase(): EbicsRequest {
-
- }
-
- fun createForDownloadTransferPhase(): EbicsRequest {
-
-
- }
-
- fun createForDownloadReceiptPhase(): EbicsRequest {
-
}
}
-}
+}
+\ No newline at end of file
diff --git a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsUnsecuredRequest.kt b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsUnsecuredRequest.kt
@@ -1,5 +1,9 @@
package tech.libeufin.schema.ebics_h004
+import org.apache.xml.security.binding.xmldsig.RSAKeyValueType
+import tech.libeufin.sandbox.EbicsOrderUtil
+import tech.libeufin.schema.ebics_s001.SignatureTypes
+import java.security.interfaces.RSAPrivateCrtKey
import javax.xml.bind.annotation.*
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter
@@ -102,4 +106,116 @@ class EbicsUnsecuredRequest {
@get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
lateinit var orderAttribute: String
}
+
+ companion object {
+
+ fun createHia(
+ hostId: String,
+ userId: String,
+ partnerId: String,
+ authKey: RSAPrivateCrtKey,
+ encKey: RSAPrivateCrtKey
+
+ ): EbicsUnsecuredRequest {
+
+ return EbicsUnsecuredRequest().apply {
+
+ version = "H004"
+ revision = 1
+ header = EbicsUnsecuredRequest.Header().apply {
+ authenticate = true
+ static = EbicsUnsecuredRequest.StaticHeaderType().apply {
+ orderDetails = EbicsUnsecuredRequest.OrderDetails().apply {
+ orderAttribute = "DZNNN"
+ orderType = "HIA"
+ securityMedium = "0000"
+ hostID = hostId
+ userID = userId
+ partnerID = partnerId
+ }
+ }
+ mutable = EbicsUnsecuredRequest.Header.EmptyMutableHeader()
+ }
+ body = EbicsUnsecuredRequest.Body().apply {
+ dataTransfer = EbicsUnsecuredRequest.UnsecuredDataTransfer().apply {
+ orderData = EbicsUnsecuredRequest.OrderData().apply {
+ value = EbicsOrderUtil.encodeOrderDataXml(
+ HIARequestOrderData().apply {
+ authenticationPubKeyInfo = EbicsTypes.AuthenticationPubKeyInfoType().apply {
+ pubKeyValue = EbicsTypes.PubKeyValueType().apply {
+ rsaKeyValue = RSAKeyValueType().apply {
+ exponent = authKey.publicExponent.toByteArray()
+ modulus = authKey.modulus.toByteArray()
+ }
+ }
+ authenticationVersion = "X002"
+ }
+ encryptionPubKeyInfo = EbicsTypes.EncryptionPubKeyInfoType().apply {
+ pubKeyValue = EbicsTypes.PubKeyValueType().apply {
+ rsaKeyValue = RSAKeyValueType().apply {
+ exponent = encKey.publicExponent.toByteArray()
+ modulus = encKey.modulus.toByteArray()
+ }
+ }
+ encryptionVersion = "E002"
+
+ }
+ partnerID = partnerId
+ userID = userId
+ }
+ )
+ }
+ }
+ }
+ }
+ }
+
+ fun createIni(
+ hostId: String,
+ userId: String,
+ partnerId: String,
+ signKey: RSAPrivateCrtKey
+
+ ): EbicsUnsecuredRequest {
+ return EbicsUnsecuredRequest().apply {
+ version = "H004"
+ revision = 1
+ header = EbicsUnsecuredRequest.Header().apply {
+ authenticate = true
+ static = EbicsUnsecuredRequest.StaticHeaderType().apply {
+ orderDetails = EbicsUnsecuredRequest.OrderDetails().apply {
+ orderAttribute = "DZNNN"
+ orderType = "INI"
+ securityMedium = "0000"
+ hostID = hostId
+ userID = userId
+ partnerID = partnerId
+ }
+ }
+ mutable = EbicsUnsecuredRequest.Header.EmptyMutableHeader()
+ }
+ body = Body().apply {
+ dataTransfer = EbicsUnsecuredRequest.UnsecuredDataTransfer().apply {
+ orderData = EbicsUnsecuredRequest.OrderData().apply {
+ value = EbicsOrderUtil.encodeOrderDataXml(
+ SignatureTypes.SignaturePubKeyOrderData().apply {
+ signaturePubKeyInfo = SignatureTypes.SignaturePubKeyInfoType().apply {
+ signatureVersion = "A006"
+ pubKeyValue = SignatureTypes.PubKeyValueType().apply {
+ rsaKeyValue = org.apache.xml.security.binding.xmldsig.RSAKeyValueType().apply {
+ exponent = signKey.publicExponent.toByteArray()
+ modulus = signKey.modulus.toByteArray()
+ }
+ }
+ }
+ userID = userId
+ partnerID = partnerId
+ }
+ )
+ }
+ }
+ }
+ }
+ }
+ }
}