libeufin

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

commit cc867f98a0f7034be6485d5b57dfda34ed5194e3
parent ff960f0b7d662df5c7cff890ceabfdae61c8c1e3
Author: Florian Dold <florian.dold@gmail.com>
Date:   Tue, 12 Nov 2019 15:17:34 +0100

EBICS VEU crypto WIP

Diffstat:
Mnexus/src/main/kotlin/Main.kt | 10++++------
Msandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt | 21++++++++++++++++++---
Msandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt | 5+++++
Msandbox/src/main/kotlin/tech/libeufin/schema/ebics_s001/UserSignatureData.kt | 22+++++++++++++++++++---
Msandbox/src/test/kotlin/CryptoUtilTest.kt | 8++++++++
5 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/nexus/src/main/kotlin/Main.kt b/nexus/src/main/kotlin/Main.kt @@ -46,13 +46,11 @@ import org.jetbrains.exposed.sql.transactions.transaction import org.slf4j.LoggerFactory import tech.libeufin.sandbox.* import tech.libeufin.schema.ebics_h004.* -import tech.libeufin.schema.ebics_s001.SignatureTypes.SignaturePubKeyInfoType -import tech.libeufin.schema.ebics_s001.SignatureTypes.SignaturePubKeyOrderData -import tech.libeufin.schema.ebics_s001.SignatureTypes.PubKeyValueType import java.text.DateFormat import javax.sql.rowset.serial.SerialBlob import javax.xml.bind.JAXBElement import org.w3c.dom.Document +import tech.libeufin.schema.ebics_s001.SignatureTypes import java.security.SecureRandom import java.util.* import java.util.zip.InflaterInputStream @@ -514,10 +512,10 @@ fun main() { dataTransfer = EbicsUnsecuredRequest.UnsecuredDataTransfer().apply { orderData = EbicsUnsecuredRequest.OrderData().apply { value = EbicsOrderUtil.encodeOrderDataXml( - SignaturePubKeyOrderData().apply { - signaturePubKeyInfo = SignaturePubKeyInfoType().apply { + SignatureTypes.SignaturePubKeyOrderData().apply { + signaturePubKeyInfo = SignatureTypes.SignaturePubKeyInfoType().apply { signatureVersion = "A006" - pubKeyValue = PubKeyValueType().apply { + pubKeyValue = SignatureTypes.PubKeyValueType().apply { rsaKeyValue = org.apache.xml.security.binding.xmldsig.RSAKeyValueType().apply { exponent = tmpKey.publicExponent.toByteArray() modulus = tmpKey.modulus.toByteArray() diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt @@ -25,11 +25,10 @@ import java.math.BigInteger import java.security.KeyFactory import java.security.KeyPairGenerator import java.security.MessageDigest +import java.security.Signature import java.security.interfaces.RSAPrivateCrtKey import java.security.interfaces.RSAPublicKey -import java.security.spec.PKCS8EncodedKeySpec -import java.security.spec.RSAPublicKeySpec -import java.security.spec.X509EncodedKeySpec +import java.security.spec.* import javax.crypto.Cipher import javax.crypto.KeyGenerator import javax.crypto.spec.IvParameterSpec @@ -165,4 +164,20 @@ object CryptoUtil { val data = symmetricCipher.doFinal(encryptedData) return data } + + fun signEbicsA006(data: ByteArray, privateKey: RSAPrivateCrtKey): ByteArray { + val signature = Signature.getInstance("SHA256withRSA/PSS", bouncyCastleProvider) + signature.setParameter(PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1)) + signature.initSign(privateKey) + signature.update(data) + return signature.sign() + } + + fun verifyEbicsA006(sig: ByteArray, data: ByteArray, publicKey: RSAPublicKey): Boolean { + val signature = Signature.getInstance("SHA256withRSA/PSS", bouncyCastleProvider) + signature.setParameter(PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1)) + signature.initVerify(publicKey) + signature.update(data) + return signature.verify(sig) + } } diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt @@ -34,6 +34,7 @@ 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.SignatureTypes +import tech.libeufin.schema.ebics_s001.UserSignatureData import java.security.interfaces.RSAPrivateCrtKey import java.util.* import java.util.zip.DeflaterInputStream @@ -603,6 +604,10 @@ suspend fun ApplicationCall.ebicsweb() { } //val sigDataObject = XMLUtil.convertStringToJaxb<OrderSignatureData>(plainSigData) println("signature data: ${plainSigData.toString(Charsets.UTF_8)}") + + val sig = XMLUtil.convertStringToJaxb<UserSignatureData>(plainSigData.toString(Charsets.UTF_8)) + val sigVal = sig.value.orderSignatureList?.get(0)?.signatureValue + println("creating upload transaction for transactionID $transactionID") EbicsUploadTransactionEntity.new(transactionID) { this.host = ebicsHost diff --git a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_s001/UserSignatureData.kt b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_s001/UserSignatureData.kt @@ -1,11 +1,27 @@ package tech.libeufin.schema.ebics_s001 -import javax.xml.bind.annotation.XmlAccessType -import javax.xml.bind.annotation.XmlAccessorType -import javax.xml.bind.annotation.XmlRootElement +import javax.xml.bind.annotation.* @XmlAccessorType(XmlAccessType.NONE) @XmlRootElement(name = "UserSignatureData") +@XmlType(name = "", propOrder = ["orderSignatureList"]) class UserSignatureData { + @XmlElement(name = "OrderSignature", type = OrderSignatureData::class) + var orderSignatureList: List<OrderSignatureData>? = null + @XmlAccessorType(XmlAccessType.NONE) + @XmlType(name = "", propOrder = ["signatureVersion", "signatureValue", "partnerID", "customerID"]) + class OrderSignatureData { + @XmlElement(name = "SignatureVersion") + lateinit var signatureVersion: String + + @XmlElement(name = "SignatureValue") + lateinit var signatureValue: ByteArray + + @XmlElement(name = "PartnerID") + lateinit var partnerID: String + + @XmlElement(name = "CustomerID") + lateinit var customerID: String + } } \ No newline at end of file diff --git a/sandbox/src/test/kotlin/CryptoUtilTest.kt b/sandbox/src/test/kotlin/CryptoUtilTest.kt @@ -66,4 +66,12 @@ class CryptoUtilTest { val dec = CryptoUtil.decryptEbicsE002(enc, keyPair.private) assertTrue(data.contentEquals(dec)) } + + @Test + fun testEbicsE006() { + val keyPair = CryptoUtil.generateRsaKeyPair(1024) + val data = "Hello, World".toByteArray(Charsets.UTF_8) + val sig = CryptoUtil.signEbicsA006(data, keyPair.private) + assertTrue(CryptoUtil.verifyEbicsA006(sig, data, keyPair.public)) + } } \ No newline at end of file