gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated: Get upload TRANSACTION request to decr


From: gnunet
Subject: [libeufin] branch master updated: Get upload TRANSACTION request to decrypt.
Date: Tue, 19 Nov 2019 00:32:30 +0100

This is an automated email from the git hooks/post-receive script.

marcello pushed a commit to branch master
in repository libeufin.

The following commit(s) were added to refs/heads/master by this push:
     new aa9064a  Get upload TRANSACTION request to decrypt.
aa9064a is described below

commit aa9064ac730b0cb530e827f3244f77920114f155
Author: Marcello Stanisci <address@hidden>
AuthorDate: Tue Nov 19 00:30:28 2019 +0100

    Get upload TRANSACTION request to decrypt.
---
 nexus/src/main/kotlin/Main.kt                      | 63 ++++++++++++++++++++--
 .../kotlin/tech/libeufin/sandbox/CryptoUtil.kt     | 26 +++++++--
 .../tech/libeufin/sandbox/EbicsProtocolBackend.kt  |  2 +-
 .../libeufin/schema/ebics_h004/EbicsRequest.kt     |  2 +-
 .../libeufin/schema/ebics_h004/EbicsResponse.kt    | 16 ++----
 .../tech/libeufin/schema/ebics_h004/EbicsTypes.kt  | 11 ++++
 6 files changed, 97 insertions(+), 23 deletions(-)

diff --git a/nexus/src/main/kotlin/Main.kt b/nexus/src/main/kotlin/Main.kt
index 4c20aa6..86542d4 100644
--- a/nexus/src/main/kotlin/Main.kt
+++ b/nexus/src/main/kotlin/Main.kt
@@ -58,6 +58,7 @@ import java.security.SecureRandom
 import java.text.SimpleDateFormat
 import java.time.Instant.now
 import java.util.*
+import java.util.zip.DeflaterInputStream
 import java.util.zip.InflaterInputStream
 import javax.xml.datatype.DatatypeFactory
 import javax.xml.datatype.XMLGregorianCalendar
