libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit 106c02fbf8c55376ac94575854de8c0134c387cb
parent f6e7b7c1f314f4783f213e65dd23856f5a8a68ad
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Fri, 15 Nov 2019 20:41:53 +0100

crafting TST upload order

Diffstat:
Mnexus/src/main/kotlin/Main.kt | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anexus/src/test/kotlin/SignatureDataTest.kt | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsRequest.kt | 4++--
Msandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsTypes.kt | 1-
4 files changed, 190 insertions(+), 3 deletions(-)

diff --git a/nexus/src/main/kotlin/Main.kt b/nexus/src/main/kotlin/Main.kt @@ -52,6 +52,8 @@ import javax.sql.rowset.serial.SerialBlob import javax.xml.bind.JAXBElement import org.w3c.dom.Document import tech.libeufin.schema.ebics_s001.SignatureTypes +import tech.libeufin.schema.ebics_s001.UserSignatureData +import java.math.BigInteger import java.security.SecureRandom import java.text.SimpleDateFormat import java.time.Instant.now @@ -667,6 +669,114 @@ fun main() { post("/ebics/subscribers/{id}/sync") { val id = expectId(call.parameters["id"]) + + val (url, doc) = transaction { + val subscriber = EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound) + + // first prepare ES content + val ES_signature = CryptoUtil.signEbicsA006( + CryptoUtil.digestEbicsA006("ES-PAYLOAD".toByteArray()), + CryptoUtil.loadRsaPrivateKey(subscriber.signaturePrivateKey.toByteArray()) + ) + + val userSignatureData = UserSignatureData().apply { + orderSignatureList = listOf( + UserSignatureData.OrderSignatureData().apply { + signatureVersion = "A006" + signatureValue = ES_signature + partnerID = subscriber.partnerID + userID = subscriber.userID + } + ) + } + + println("inner ES is: ${XMLUtil.convertJaxbToString(userSignatureData)}") + + val usd_compressed = EbicsOrderUtil.encodeOrderDataXml(userSignatureData) + val usd_encrypted = CryptoUtil.encryptEbicsE002( + usd_compressed, + CryptoUtil.loadRsaPublicKey(subscriber.bankEncryptionPublicKey!!.toByteArray() + ) + ) + + val tmp = EbicsRequest().apply { + header = EbicsRequest.Header().apply { + version = "H004" + revision = 1 + authenticate = true + static = EbicsRequest.StaticHeaderType().apply { + hostID = subscriber.hostID + nonce = getNonce(128) + timestamp = getGregorianDate() + partnerID = subscriber.partnerID + userID = subscriber.userID + orderDetails = EbicsRequest.OrderDetails().apply { + orderType = "TST" + orderAttribute = "OZHNN" + } + 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!!.toByteArray()) + ) + } + encryption = EbicsTypes.PubKeyDigest().apply { + algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" + version = "E002" + value = CryptoUtil.getEbicsPublicKeyHash( + CryptoUtil.loadRsaPublicKey(subscriber.bankEncryptionPublicKey!!.toByteArray()) + + ) + } + } + securityMedium = "0000" + numSegments = BigInteger.ONE + + authSignature = SignatureType() + } + mutable = EbicsRequest.MutableHeader().apply { + transactionPhase = EbicsTypes.TransactionPhaseType.INITIALISATION + } + body = EbicsRequest.Body().apply { + dataTransfer = EbicsRequest.DataTransfer().apply { + signatureData = EbicsRequest.SignatureData().apply { + authenticate = true + value = usd_encrypted.encryptedData + } + dataEncryptionInfo = EbicsTypes.DataEncryptionInfo().apply { + transactionKey = usd_encrypted.encryptedTransactionKey + authenticate = true + encryptionPubKeyDigest = EbicsTypes.PubKeyDigest().apply { + algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" + version = "E002" + value = CryptoUtil.getEbicsPublicKeyHash( + CryptoUtil.loadRsaPublicKey( + subscriber.bankEncryptionPublicKey!!.toByteArray() + ) + ) + } + } + hostId = subscriber.hostID + } + } + } + } + + val doc = XMLUtil.convertJaxbToDocument(tmp) + XMLUtil.signEbicsDocument( + doc, + CryptoUtil.loadRsaPrivateKey(subscriber.authenticationPrivateKey.toByteArray()) + ) + Pair(subscriber.ebicsURL, doc) + } + + // send document here + } + + post("/ebics/subscribers/{id}/sync") { + val id = expectId(call.parameters["id"]) val (url, body, encPrivBlob) = transaction { val subscriber = EbicsSubscriberEntity.findById(id) ?: throw SubscriberNotFoundError(HttpStatusCode.NotFound) val hpbRequest = EbicsNpkdRequest().apply { diff --git a/nexus/src/test/kotlin/SignatureDataTest.kt b/nexus/src/test/kotlin/SignatureDataTest.kt @@ -0,0 +1,77 @@ +package tech.libeufin.nexus + +import okio.internal.commonAsUtf8ToByteArray +import tech.libeufin.sandbox.XMLUtil +import org.apache.xml.security.binding.xmldsig.SignatureType +import org.junit.Test +import tech.libeufin.sandbox.CryptoUtil +import tech.libeufin.schema.ebics_h004.EbicsRequest +import tech.libeufin.schema.ebics_h004.EbicsTypes +import java.math.BigInteger + +class SignatureDataTest { + + @Test + fun makeSignatureData() { + + val pair = CryptoUtil.generateRsaKeyPair(1024) + + val tmp = EbicsRequest().apply { + header = EbicsRequest.Header().apply { + version = "H004" + revision = 1 + authenticate = true + static = EbicsRequest.StaticHeaderType().apply { + hostID = "some host ID" + nonce = getNonce(128) + timestamp = getGregorianDate() + partnerID = "some partner ID" + userID = "some user ID" + orderDetails = EbicsRequest.OrderDetails().apply { + orderType = "TST" + orderAttribute = "OZHNN" + } + bankPubKeyDigests = EbicsRequest.BankPubKeyDigests().apply { + authentication = EbicsTypes.PubKeyDigest().apply { + algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" + version = "X002" + value = CryptoUtil.getEbicsPublicKeyHash(pair.public) + } + encryption = EbicsTypes.PubKeyDigest().apply { + algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" + version = "E002" + value = CryptoUtil.getEbicsPublicKeyHash(pair.public) + } + } + securityMedium = "0000" + numSegments = BigInteger.ONE + + authSignature = SignatureType() + } + mutable = EbicsRequest.MutableHeader().apply { + transactionPhase = EbicsTypes.TransactionPhaseType.INITIALISATION + } + body = EbicsRequest.Body().apply { + dataTransfer = EbicsRequest.DataTransfer().apply { + signatureData = EbicsRequest.SignatureData().apply { + authenticate = true + value = "to byte array".toByteArray() + } + dataEncryptionInfo = EbicsTypes.DataEncryptionInfo().apply { + transactionKey = "mock".toByteArray() + authenticate = true + encryptionPubKeyDigest = EbicsTypes.PubKeyDigest().apply { + algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" + version = "E002" + value = CryptoUtil.getEbicsPublicKeyHash(pair.public) + } + } + hostId = "a host ID" + } + } + } + } + + println(XMLUtil.convertJaxbToString(tmp)) + } +} +\ 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 @@ -200,7 +200,7 @@ class EbicsRequest { } @XmlAccessorType(XmlAccessType.NONE) - class SignatureDataType { + class SignatureData { @get:XmlAttribute(name = "authenticate", required = true) var authenticate: Boolean = false @@ -217,7 +217,7 @@ class EbicsRequest { var dataEncryptionInfo: EbicsTypes.DataEncryptionInfo? = null @get:XmlElement(name = "SignatureData") - var signatureData: SignatureDataType? = null + var signatureData: SignatureData? = null @get:XmlElement(name = "OrderData") var orderData: ByteArray? = null diff --git a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsTypes.kt b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsTypes.kt @@ -243,7 +243,6 @@ object EbicsTypes { @get:XmlElement(name = "NumSigRequired") var numSigRequired: Int? = null - } @XmlAccessorType(XmlAccessType.NONE)