[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: Get upload TRANSACTION request to decrypt.,
gnunet <=