@@ -670,12 +671,14 @@ fun main() {
             post("/ebics/subscribers/{id}/sendTst") {
                 val id = expectId(call.parameters["id"])
 
-                val (url, doc) = transaction {
+                val innerPayload = "ES-PAYLOAD"
+
+                val (url, doc, transactionKey) = 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.digestEbicsA006(innerPayload.toByteArray()),
                         
CryptoUtil.loadRsaPrivateKey(subscriber.signaturePrivateKey.toByteArray())
                     )
 
@@ -767,12 +770,66 @@ fun main() {
                         doc,
                         
CryptoUtil.loadRsaPrivateKey(subscriber.authenticationPrivateKey.toByteArray())
                     )
-                    Pair(subscriber.ebicsURL, doc)
+                    Triple(subscriber.ebicsURL, doc, 
usd_encrypted.plainTransactionKey)
                 }
 
                 // send document here
                 val response = client.postToBank<EbicsResponse>(url, doc)
 
+                // MUST validate bank signature first (FIXME)
+                // MUST check that outcome is EBICS_OK (FIXME)
+
+                val (urlTransfer, docTransfer) = transaction {
+
+                    val subscriber = EbicsSubscriberEntity.findById(id) ?: 
throw SubscriberNotFoundError(HttpStatusCode.NotFound)
+
+                    val compressedInnerPayload = DeflaterInputStream(
+                        innerPayload.toByteArray().inputStream()
+
+                    ).use { it.readAllBytes() }
+
+                    val encryptedPayload = 
CryptoUtil.encryptEbicsE002withTransactionKey(
+                        compressedInnerPayload,
+                        
CryptoUtil.loadRsaPublicKey(subscriber.bankEncryptionPublicKey!!.toByteArray()),
+                        transactionKey!!
+                    )
+
+                    val tmp = EbicsRequest().apply {
+                        header = EbicsRequest.Header().apply {
+                            version = "H004"
+                            revision = 1
+                            authenticate = true
+                            static = EbicsRequest.StaticHeaderType().apply {
+                                hostID = subscriber.hostID
+                                transactionID = 
response.value.header._static.transactionID
+                            }
+                            mutable = EbicsRequest.MutableHeader().apply {
+                                transactionPhase = 
EbicsTypes.TransactionPhaseType.TRANSFER
+                                segmentNumber = 
EbicsTypes.SegmentNumber().apply {
+                                    lastSegment = true
+                                    value = BigInteger.ONE
+                                }
+                            }
+                        }
+
+                        authSignature = SignatureType()
+                        body = EbicsRequest.Body().apply {
+                            dataTransfer = EbicsRequest.DataTransfer().apply {
+                                orderData = encryptedPayload.encryptedData
+                            }
+                        }
+                    }
+
+                    val doc = XMLUtil.convertJaxbToDocument(tmp)
+                    XMLUtil.signEbicsDocument(
+                        doc,
+                        
CryptoUtil.loadRsaPrivateKey(subscriber.authenticationPrivateKey.toByteArray())
+                    )
+                    Pair(subscriber.ebicsURL, doc)
+                }
+
+                val responseTransaction = 
client.postToBank<EbicsResponse>(urlTransfer, docTransfer)
+
                 call.respondText(
                     "not implemented\n",
                     ContentType.Text.Plain,
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt
index 79ae3db..55ad1bd 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt
@@ -31,6 +31,7 @@ import java.security.interfaces.RSAPublicKey
 import java.security.spec.*
 import javax.crypto.Cipher
 import javax.crypto.KeyGenerator
+import javax.crypto.SecretKey
 import javax.crypto.spec.IvParameterSpec
 import javax.crypto.spec.SecretKeySpec
 
@@ -47,7 +48,12 @@ object CryptoUtil {
     class EncryptionResult(
         val encryptedTransactionKey: ByteArray,
         val pubKeyDigest: ByteArray,
-        val encryptedData: ByteArray
+        val encryptedData: ByteArray,
+
+        /**
+         * This key needs to be reused between different upload phases.
+         */
+        val plainTransactionKey: SecretKey? = null
     )
 
     private val bouncyCastleProvider = BouncyCastleProvider()
@@ -131,13 +137,22 @@ object CryptoUtil {
         return digest.digest(keyBytes.toByteArray())
     }
 
-    /**
-     * Encrypt data according to the EBICS E002 encryption process.
-     */
     fun encryptEbicsE002(data: ByteArray, encryptionPublicKey: RSAPublicKey): 
EncryptionResult {
         val keygen = KeyGenerator.getInstance("AES", bouncyCastleProvider)
         keygen.init(128)
         val transactionKey = keygen.generateKey()
+        return encryptEbicsE002withTransactionKey(data, encryptionPublicKey, 
transactionKey)
+    }
+
+    /**
+     * Encrypt data according to the EBICS E002 encryption process.
+     */
+    fun encryptEbicsE002withTransactionKey(
+        data: ByteArray,
+        encryptionPublicKey: RSAPublicKey,
+        transactionKey: SecretKey
+    ): EncryptionResult {
+
         val symmetricCipher = Cipher.getInstance("AES/CBC/X9.23Padding", 
bouncyCastleProvider)
         val ivParameterSpec = IvParameterSpec(ByteArray(16))
         symmetricCipher.init(Cipher.ENCRYPT_MODE, transactionKey, 
ivParameterSpec)
@@ -146,7 +161,7 @@ object CryptoUtil {
         asymmetricCipher.init(Cipher.ENCRYPT_MODE, encryptionPublicKey)
         val encryptedTransactionKey = 
asymmetricCipher.doFinal(transactionKey.encoded)
         val pubKeyDigest = getEbicsPublicKeyHash(encryptionPublicKey)
-        return EncryptionResult(encryptedTransactionKey, pubKeyDigest, 
encryptedData)
+        return EncryptionResult(encryptedTransactionKey, pubKeyDigest, 
encryptedData, transactionKey)
     }
 
     fun decryptEbicsE002(enc: EncryptionResult, privateKey: RSAPrivateCrtKey): 
ByteArray {
@@ -161,6 +176,7 @@ object CryptoUtil {
         val symmetricCipher = Cipher.getInstance("AES/CBC/X9.23Padding", 
bouncyCastleProvider)
         val ivParameterSpec = IvParameterSpec(ByteArray(16))
         symmetricCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, 
ivParameterSpec)
+        logger.debug("decrypting: ${encryptedData.toHexString()}")
         val data = symmetricCipher.doFinal(encryptedData)
         return data
     }
diff --git 
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 5ec537f..5eea9f5 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -649,7 +649,7 @@ suspend fun ApplicationCall.ebicsweb() {
                     EbicsTypes.TransactionPhaseType.TRANSFER -> {
                         requestTransactionID ?: throw 
EbicsInvalidRequestError()
                         val requestSegmentNumber =
-                            
requestObject.header.mutable.segmentNumber?.toInt() ?: throw 
EbicsInvalidRequestError()
+                            
requestObject.header.mutable.segmentNumber?.value?.toInt() ?: throw 
EbicsInvalidRequestError()
                         if (uploadTransaction != null) {
                             if (requestSegmentNumber == 1 && 
uploadTransaction.numSegments == 1) {
                                 val encOrderData =
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
index 0f5567f..ffe797d 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsRequest.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsRequest.kt
@@ -142,7 +142,7 @@ class EbicsRequest {
          * contains order data.
          */
         @get:XmlElement(name = "SegmentNumber")
-        var segmentNumber: BigInteger? = null
+        var segmentNumber: EbicsTypes.SegmentNumber? = null
 
     }
 
diff --git 
a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsResponse.kt 
b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsResponse.kt
index 1e088da..c2dc841 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsResponse.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsResponse.kt
@@ -68,7 +68,7 @@ class EbicsResponse {
         lateinit var transactionPhase: EbicsTypes.TransactionPhaseType
 
         @get:XmlElement(name = "SegmentNumber")
-        var segmentNumber: SegmentNumber? = null
+        var segmentNumber: EbicsTypes.SegmentNumber? = null
 
         @get:XmlElement(name = "OrderID")
         @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
@@ -86,16 +86,6 @@ class EbicsResponse {
         lateinit var reportText: String
     }
 
-    @XmlAccessorType(XmlAccessType.NONE)
-    @XmlType(name = "", propOrder = ["value"])
-    class SegmentNumber {
-        @XmlValue
-        lateinit var value: BigInteger
-
-        @XmlAttribute(name = "lastSegment")
-        var lastSegment: Boolean? = null
-    }
-
     @XmlAccessorType(XmlAccessType.NONE)
     class OrderData {
         @get:XmlValue
@@ -209,7 +199,7 @@ class EbicsResponse {
                     }
                     this.mutable = EbicsResponse.MutableHeaderType().apply {
                         this.transactionPhase = 
EbicsTypes.TransactionPhaseType.TRANSFER
-                        this.segmentNumber = 
EbicsResponse.SegmentNumber().apply {
+                        this.segmentNumber = EbicsTypes.SegmentNumber().apply {
                             this.value = 
BigInteger.valueOf(segmentNumber.toLong())
                             if (lastSegment) {
                                 this.lastSegment = true
@@ -248,7 +238,7 @@ class EbicsResponse {
                     }
                     this.mutable = EbicsResponse.MutableHeaderType().apply {
                         this.transactionPhase = 
EbicsTypes.TransactionPhaseType.INITIALISATION
-                        this.segmentNumber = 
EbicsResponse.SegmentNumber().apply {
+                        this.segmentNumber = EbicsTypes.SegmentNumber().apply {
                             this.lastSegment = (numSegments == 1)
                             this.value = BigInteger.valueOf(1)
                         }
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
index 8c9ff3f..092ded5 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsTypes.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsTypes.kt
@@ -21,6 +21,7 @@ package tech.libeufin.schema.ebics_h004
 
 import org.apache.xml.security.binding.xmldsig.RSAKeyValueType
 import org.w3c.dom.Element
+import java.math.BigInteger
 import java.util.*
 import javax.xml.bind.annotation.*
 import javax.xml.bind.annotation.adapters.CollapsedStringAdapter
@@ -52,6 +53,16 @@ object EbicsTypes {
         var instituteID: String? = null
     }
 
+    @XmlAccessorType(XmlAccessType.NONE)
+    @XmlType(name = "", propOrder = ["value"])
+    class SegmentNumber {
+        @XmlValue
+        lateinit var value: BigInteger
+
+        @XmlAttribute(name = "lastSegment")
+        var lastSegment: Boolean? = null
+    }
+
 
     @XmlType(name = "", propOrder = ["encryptionPubKeyDigest", 
"transactionKey"])
     @XmlAccessorType(XmlAccessType.NONE)

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]