gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] branch master updated (43fa22d -> bd6cbe4)


From: gnunet
Subject: [libeufin] branch master updated (43fa22d -> bd6cbe4)
Date: Thu, 31 Oct 2019 19:01:23 +0100

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

dold pushed a change to branch master
in repository libeufin.

    from 43fa22d  crypto utils
     new 7db6c2a  crypto util test
     new bd6cbe4  database rework, make INI succeed

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 sandbox/build.gradle                               |   2 +-
 sandbox/src/main/kotlin/CryptoUtil.kt              |  37 +-
 sandbox/src/main/kotlin/DB.kt                      | 172 +++-----
 sandbox/src/main/kotlin/JSON.kt                    |  46 +-
 sandbox/src/main/kotlin/Main.kt                    | 491 ++++++++-------------
 sandbox/src/main/kotlin/ProtocolAndVersion.kt      |   6 -
 .../libeufin/schema/ebics_h004/EbicsMessages.kt    | 239 ++++++----
 sandbox/src/test/kotlin/CryptoUtilTest.kt          |  59 +++
 sandbox/src/test/kotlin/DbTest.kt                  |  65 ---
 sandbox/src/test/kotlin/GeneratePrivateKeyTest.kt  |  28 --
 sandbox/src/test/kotlin/HiaLoadTest.kt             |   2 +-
 sandbox/src/test/kotlin/InnerIniLoadTest.kt        |  27 +-
 sandbox/src/test/kotlin/JaxbTest.kt                |  27 ++
 .../test/resources/ebics_ini_request_sample.xml    |  58 +--
 .../resources/ebics_ini_request_sample_patched.xml |  21 -
 .../test/resources/{HIA.xml => hia_request.xml}    |   0
 .../src/test/resources/hia_request_order_data.xml  |  23 +
 .../test/resources/{HPB.xml => hpb_request.xml}    |   0
 18 files changed, 635 insertions(+), 668 deletions(-)
 delete mode 100644 sandbox/src/main/kotlin/ProtocolAndVersion.kt
 create mode 100644 sandbox/src/test/kotlin/CryptoUtilTest.kt
 delete mode 100644 sandbox/src/test/kotlin/DbTest.kt
 delete mode 100644 sandbox/src/test/kotlin/GeneratePrivateKeyTest.kt
 delete mode 100644 
sandbox/src/test/resources/ebics_ini_request_sample_patched.xml
 rename sandbox/src/test/resources/{HIA.xml => hia_request.xml} (100%)
 create mode 100644 sandbox/src/test/resources/hia_request_order_data.xml
 rename sandbox/src/test/resources/{HPB.xml => hpb_request.xml} (100%)

diff --git a/sandbox/build.gradle b/sandbox/build.gradle
index 47b2e0b..04cb301 100644
--- a/sandbox/build.gradle
+++ b/sandbox/build.gradle
@@ -28,7 +28,7 @@ dependencies {
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
     implementation "io.ktor:ktor-gson:1.1.5"
     compile group: 'io.ktor', name: 'ktor-gson', version: '0.9.0'
-    compile "org.jetbrains.exposed:exposed:0.17.3"
+    compile "org.jetbrains.exposed:exposed:0.17.6"
     compile "io.ktor:ktor-server-netty:1.2.4"
     compile "ch.qos.logback:logback-classic:1.2.3"
     compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
diff --git a/sandbox/src/main/kotlin/CryptoUtil.kt 
b/sandbox/src/main/kotlin/CryptoUtil.kt
index fb72d09..20f5d52 100644
--- a/sandbox/src/main/kotlin/CryptoUtil.kt
+++ b/sandbox/src/main/kotlin/CryptoUtil.kt
@@ -20,8 +20,10 @@
 package tech.libeufin.sandbox
 
 import java.lang.Exception
+import java.math.BigInteger
 import java.security.KeyFactory
 import java.security.KeyPairGenerator
+import java.security.PublicKey
 import java.security.interfaces.RSAPrivateCrtKey
 import java.security.interfaces.RSAPublicKey
 import java.security.spec.PKCS8EncodedKeySpec
@@ -38,6 +40,9 @@ data class RsaCrtKeyPair(val private: RSAPrivateCrtKey, val 
public: RSAPublicKey
  */
 class CryptoUtil {
     companion object {
+        /**
+         * Load an RSA private key from its binary PKCS#8 encoding.
+         */
         fun loadRsaPrivateKey(encodedPrivateKey: ByteArray): RSAPrivateCrtKey {
             val spec = PKCS8EncodedKeySpec(encodedPrivateKey)
             val priv = KeyFactory.getInstance("RSA").generatePrivate(spec)
@@ -45,6 +50,10 @@ class CryptoUtil {
                 throw Exception("wrong encoding")
             return priv
         }
+
+        /**
+         * Load an RSA public key from its binary X509 encoding.
+         */
         fun loadRsaPublicKey(encodedPublicKey: ByteArray): RSAPublicKey {
             val spec = X509EncodedKeySpec(encodedPublicKey)
             val pub = KeyFactory.getInstance("RSA").generatePublic(spec)
@@ -52,6 +61,10 @@ class CryptoUtil {
                 throw Exception("wrong encoding")
             return pub
         }
+
+        /**
+         * Load an RSA public key from its binary X509 encoding.
+         */
         fun getRsaPublicFromPrivate(rsaPrivateCrtKey: RSAPrivateCrtKey): 
RSAPublicKey {
             val spec = RSAPublicKeySpec(rsaPrivateCrtKey.modulus, 
rsaPrivateCrtKey.publicExponent)
             val pub = KeyFactory.getInstance("RSA").generatePublic(spec)
@@ -59,6 +72,12 @@ class CryptoUtil {
                 throw Exception("wrong encoding")
             return pub
         }
+
+        /**
+         * Generate a fresh RSA key pair.
+         *
+         * @param nbits size of the modulus in bits
+         */
         fun generateRsaKeyPair(nbits: Int): RsaCrtKeyPair {
             val gen = KeyPairGenerator.getInstance("RSA")
             gen.initialize(nbits)
@@ -71,5 +90,21 @@ class CryptoUtil {
                 throw Exception("key generation failed")
             return RsaCrtKeyPair(priv, pub)
         }
+
+        /**
+         * Load an RSA public key from its components.
+         *
+         * @param exponent
+         * @param modulus
+         * @return key
+         */
+        fun loadRsaPublicKeyFromComponents(modulus: ByteArray, exponent: 
ByteArray): RSAPublicKey {
+            val modulusBigInt = BigInteger(1, modulus)
+            val exponentBigInt = BigInteger(1, exponent)
+
+            val keyFactory = KeyFactory.getInstance("RSA")
+            val tmp = RSAPublicKeySpec(modulusBigInt, exponentBigInt)
+            return keyFactory.generatePublic(tmp) as RSAPublicKey
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/sandbox/src/main/kotlin/DB.kt b/sandbox/src/main/kotlin/DB.kt
index 654e17b..ca95151 100644
--- a/sandbox/src/main/kotlin/DB.kt
+++ b/sandbox/src/main/kotlin/DB.kt
@@ -1,3 +1,22 @@
+/*
+ * This file is part of LibEuFin.
+ * Copyright (C) 2019 Stanisci and Dold.
+
+ * LibEuFin is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation; either version 3, or
+ * (at your option) any later version.
+
+ * LibEuFin is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
+ * Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public
+ * License along with LibEuFin; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>
+ */
+
 package tech.libeufin.sandbox.db
 
 import org.jetbrains.exposed.dao.*
@@ -5,18 +24,14 @@ import org.jetbrains.exposed.sql.*
 import org.jetbrains.exposed.sql.transactions.transaction
 
 const val CUSTOMER_NAME_MAX_LENGTH = 20
+const val EBICS_HOST_ID_MAX_LENGTH = 10
 const val EBICS_USER_ID_MAX_LENGTH = 10
 const val EBICS_PARTNER_ID_MAX_LENGTH = 10
 const val EBICS_SYSTEM_ID_MAX_LENGTH = 10
-const val PUBLIC_KEY_MAX_MODULUS_LENGTH = 2048 // FIXME review this value!
-const val PUBLIC_KEY_MAX_EXPONENT_LENGTH = 64 // FIXME review this value!
-const val PRIVATE_KEY_MODULUS_LENGTH = 1024 // FIXME review this value!
-const val PRIVATE_KEY_EXPONENT_LENGTH = 10
-
 /**
  * All the states to give a subscriber.
  */
-enum class SubscriberStates {
+enum class SubscriberState {
     /**
      * No keys at all given to the bank.
      */
@@ -27,7 +42,7 @@ enum class SubscriberStates {
      */
     PARTIALLY_INITIALIZED_INI,
 
-    /**
+    /**r
      * Only HIA electronic message was successfully sent.
      */
     PARTIALLY_INITIALIZED_HIA,
@@ -47,7 +62,7 @@ enum class SubscriberStates {
 /**
  * All the states that one key can be assigned.
  */
-enum class KeyStates {
+enum class KeyState {
 
     /**
      * The key was never communicated.
@@ -83,89 +98,42 @@ class BankCustomer(id: EntityID<Int>) : IntEntity(id) {
     var ebicsSubscriber by EbicsSubscriber referencedOn 
BankCustomers.ebicsSubscriber
 }
 
-/**
- * The following tables define IDs that make a EBCIS
- * 'subscriber' exist.  Each EBICS subscriber is the tuple:
- *
- * - UserID, the human who is performing a EBICS task.
- * - PartnerID, the legal entity that signed a formal agreement with the 
financial institution.
- * - SystemID, (optional) the machine that is handling the EBICS task on 
behalf of the UserID.
- */
-
-object EbicsUsers: IntIdTable() {
-    /* EBICS user ID in the string form. */
-    val userId = varchar("userId", 
EBICS_USER_ID_MAX_LENGTH).primaryKey().nullable()
-
-}
-
-class EbicsUser(id: EntityID<Int>) : IntEntity(id){
-    companion object : IntEntityClass<EbicsUser>(EbicsUsers) {
-        override fun new(init: EbicsUser.() -> Unit): EbicsUser {
-            var row = super.new(init)
-            row.userId = "u${row.id}"
-            return row
-        }
-    }
-    var userId by EbicsUsers.userId
-}
 
 /**
- * Table for UserID.
+ * This table stores RSA public keys of subscribers.
  */
-object EbicsPartners: IntIdTable() {
-    val partnerId = varchar("partnerId", 
EBICS_PARTNER_ID_MAX_LENGTH).primaryKey().nullable()
-}
-
-
-class EbicsPartner(id: EntityID<Int>) : IntEntity(id) {
-    companion object : IntEntityClass<EbicsPartner>(EbicsPartners) {
-        override fun new(init: EbicsPartner.() -> Unit): EbicsPartner {
-            var row = super.new(init)
-            row.partnerId = "p${row.id}"
-            return row
-        }
-    }
-    var partnerId by EbicsPartners.partnerId
+object EbicsPublicKeys : IntIdTable() {
+    val rsaPublicKey = blob("rsaPublicKey")
+    val state = enumeration("state", KeyState::class)
 }
 
 
 /**
- * Table for UserID.
+ * Definition of a row in the [EbicsPublicKey] table
  */
-object EbicsSystems: IntIdTable() {
-    val systemId = EbicsPartners.varchar("systemId", 
EBICS_SYSTEM_ID_MAX_LENGTH).nullable()
+class EbicsPublicKey(id: EntityID<Int>) : IntEntity(id) {
+    companion object : IntEntityClass<EbicsPublicKey>(EbicsPublicKeys)
+    var rsaPublicKey by EbicsPublicKeys.rsaPublicKey
+    var state by EbicsPublicKeys.state
 }
 
-class EbicsSystem(id: EntityID<Int>) : IntEntity(id) {
-    companion object : IntEntityClass<EbicsSystem>(EbicsSystems) {
-        override fun new(init: EbicsSystem.() -> Unit): EbicsSystem {
-            val row = super.new(init)
-            row.systemId = "s${row.id}"
-            return row
-        }
-    }
-
-    var systemId by EbicsSystems.systemId
-}
 
-/**
- * This table stores RSA public keys.
- */
-object EbicsPublicKeys: IntIdTable() {
-    val modulus = binary("modulus", PUBLIC_KEY_MAX_MODULUS_LENGTH)
-    val exponent = binary("exponent", PUBLIC_KEY_MAX_EXPONENT_LENGTH)
-    val state = enumeration("state", KeyStates::class)
+object EbicsHosts : IntIdTable() {
+    val hostID = text("hostID")
+    val ebicsVersion = text("ebicsVersion")
+    val signaturePrivateKey = blob("signaturePrivateKey")
+    val encryptionPrivateKey = blob("encryptionPrivateKey")
+    val authenticationPrivateKey = blob("authenticationPrivateKey")
 }
 
 
-/**
- * Definition of a row in the keys table
- */
-class EbicsPublicKey(id: EntityID<Int>) : IntEntity(id) {
-    companion object : IntEntityClass<EbicsPublicKey>(EbicsPublicKeys)
-    var modulus by EbicsPublicKeys.modulus
-    var exponent by EbicsPublicKeys.exponent
-    var state by EbicsPublicKeys.state
+class EbicsHost(id: EntityID<Int>) : IntEntity(id) {
+    companion object : IntEntityClass<EbicsHost>(EbicsHosts)
+    var hostId by EbicsHosts.hostID
+    var ebicsVersion by EbicsHosts.ebicsVersion
+    var signaturePrivateKey by EbicsHosts.signaturePrivateKey
+    var encryptionPrivateKey by EbicsHosts.encryptionPrivateKey
+    var authenticationPrivateKey by EbicsHosts.authenticationPrivateKey
 }
 
 /**
@@ -173,60 +141,31 @@ class EbicsPublicKey(id: EntityID<Int>) : IntEntity(id) {
  * and systems.  Each value can appear multiple times in the same column.
  */
 object EbicsSubscribers: IntIdTable() {
-
-    val userId = reference("userId", EbicsUsers)
-    val partnerId = reference("partnerId", EbicsPartners)
-    val systemId = reference("systemId", EbicsSystems)
+    val userId = text("userID")
+    val partnerId = text("partnerID")
+    val systemId = text("systemID").nullable()
 
     val signatureKey = reference("signatureKey", EbicsPublicKeys).nullable()
     val encryptionKey = reference("encryptionKey", EbicsPublicKeys).nullable()
     val authenticationKey = reference("authorizationKey", 
EbicsPublicKeys).nullable()
 
-    val state = enumeration("state", SubscriberStates::class)
+    val state = enumeration("state", SubscriberState::class)
 }
 
 class EbicsSubscriber(id: EntityID<Int>) : IntEntity(id) {
     companion object : IntEntityClass<EbicsSubscriber>(EbicsSubscribers)
 
-    var userId by EbicsUser referencedOn EbicsSubscribers.userId
-    var partnerId by EbicsPartner referencedOn EbicsSubscribers.partnerId
-    var systemId by EbicsSystem referencedOn EbicsSubscribers.systemId
+    var userId by EbicsSubscribers.userId
+    var partnerId by EbicsSubscribers.partnerId
+    var systemId by EbicsSubscribers.systemId
 
     var signatureKey by EbicsPublicKey optionalReferencedOn 
EbicsSubscribers.signatureKey
     var encryptionKey by EbicsPublicKey optionalReferencedOn 
EbicsSubscribers.encryptionKey
     var authenticationKey by EbicsPublicKey optionalReferencedOn 
EbicsSubscribers.authenticationKey
-    var state by EbicsSubscribers.state
-}
-
-/**
- * Helper function that makes a new subscriber
- * @return new object
- */
-fun createSubscriber() : EbicsSubscriber {
-
-    return EbicsSubscriber.new {
-        userId = EbicsUser.new { }
-        partnerId = EbicsPartner.new { }
-        systemId = EbicsSystem.new { }
-        state = SubscriberStates.NEW
-    }
-}
-
 
-/**
- * This table stores RSA private keys.
- */
-object EbicsBankPrivateKeys: IntIdTable() {
-    val modulus = binary("modulus", PRIVATE_KEY_MODULUS_LENGTH)
-    val exponent = binary("exponent", PRIVATE_KEY_EXPONENT_LENGTH)
+    var state by EbicsSubscribers.state
 }
 
-class EbicsBankPrivateKey(id: EntityID<Int>) : IntEntity(id) {
-    companion object : 
IntEntityClass<EbicsBankPrivateKey>(EbicsBankPrivateKeys)
-
-    var modulus by EbicsBankPrivateKeys.modulus
-    var exponent by EbicsBankPrivateKeys.exponent
-}
 
 fun dbCreateTables() {
     Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", driver = 
"org.h2.Driver")
@@ -236,11 +175,8 @@ fun dbCreateTables() {
 
         SchemaUtils.create(
             BankCustomers,
-            EbicsUsers,
-            EbicsPartners,
-            EbicsSystems,
             EbicsSubscribers,
-            EbicsBankPrivateKeys
+            EbicsHosts
         )
     }
 }
diff --git a/sandbox/src/main/kotlin/JSON.kt b/sandbox/src/main/kotlin/JSON.kt
index 86a9629..157db79 100644
--- a/sandbox/src/main/kotlin/JSON.kt
+++ b/sandbox/src/main/kotlin/JSON.kt
@@ -1,3 +1,22 @@
+/*
+ * This file is part of LibEuFin.
+ * Copyright (C) 2019 Stanisci and Dold.
+
+ * LibEuFin is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation; either version 3, or
+ * (at your option) any later version.
+
+ * LibEuFin is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
+ * Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public
+ * License along with LibEuFin; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>
+ */
+
 package tech.libeufin.sandbox
 
 /**
@@ -44,7 +63,6 @@ data class IniHiaLetters(
  * Request for INI letter.
  */
 data class IniLetter(
-
     val userId: String,
     val customerId: String,
     val name: String,
@@ -79,3 +97,29 @@ data class HiaLetter(
     val enc_public_modulus: String,
     val enc_hash: String
 )
+
+data class EbicsSubscribersResponse(
+    val subscribers: List<String>
+)
+
+data class EbicsSubscriberResponse(
+    val id: String,
+    val partnerID: String,
+    val userID: String,
+    val systemID: String?,
+    val state: String
+)
+
+data class EbicsHostsResponse(
+    val ebicsHosts: List<String>
+)
+
+data class EbicsHostResponse(
+    val hostID: String,
+    val ebicsVersion: String
+)
+
+data class EbicsHostCreateRequest(
+    val hostID: String,
+    val ebicsVersion: String
+)
\ No newline at end of file
diff --git a/sandbox/src/main/kotlin/Main.kt b/sandbox/src/main/kotlin/Main.kt
index b970a60..6b94078 100644
--- a/sandbox/src/main/kotlin/Main.kt
+++ b/sandbox/src/main/kotlin/Main.kt
@@ -20,15 +20,18 @@
 package tech.libeufin.sandbox
 
 import io.ktor.application.ApplicationCall
+import io.ktor.application.ApplicationCallPipeline
 import io.ktor.application.call
 import io.ktor.application.install
 import io.ktor.features.CallLogging
 import io.ktor.features.ContentNegotiation
+import io.ktor.features.StatusPages
 import io.ktor.gson.gson
 import io.ktor.http.ContentType
 import io.ktor.http.HttpStatusCode
 import io.ktor.request.receive
 import io.ktor.request.receiveText
+import io.ktor.request.uri
 import io.ktor.response.respond
 import io.ktor.response.respondText
 import io.ktor.routing.get
@@ -36,285 +39,86 @@ import io.ktor.routing.post
 import io.ktor.routing.routing
 import io.ktor.server.engine.embeddedServer
 import io.ktor.server.netty.Netty
-import org.jetbrains.exposed.dao.EntityID
+import org.jetbrains.exposed.sql.and
 import org.jetbrains.exposed.sql.transactions.transaction
+import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import org.w3c.dom.Document
 import tech.libeufin.sandbox.db.*
-import tech.libeufin.schema.ebics_h004.*
+import tech.libeufin.schema.ebics_h004.EbicsKeyManagementResponse
+import tech.libeufin.schema.ebics_h004.EbicsUnsecuredRequest
+import tech.libeufin.schema.ebics_h004.HIARequestOrderDataType
 import tech.libeufin.schema.ebics_hev.HEVResponse
 import tech.libeufin.schema.ebics_hev.SystemReturnCodeType
 import tech.libeufin.schema.ebics_s001.SignaturePubKeyOrderData
-import java.math.BigInteger
 import java.nio.charset.StandardCharsets.US_ASCII
 import java.nio.charset.StandardCharsets.UTF_8
-import java.security.KeyFactory
-import java.security.PrivateKey
-import java.security.PublicKey
-import java.security.spec.RSAPrivateKeySpec
-import java.security.spec.RSAPublicKeySpec
+import java.security.interfaces.RSAPublicKey
 import java.text.DateFormat
-import java.util.*
 import java.util.zip.InflaterInputStream
+import javax.sql.rowset.serial.SerialBlob
 
-val logger = LoggerFactory.getLogger("tech.libeufin.sandbox")
-val xmlProcess = XMLUtil()
-val getEbicsHostId = { "LIBEUFIN-SANDBOX" }
-val getEbicsVersion = { "H004" }
-val getEbicsRevision = { 1 }
-
-
-/**
- * Instantiate a new RSA public key.
- *
- * @param exponent
- * @param modulus
- * @return key
- */
-fun loadRsaPublicKey(modulus: ByteArray, exponent: ByteArray): PublicKey {
-
-    val modulusBigInt = BigInteger(1, modulus)
-    val exponentBigInt = BigInteger(1, exponent)
-
-    val keyFactory = KeyFactory.getInstance("RSA")
-    val tmp = RSAPublicKeySpec(modulusBigInt, exponentBigInt)
-    return keyFactory.generatePublic(tmp)
-}
-
-/**
- * The function tries to get the bank private key from the database.
- * If it does not find it, it generates a new one and stores it in
- * database.
- *
- * @return the key (whether from database or freshly created)
- */
-fun getOrMakePrivateKey(): PrivateKey {
-
-    // bank has always one private key in database.
-    var tmp = transaction {
-        EbicsBankPrivateKey.findById(1)
-    }
-
-    // must generate one now
-    if (tmp == null) {
-
-        val privateExponent =
-            BigInteger(PRIVATE_KEY_EXPONENT_LENGTH, Random()) // shall be set 
to some well-known value?
-        val privateModulus = BigInteger(PRIVATE_KEY_MODULUS_LENGTH, Random())
-
-        tmp = transaction {
-            EbicsBankPrivateKey.new {
-                modulus = privateModulus.toByteArray()
-                exponent = privateExponent.toByteArray()
-            }
-        }
-    }
-
-    val keySpec = RSAPrivateKeySpec(
-        BigInteger(tmp.modulus),
-        BigInteger(tmp.exponent)
-    )
-
-    val factory = KeyFactory.getInstance("RSA")
-    val privateKey = factory.generatePrivate(keySpec)
-
-    return privateKey
-}
-
-
-private suspend fun ApplicationCall.adminCustomers() {
-    val body = try {
-        receive<CustomerRequest>()
-    } catch (e: Exception) {
-        e.printStackTrace()
-        respond(
-            HttpStatusCode.BadRequest,
-            SandboxError(e.message.toString())
-        )
-        return
-    }
-    logger.info(body.toString())
-
-    val returnId = transaction {
-        val myUserId = EbicsUser.new { }
-        val myPartnerId = EbicsPartner.new { }
-        val mySystemId = EbicsSystem.new { }
-        val subscriber = EbicsSubscriber.new {
-            userId = myUserId
-            partnerId = myPartnerId
-            systemId = mySystemId
-            state = SubscriberStates.NEW
-        }
-        println("subscriber ID: ${subscriber.id.value}")
-        val customer = BankCustomer.new {
-            name = body.name
-            ebicsSubscriber = subscriber
-        }
-        println("name: ${customer.name}")
-        return@transaction customer.id.value
-    }
-
-    respond(
-        HttpStatusCode.OK,
-        CustomerResponse(id = returnId)
-    )
-}
-
-private suspend fun ApplicationCall.adminCustomersInfo() {
-    val id: Int = try {
-        parameters["id"]!!.toInt()
-    } catch (e: NumberFormatException) {
-        respond(
-            HttpStatusCode.BadRequest,
-            SandboxError(e.message.toString())
-        )
-        return
-    }
-
-    val customerInfo = transaction {
-        val customer = BankCustomer.findById(id) ?: return@transaction null
-        CustomerInfo(
-            customer.name,
-            ebicsInfo = CustomerEbicsInfo(
-                customer.ebicsSubscriber.userId.userId!!
-            )
-        )
-    }
-
-    if (null == customerInfo) {
-        respond(
-            HttpStatusCode.NotFound,
-            SandboxError("id $id not found")
-        )
-        return
-    }
-
-    respond(HttpStatusCode.OK, customerInfo)
-}
-
-private suspend fun ApplicationCall.adminCustomersKeyletter() {
-    val body = try {
-        receive<IniHiaLetters>()
-    } catch (e: Exception) {
-        e.printStackTrace()
-        respond(
-            HttpStatusCode.BadRequest,
-            SandboxError(e.message.toString())
-        )
-        return
-    }
-
-    val ebicsUserID = transaction {
-        EbicsUser.find { EbicsUsers.userId eq body.ini.userId }.firstOrNull()
-    }
-
-    if (ebicsUserID == null) {
-        respond(
-            HttpStatusCode.NotFound,
-            SandboxError("User ID not found")
-        )
-        return
-    }
-
-    val ebicsSubscriber = EbicsSubscriber.find {
-        EbicsSubscribers.userId eq EntityID(ebicsUserID.id.value, EbicsUsers)
-    }.firstOrNull()
-
-    if (ebicsSubscriber == null) {
-        respond(
-            HttpStatusCode.InternalServerError,
-            SandboxError("Bank had internal errors retrieving the Subscriber")
-        )
-        return
-    }
-
-    // check signature key
-    var modulusFromDd = BigInteger(ebicsSubscriber.signatureKey?.modulus)
-    var exponentFromDb = BigInteger(ebicsSubscriber.signatureKey?.exponent)
-    var modulusFromLetter = body.ini.public_modulus.toBigInteger(16)
-    var exponentFromLetter = body.ini.public_modulus.toBigInteger(16)
-
-    if (!((modulusFromDd == modulusFromLetter) && (exponentFromDb == 
exponentFromLetter))) {
-        logger.info("Signature key mismatches for ${ebicsUserID.userId}")
-        respond(
-            HttpStatusCode.NotAcceptable,
-            SandboxError("Signature Key mismatches!")
-        )
-        return
-    }
-
-    logger.info("Signature key from user ${ebicsUserID.userId} becomes 
RELEASED")
-    ebicsSubscriber.signatureKey?.state = KeyStates.RELEASED
-
-    // check identification and authentication key
-    modulusFromDd = BigInteger(ebicsSubscriber.authenticationKey?.modulus)
-    exponentFromDb = BigInteger(ebicsSubscriber.authenticationKey?.exponent)
-    modulusFromLetter = body.hia.ia_public_modulus.toBigInteger(16)
-    exponentFromLetter = body.hia.ia_public_exponent.toBigInteger(16)
-
-    if (!((modulusFromDd == modulusFromLetter) && (exponentFromDb == 
exponentFromLetter))) {
-        logger.info("Identification and authorization key mismatches for 
${ebicsUserID.userId}")
-        respond(
-            HttpStatusCode.NotAcceptable,
-            SandboxError("Identification and authorization key mismatches!")
-        )
-        return
-    }
-
-    logger.info("Authentication key from user ${ebicsUserID.userId} becomes 
RELEASED")
-    ebicsSubscriber.authenticationKey?.state = KeyStates.RELEASED
-
-    // check encryption key
-    modulusFromDd = BigInteger(ebicsSubscriber.encryptionKey?.modulus)
-    exponentFromDb = BigInteger(ebicsSubscriber.encryptionKey?.exponent)
-    modulusFromLetter = body.hia.enc_public_modulus.toBigInteger(16)
-    exponentFromLetter = body.hia.enc_public_exponent.toBigInteger(16)
-
-    if (!((modulusFromDd == modulusFromLetter) && (exponentFromDb == 
exponentFromLetter))) {
-        logger.info("Encryption key mismatches for ${ebicsUserID.userId}")
-        respond(
-            HttpStatusCode.NotAcceptable,
-            SandboxError("Encryption key mismatches!")
-        )
-        return
-    }
-
-    logger.info("Encryption key from user ${ebicsUserID.userId} becomes 
RELEASED")
-    ebicsSubscriber.encryptionKey?.state = KeyStates.RELEASED
+val logger: Logger = LoggerFactory.getLogger("tech.libeufin.sandbox")
 
+val xmlProcess = XMLUtil()
 
-    // TODO change subscriber status!
-    ebicsSubscriber.state = SubscriberStates.READY
-
-    respond(
-        HttpStatusCode.OK,
-        "Your status has changed to READY"
-    )
-}
+data class EbicsRequestError(val statusCode: HttpStatusCode) : 
Exception("Ebics request error")
 
 private suspend fun ApplicationCall.respondEbicsKeyManagement(
     errorText: String,
     errorCode: String,
-    statusCode: HttpStatusCode
+    statusCode: HttpStatusCode,
+    orderId: String? = null,
+    bankReturnCode: String? = null
 ) {
-    val responseXml = EbicsResponse().apply {
-        header = EbicsResponse.Header().apply {
-            mutable = ResponseMutableHeaderType().apply {
+    val responseXml = EbicsKeyManagementResponse().apply {
+        version = "H004"
+        header = EbicsKeyManagementResponse.Header().apply {
+            authenticate = true
+            mutable = 
EbicsKeyManagementResponse.Header.KeyManagementResponseMutableHeaderType().apply
 {
                 reportText = errorText
                 returnCode = errorCode
+                if (orderId != null) {
+                    this.orderID = orderId
+                }
+            }
+            _static = EbicsKeyManagementResponse.Header.EmptyStaticHeader()
+        }
+        body = EbicsKeyManagementResponse.Body().apply {
+            if (bankReturnCode != null) {
+                this.returnCode = 
EbicsKeyManagementResponse.Body.ReturnCode().apply {
+                    this.authenticate = true
+                    this.value = bankReturnCode
+                }
             }
         }
     }
     val text = XMLUtil.convertJaxbToString(responseXml)
+    logger.info("responding with:\n${text}")
     respondText(text, ContentType.Application.Xml, statusCode)
 }
 
+
 private suspend fun ApplicationCall.respondEbicsInvalidXml() {
     respondEbicsKeyManagement("[EBICS_INVALID_XML]", "091010", 
HttpStatusCode.BadRequest)
 }
 
-private suspend fun ApplicationCall.ebicsweb() {
 
+fun findEbicsSubscriber(partnerID: String, userID: String, systemID: String?): 
EbicsSubscriber? {
+    return if (systemID == null) {
+        EbicsSubscriber.find {
+            (EbicsSubscribers.partnerId eq partnerID) and 
(EbicsSubscribers.userId eq userID)
+        }
+    } else {
+        EbicsSubscriber.find {
+            (EbicsSubscribers.partnerId eq partnerID) and
+                    (EbicsSubscribers.userId eq userID) and
+                    (EbicsSubscribers.systemId eq systemID)
+        }
+    }.firstOrNull()
+}
+
+private suspend fun ApplicationCall.ebicsweb() {
     val body: String = receiveText()
     logger.debug("Data received: $body")
 
@@ -335,28 +139,16 @@ private suspend fun ApplicationCall.ebicsweb() {
                 bodyDocument
             )
 
-            if (bodyJaxb.value.header.static.hostID != getEbicsHostId()) {
-                respondEbicsKeyManagement("[EBICS_INVALID_HOST_ID]", "091011", 
HttpStatusCode.NotFound)
-                return
-            }
-
-            val ebicsUserID = transaction {
-                EbicsUser.find { EbicsUsers.userId eq 
bodyJaxb.value.header.static.userID }.firstOrNull()
-            }
+            val staticHeader = bodyJaxb.value.header.static
+            val requestHostID = bodyJaxb.value.header.static.hostID
 
-            if (ebicsUserID == null) {
-                respondEbicsKeyManagement("[EBICS_UNKNOWN_USER]", "091003", 
HttpStatusCode.NotFound)
-                return
+            val ebicsHost = transaction {
+                EbicsHost.find { EbicsHosts.hostID eq requestHostID 
}.firstOrNull()
             }
 
-            val ebicsSubscriber = transaction {
-                EbicsSubscriber.find {
-                    EbicsSubscribers.userId eq EntityID(ebicsUserID.id.value, 
EbicsUsers)
-                }.firstOrNull()
-            }
-
-            if (ebicsSubscriber == null) {
-                respondEbicsKeyManagement("[EBICS_INTERNAL_ERROR]", "061099", 
HttpStatusCode.InternalServerError)
+            if (ebicsHost == null) {
+                logger.warn("client requested unknown HostID")
+                respondEbicsKeyManagement("[EBICS_INVALID_HOST_ID]", "091011", 
HttpStatusCode.NotFound)
                 return
             }
 
@@ -403,12 +195,11 @@ private suspend fun ApplicationCall.ebicsweb() {
             logger.debug("Found payload: ${payload.toString(US_ASCII)}")
 
             when (bodyJaxb.value.header.static.orderDetails.orderType) {
-
                 "INI" -> {
                     val keyObject = 
XMLUtil.convertStringToJaxb<SignaturePubKeyOrderData>(payload.toString(UTF_8))
 
-                    try {
-                        loadRsaPublicKey(
+                    val rsaPublicKey: RSAPublicKey = try {
+                        CryptoUtil.loadRsaPublicKeyFromComponents(
                             
keyObject.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
                             
keyObject.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.exponent
                         )
@@ -421,64 +212,93 @@ private suspend fun ApplicationCall.ebicsweb() {
 
                     // put try-catch block here? (FIXME)
                     transaction {
+                        val ebicsSubscriber =
+                            findEbicsSubscriber(staticHeader.partnerID, 
staticHeader.userID, staticHeader.systemID)
+                        if (ebicsSubscriber == null) {
+                            logger.warn("ebics subscriber 
('${staticHeader.partnerID}' / '${staticHeader.userID}' / 
'${staticHeader.systemID}') not found")
+                            throw EbicsRequestError(HttpStatusCode.NotFound)
+                        }
                         ebicsSubscriber.signatureKey = EbicsPublicKey.new {
-                            modulus = 
keyObject.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.modulus
-                            exponent = 
keyObject.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.exponent
-                            state = KeyStates.NEW
+                            this.rsaPublicKey = 
SerialBlob(rsaPublicKey.encoded)
+                            state = KeyState.NEW
                         }
 
-                        if (ebicsSubscriber.state == SubscriberStates.NEW) {
-                            ebicsSubscriber.state = 
SubscriberStates.PARTIALLY_INITIALIZED_INI
+                        if (ebicsSubscriber.state == SubscriberState.NEW) {
+                            ebicsSubscriber.state = 
SubscriberState.PARTIALLY_INITIALIZED_INI
                         }
 
-                        if (ebicsSubscriber.state == 
SubscriberStates.PARTIALLY_INITIALIZED_HIA) {
-                            ebicsSubscriber.state = 
SubscriberStates.INITIALIZED
+                        if (ebicsSubscriber.state == 
SubscriberState.PARTIALLY_INITIALIZED_HIA) {
+                            ebicsSubscriber.state = SubscriberState.INITIALIZED
                         }
                     }
 
                     logger.info("Signature key inserted in database _and_ 
subscriber state changed accordingly")
+                    respondEbicsKeyManagement(
+                        "[EBICS_OK]",
+                        "000000",
+                        HttpStatusCode.OK,
+                        bankReturnCode = "000000",
+                        orderId = "OR01"
+                    )
+                    return
                 }
 
                 "HIA" -> {
                     val keyObject = 
XMLUtil.convertStringToJaxb<HIARequestOrderDataType>(payload.toString(US_ASCII))
 
-                    try {
-                        loadRsaPublicKey(
+                    val authenticationPublicKey = try {
+                        CryptoUtil.loadRsaPublicKeyFromComponents(
                             
keyObject.value.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
                             
keyObject.value.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
                         )
-                        loadRsaPublicKey(
+                    } catch (e: Exception) {
+                        logger.info("auth public key invalid")
+                        e.printStackTrace()
+                        respondEbicsInvalidXml()
+                        return
+                    }
+
+                    val encryptionPublicKey = try {
+                        CryptoUtil.loadRsaPublicKeyFromComponents(
                             
keyObject.value.encryptionPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
                             
keyObject.value.encryptionPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
                         )
                     } catch (e: Exception) {
-                        logger.info("User gave at least one invalid HIA key")
+                        logger.info("auth public key invalid")
                         e.printStackTrace()
                         respondEbicsInvalidXml()
                         return
                     }
 
-                    // put try-catch block here? (FIXME)
                     transaction {
+                        val ebicsSubscriber =
+                            findEbicsSubscriber(staticHeader.partnerID, 
staticHeader.userID, staticHeader.systemID)
+                        if (ebicsSubscriber == null) {
+                            logger.warn("ebics subscriber not found")
+                            throw EbicsRequestError(HttpStatusCode.NotFound)
+                        }
                         ebicsSubscriber.authenticationKey = EbicsPublicKey.new 
{
-                            modulus = 
keyObject.value.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.modulus
-                            exponent = 
keyObject.value.authenticationPubKeyInfo.pubKeyValue.rsaKeyValue.exponent
-                            state = KeyStates.NEW
+                            this.rsaPublicKey = 
SerialBlob(authenticationPublicKey.encoded)
+                            state = KeyState.NEW
+                        }
+                        ebicsSubscriber.encryptionKey = EbicsPublicKey.new {
+                            this.rsaPublicKey = 
SerialBlob(encryptionPublicKey.encoded)
+                            state = KeyState.NEW
                         }
 
-                        if (ebicsSubscriber.state == SubscriberStates.NEW) {
-                            ebicsSubscriber.state = 
SubscriberStates.PARTIALLY_INITIALIZED_HIA
+                        if (ebicsSubscriber.state == SubscriberState.NEW) {
+                            ebicsSubscriber.state = 
SubscriberState.PARTIALLY_INITIALIZED_HIA
                         }
 
-                        if (ebicsSubscriber.state == 
SubscriberStates.PARTIALLY_INITIALIZED_INI) {
-                            ebicsSubscriber.state = 
SubscriberStates.INITIALIZED
+                        if (ebicsSubscriber.state == 
SubscriberState.PARTIALLY_INITIALIZED_INI) {
+                            ebicsSubscriber.state = SubscriberState.INITIALIZED
                         }
                     }
+                    respondEbicsKeyManagement("[EBICS_OK]", "000000", 
HttpStatusCode.OK)
                 }
             }
 
-            respondEbicsKeyManagement("[EBICS_OK]", "000000", 
HttpStatusCode.OK)
-            return
+            throw AssertionError("not reached")
         }
 
         "ebicsHEVRequest" -> {
@@ -509,8 +329,28 @@ private suspend fun ApplicationCall.ebicsweb() {
 
 fun main() {
     dbCreateTables()
-    val server = embeddedServer(Netty, port = 5000) {
 
+    transaction {
+        val pairA = CryptoUtil.generateRsaKeyPair(2048)
+        val pairB = CryptoUtil.generateRsaKeyPair(2048)
+        val pairC = CryptoUtil.generateRsaKeyPair(2048)
+        EbicsHost.new {
+            hostId = "host01"
+            ebicsVersion = "H004"
+            authenticationPrivateKey = SerialBlob(pairA.private.encoded)
+            encryptionPrivateKey = SerialBlob(pairB.private.encoded)
+            signaturePrivateKey = SerialBlob(pairC.private.encoded)
+        }
+
+        EbicsSubscriber.new {
+            partnerId = "PARTNER1"
+            userId = "USER1"
+            systemId = null
+            state = SubscriberState.NEW
+        }
+    }
+
+    val server = embeddedServer(Netty, port = 5000) {
         install(CallLogging)
         install(ContentNegotiation) {
             gson {
@@ -518,35 +358,72 @@ fun main() {
                 setPrettyPrinting()
             }
         }
+        install(StatusPages) {
+            exception<Throwable> { cause ->
+                logger.error("Exception while handling 
'${call.request.uri.toString()}'", cause)
+                call.respondText("Internal server error.", 
ContentType.Text.Plain, HttpStatusCode.InternalServerError)
+            }
+        }
+        intercept(ApplicationCallPipeline.Fallback) {
+            if (this.call.response.status() == null) {
+                call.respondText("Not found (no route matched).\n", 
ContentType.Text.Plain, HttpStatusCode.NotFound)
+                return@intercept finish()
+            }
+        }
         routing {
+            //trace { logger.info(it.buildText()) }
             get("/") {
-                logger.debug("GET: not implemented")
                 call.respondText("Hello LibEuFin!\n", ContentType.Text.Plain)
-                return@get
             }
-
-            post("/admin/customers") {
-                call.adminCustomers()
-                return@post
+            get("/ebics/hosts") {
+                val ebicsHosts = transaction {
+                    EbicsHost.all().map { it.hostId }
+                }
+                call.respond(EbicsHostsResponse(ebicsHosts))
             }
-
-            get("/admin/customers/{id}") {
-                call.adminCustomersInfo()
-                return@get
+            post("/ebics/hosts") {
+                val req = call.receive<EbicsHostCreateRequest>()
+                transaction {
+                    EbicsHost.new {
+                        this.ebicsVersion = req.ebicsVersion
+                        this.hostId = hostId
+                    }
+                }
             }
-
-            post("/admin/customers/{id}/ebics/keyletter") {
-                call.adminCustomersKeyletter()
-                return@post
+            get("/ebics/hosts/{id}") {
+                val resp = transaction {
+                    val host = EbicsHost.find { EbicsHosts.hostID eq 
call.parameters["id"]!! }.firstOrNull()
+                    if (host == null) null
+                    else EbicsHostResponse(host.hostId, host.ebicsVersion)
+                }
+                if (resp == null) call.respond(HttpStatusCode.NotFound, 
SandboxError("host not found"))
+                else call.respond(resp)
+            }
+            get("/ebics/subscribers") {
+                val subscribers = transaction {
+                    EbicsSubscriber.all().map { it.id.value.toString() }
+                }
+                call.respond(EbicsSubscribersResponse(subscribers))
+            }
+            get("/ebics/subscribers/{id}") {
+                val resp = transaction {
+                    val id = call.parameters["id"]!!
+                    val subscriber = EbicsSubscriber.findById(id.toInt())!!
+                    EbicsSubscriberResponse(
+                        id,
+                        subscriber.partnerId,
+                        subscriber.userId,
+                        subscriber.systemId,
+                        subscriber.state.name
+                    )
+                }
+                call.respond(resp)
             }
-
             post("/ebicsweb") {
                 call.ebicsweb()
-                return@post
             }
         }
     }
     logger.info("Up and running")
     server.start(wait = true)
 }
-
diff --git a/sandbox/src/main/kotlin/ProtocolAndVersion.kt 
b/sandbox/src/main/kotlin/ProtocolAndVersion.kt
deleted file mode 100644
index e69f08b..0000000
--- a/sandbox/src/main/kotlin/ProtocolAndVersion.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package tech.libeufin.sandbox
-
-class ProtocolAndVersion(protocol: String, version: String) {
-    val protocol = protocol
-    val version = version
-}
\ No newline at end of file
diff --git 
a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt 
b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt
index 986e7de..0ed892e 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt
@@ -132,11 +132,11 @@ class EbicsUnsecuredRequest {
     @XmlType(name = "", propOrder = ["dataTransfer"])
     class Body {
         @get:XmlElement(name = "DataTransfer", required = true)
-        lateinit var dataTransfer: DataTransfer
+        lateinit var dataTransfer: UnsecuredDataTransfer
 
         @XmlAccessorType(XmlAccessType.NONE)
         @XmlType(name = "", propOrder = ["orderData"])
-        class DataTransfer {
+        class UnsecuredDataTransfer {
             @get:XmlElement(name = "OrderData", required = true)
             lateinit var orderData: OrderData
 
@@ -166,55 +166,32 @@ class EbicsUnsecuredRequest {
     lateinit var body: Body
 }
 
-
 @XmlAccessorType(XmlAccessType.NONE)
-@XmlType(name = "DataTransferResponseType", propOrder = ["dataEncryptionInfo", 
"orderData", "any"])
-class DataTransferResponse {
-    @get:XmlElement(name = "DataEncryptionInfo")
-    var dataEncryptionInfo: DataEncryptionInfo? = null
+class DataEncryptionInfo {
+    @get:XmlAttribute(name = "authenticate", required = true)
+    var authenticate: Boolean = false
+
+    @get:XmlElement(name = "EncryptionPubKeyDigest", required = true)
+    lateinit var encryptionPubKeyDigest: EncryptionPubKeyDigest
 
-    @get:XmlElement(name = "OrderData", required = true)
-    lateinit var orderData: OrderData
+    @get:XmlElement(name = "TransactionKey", required = true)
+    lateinit var transactionKey: ByteArray
 
     @get:XmlAnyElement(lax = true)
     var any: List<Any>? = null
 
     @XmlAccessorType(XmlAccessType.NONE)
-    class OrderData {
-        @get:XmlValue
-        lateinit var value: ByteArray
-
-        @get:XmlAnyAttribute
-        var otherAttributes = HashMap<QName, String>()
-    }
-
-    @XmlAccessorType(XmlAccessType.NONE)
-    class DataEncryptionInfo {
-        @get:XmlAttribute(name = "authenticate", required = true)
-        var authenticate: Boolean = false
-
-        @get:XmlElement(name = "EncryptionPubKeyDigest", required = true)
-        lateinit var encryptionPubKeyDigest: EncryptionPubKeyDigest
-
-        @get:XmlElement(name = "TransactionKey", required = true)
-        lateinit var transactionKey: ByteArray
-
-        @get:XmlAnyElement(lax = true)
-        var any: List<Any>? = null
-
-        @XmlAccessorType(XmlAccessType.NONE)
-        class EncryptionPubKeyDigest {
-            @get:XmlAttribute(name = "Version", required = true)
-            @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
-            lateinit var version: String
+    class EncryptionPubKeyDigest {
+        @get:XmlAttribute(name = "Version", required = true)
+        @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
+        lateinit var version: String
 
-            @XmlAttribute(name = "Algorithm", required = true)
-            @XmlSchemaType(name = "anyURI")
-            lateinit var algorithm: String
+        @XmlAttribute(name = "Algorithm", required = true)
+        @XmlSchemaType(name = "anyURI")
+        lateinit var algorithm: String
 
-            @get:XmlValue
-            lateinit var value: ByteArray
-        }
+        @get:XmlValue
+        lateinit var value: ByteArray
     }
 }
 
@@ -224,7 +201,7 @@ class DataTransferResponse {
     name = "ResponseMutableHeaderType",
     propOrder = ["transactionPhase", "segmentNumber", "orderID", "returnCode", 
"reportText", "any"]
 )
-class ResponseMutableHeaderType {
+class EbicsResponseMutableHeaderType {
     @XmlElement(name = "TransactionPhase", required = true)
     @XmlSchemaType(name = "token")
     lateinit var transactionPhase: TransactionPhaseType
@@ -295,6 +272,16 @@ class ResponseStaticHeaderType {
 }
 
 
+@XmlAccessorType(XmlAccessType.NONE)
+class TimestampBankParameter {
+    @XmlValue
+    lateinit var value: XMLGregorianCalendar
+
+    @XmlAttribute(name = "authenticate", required = true)
+    var authenticate: Boolean = false
+}
+
+
 @XmlAccessorType(XmlAccessType.NONE)
 @XmlType(name = "", propOrder = ["header", "authSignature", "body"])
 @XmlRootElement(name = "ebicsResponse")
@@ -321,16 +308,11 @@ class EbicsResponse {
     @XmlAccessorType(XmlAccessType.NONE)
     @XmlType(name = "", propOrder = ["_static", "mutable"])
     class Header {
-
-        init {
-            println("creating header")
-        }
-
         @get:XmlElement(name = "static", required = true)
-        var _static: ResponseStaticHeaderType? = null
+        lateinit var _static: ResponseStaticHeaderType
 
         @get:XmlElement(required = true)
-        var mutable: ResponseMutableHeaderType? = null
+        lateinit var mutable: EbicsResponseMutableHeaderType
 
         @get:XmlAttribute(name = "authenticate", required = true)
         var authenticate: Boolean = false
@@ -340,7 +322,7 @@ class EbicsResponse {
     @XmlType(name = "", propOrder = ["dataTransfer", "returnCode", 
"timestampBankParameter"])
     class Body {
         @XmlElement(name = "DataTransfer")
-        var dataTransfer: DataTransferResponse? = null
+        var dataTransfer: DataTransferResponseType? = null
 
         @XmlElement(name = "ReturnCode", required = true)
         lateinit var returnCode: ReturnCode
@@ -348,15 +330,6 @@ class EbicsResponse {
         @XmlElement(name = "TimestampBankParameter")
         var timestampBankParameter: TimestampBankParameter? = null
 
-        @XmlAccessorType(XmlAccessType.NONE)
-        class TimestampBankParameter {
-            @XmlValue
-            lateinit var value: XMLGregorianCalendar
-
-            @XmlAttribute(name = "authenticate", required = true)
-            var authenticate: Boolean = false
-        }
-
         @XmlAccessorType(XmlAccessType.NONE)
         class ReturnCode {
             @get:XmlValue
@@ -366,19 +339,48 @@ class EbicsResponse {
             @get:XmlAttribute(name = "authenticate", required = true)
             var authenticate: Boolean = false
         }
+
+        @XmlAccessorType(XmlAccessType.NONE)
+        @XmlType(name = "DataTransferResponseType", propOrder = 
["dataEncryptionInfo", "orderData", "any"])
+        class DataTransferResponseType {
+            @get:XmlElement(name = "DataEncryptionInfo")
+            var dataEncryptionInfo: DataEncryptionInfo? = null
+
+            @get:XmlElement(name = "OrderData", required = true)
+            lateinit var orderData: OrderData
+
+            @get:XmlAnyElement(lax = true)
+            var any: List<Any>? = null
+
+            @XmlAccessorType(XmlAccessType.NONE)
+            class OrderData {
+                @get:XmlValue
+                lateinit var value: ByteArray
+
+                @get:XmlAnyAttribute
+                var otherAttributes = HashMap<QName, String>()
+            }
+        }
     }
 }
 
 
+@XmlAccessorType(XmlAccessType.NONE)
+@XmlType(
+    name = "PubKeyValueType", propOrder = [
+        "rsaKeyValue",
+        "timeStamp"
+    ]
+)
 class PubKeyValueType {
-    @XmlElement(name = "RSAKeyValue", namespace = 
"http://www.w3.org/2000/09/xmldsig#";, required = true)
+    @get:XmlElement(name = "RSAKeyValue", namespace = 
"http://www.w3.org/2000/09/xmldsig#";, required = true)
     lateinit var rsaKeyValue: RSAKeyValueType
 
-    @XmlElement(name = "TimeStamp")
-    @XmlSchemaType(name = "dateTime")
+    @get:XmlElement(name = "TimeStamp", required = false)
+    @get:XmlSchemaType(name = "dateTime")
     var timeStamp: XMLGregorianCalendar? = null
 
-    @XmlAnyElement(lax = true)
+    @get:XmlAnyElement(lax = true)
     var any: List<Any>? = null
 }
 
@@ -407,7 +409,7 @@ class AuthenticationPubKeyInfoType {
 
 @XmlAccessorType(XmlAccessType.NONE)
 @XmlType(
-    name = "AuthenticationPubKeyInfoType", propOrder = [
+    name = "EncryptionPubKeyInfoType", propOrder = [
         "x509Data",
         "pubKeyValue",
         "encryptionVersion"
@@ -427,28 +429,115 @@ class EncryptionPubKeyInfoType {
 }
 
 
-@XmlAccessorType(XmlAccessType.FIELD)
+@XmlAccessorType(XmlAccessType.NONE)
 @XmlType(
     name = "HIARequestOrderDataType",
     propOrder = ["authenticationPubKeyInfo", "encryptionPubKeyInfo", 
"partnerID", "userID", "any"]
 )
 class HIARequestOrderDataType {
-    @XmlElement(name = "AuthenticationPubKeyInfo", required = true)
+    @get:XmlElement(name = "AuthenticationPubKeyInfo", required = true)
     lateinit var authenticationPubKeyInfo: AuthenticationPubKeyInfoType
 
-    @XmlElement(name = "EncryptionPubKeyInfo", required = true)
+    @get:XmlElement(name = "EncryptionPubKeyInfo", required = true)
     lateinit var encryptionPubKeyInfo: EncryptionPubKeyInfoType
 
-    @XmlElement(name = "PartnerID", required = true)
-    @XmlJavaTypeAdapter(CollapsedStringAdapter::class)
-    @XmlSchemaType(name = "token")
+    @get:XmlElement(name = "PartnerID", required = true)
+    @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
+    @get:XmlSchemaType(name = "token")
     lateinit var partnerID: String
 
-    @XmlElement(name = "UserID", required = true)
-    @XmlJavaTypeAdapter(CollapsedStringAdapter::class)
-    @XmlSchemaType(name = "token")
+    @get:XmlElement(name = "UserID", required = true)
+    @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
+    @get:XmlSchemaType(name = "token")
     lateinit var userID: String
 
-    @XmlAnyElement(lax = true)
+    @get:XmlAnyElement(lax = true)
     var any: List<Any>? = null
 }
+
+@XmlAccessorType(XmlAccessType.NONE)
+@XmlType(name = "", propOrder = ["header", "body"])
+@XmlRootElement(name = "ebicsKeyManagementResponse")
+class EbicsKeyManagementResponse {
+    @get:XmlElement(required = true)
+    lateinit var header: Header
+
+    @get:XmlElement(required = true)
+    lateinit var body: Body
+
+    @get:XmlAttribute(name = "Version", required = true)
+    @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
+    lateinit var version: String
+
+    @get:XmlAttribute(name = "Revision")
+    var revision: Int? = null
+
+    @XmlAccessorType(XmlAccessType.NONE)
+    @XmlType(name = "", propOrder = ["_static", "mutable"])
+    class Header {
+        @get:XmlElement(name = "static", required = true)
+        lateinit var _static: EmptyStaticHeader
+
+        @get:XmlElement(required = true)
+        lateinit var mutable: KeyManagementResponseMutableHeaderType
+
+        @get:XmlAttribute(name = "authenticate", required = true)
+        var authenticate: Boolean = false
+
+        @XmlAccessorType(XmlAccessType.NONE)
+        @XmlType(name = "")
+        class EmptyStaticHeader
+
+        @XmlAccessorType(XmlAccessType.NONE)
+        @XmlType(name = "", propOrder = ["orderID", "returnCode", 
"reportText"])
+        class KeyManagementResponseMutableHeaderType {
+            @XmlElement(name = "OrderID")
+            @XmlJavaTypeAdapter(CollapsedStringAdapter::class)
+            @XmlSchemaType(name = "token")
+            var orderID: String? = null
+
+            @XmlElement(name = "ReturnCode", required = true)
+            @XmlJavaTypeAdapter(CollapsedStringAdapter::class)
+            @XmlSchemaType(name = "token")
+            lateinit var returnCode: String
+
+            @XmlElement(name = "ReportText", required = true)
+            @XmlJavaTypeAdapter(NormalizedStringAdapter::class)
+            @XmlSchemaType(name = "normalizedString")
+            lateinit var reportText: String
+        }
+    }
+
+    @XmlAccessorType(XmlAccessType.NONE)
+    @XmlType(name = "", propOrder = ["dataTransfer", "returnCode", 
"timestampBankParameter"])
+    class Body {
+        @XmlElement(name = "DataTransfer")
+        val dataTransfer: DataTransfer? = null
+
+        @XmlElement(name = "ReturnCode", required = true)
+        lateinit var returnCode: ReturnCode
+
+        @XmlElement(name = "TimestampBankParameter")
+        var timestampBankParameter: TimestampBankParameter? = null
+
+        @XmlAccessorType(XmlAccessType.NONE)
+        class ReturnCode {
+            @get:XmlValue
+            @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class)
+            lateinit var value: String
+
+            @get:XmlAttribute(name = "authenticate", required = true)
+            var authenticate: Boolean = false
+        }
+
+        @XmlAccessorType(XmlAccessType.NONE)
+        @XmlType(name = "", propOrder = ["dataEncryptionInfo", "orderData"])
+        class DataTransfer {
+            @get:XmlElement(name = "DataEncryptionInfo")
+            var dataEncryptionInfo: DataEncryptionInfo? = null
+
+            @get:XmlElement(name = "OrderData", required = true)
+            lateinit var orderData: 
EbicsResponse.Body.DataTransferResponseType.OrderData
+        }
+    }
+}
diff --git a/sandbox/src/test/kotlin/CryptoUtilTest.kt 
b/sandbox/src/test/kotlin/CryptoUtilTest.kt
new file mode 100644
index 0000000..3ea9cfe
--- /dev/null
+++ b/sandbox/src/test/kotlin/CryptoUtilTest.kt
@@ -0,0 +1,59 @@
+/*
+ * This file is part of LibEuFin.
+ * Copyright (C) 2019 Stanisci and Dold.
+
+ * LibEuFin is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation; either version 3, or
+ * (at your option) any later version.
+
+ * LibEuFin is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
+ * Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public
+ * License along with LibEuFin; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>
+ */
+
+package tech.libeufin.sandbox
+
+import org.junit.Test
+import java.security.KeyPairGenerator
+import java.security.interfaces.RSAPrivateCrtKey
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+
+class CryptoUtilTest {
+
+    @Test
+    fun loadFromModulusAndExponent() {
+        val keyPair = CryptoUtil.generateRsaKeyPair(1024)
+        val pub2 = CryptoUtil.loadRsaPublicKeyFromComponents(
+            keyPair.public.modulus.toByteArray(),
+            keyPair.public.publicExponent.toByteArray()
+        )
+        assertEquals(keyPair.public, pub2)
+    }
+
+    @Test
+    fun keyGeneration() {
+        val gen: KeyPairGenerator = KeyPairGenerator.getInstance("RSA")
+        gen.initialize(2048)
+        val pair = gen.genKeyPair()
+        println(pair.private)
+        assertTrue(pair.private is RSAPrivateCrtKey)
+    }
+
+    @Test
+    fun testCryptoUtilBasics() {
+        val keyPair = CryptoUtil.generateRsaKeyPair(1024)
+        val encodedPriv = keyPair.private.encoded
+        val encodedPub = keyPair.public.encoded
+        val otherKeyPair =
+            RsaCrtKeyPair(CryptoUtil.loadRsaPrivateKey(encodedPriv), 
CryptoUtil.loadRsaPublicKey(encodedPub))
+        assertEquals(keyPair.private, otherKeyPair.private)
+        assertEquals(keyPair.public, otherKeyPair.public)
+    }
+}
\ No newline at end of file
diff --git a/sandbox/src/test/kotlin/DbTest.kt 
b/sandbox/src/test/kotlin/DbTest.kt
deleted file mode 100644
index 1c50dd1..0000000
--- a/sandbox/src/test/kotlin/DbTest.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-package tech.libeufin.sandbox
-
-import junit.framework.TestCase.assertFalse
-import org.jetbrains.exposed.dao.EntityID
-import org.jetbrains.exposed.sql.transactions.transaction
-import org.junit.Test
-import org.junit.Before
-import tech.libeufin.sandbox.db.*
-
-class DbTest {
-
-    @Before
-    fun setUp() {
-        dbCreateTables()
-    }
-
-    /**
-     * This function creates a EBICS subscriber _first_, and
-     * subsequently tries to insert a mock bianry value into
-     * the keys columns of the subscriber.
-     */
-    @Test
-    fun storeBinary() {
-        transaction {
-            // join table
-            val subscriber = createSubscriber()
-
-            val key = EbicsPublicKey.new {
-                modulus = "BINARYVALUE".toByteArray()
-                exponent = "BINARYVALUE".toByteArray()
-                state = KeyStates.NEW
-            }
-            subscriber.authenticationKey = key
-        }
-    }
-
-    @Test
-    fun nestedQuery() {
-
-        /***
-         *  Some query like the following is needed:
-         *
-         *  val result = EbicsSubscriber.find {
-         *    EbicsSubscribers.userId.userId eq "u1"
-         *  }.first()
-         */
-
-         transaction {
-            createSubscriber()
-
-            val tmp = EbicsUser.find { EbicsUsers.userId eq "u1" 
}.firstOrNull()
-            if (tmp == null) {
-                logger.error("No such user found in database.")
-                return@transaction
-            }
-            println("Found user with id: ${tmp.id.value}")
-
-            val found = EbicsSubscriber.find {
-                EbicsSubscribers.userId eq EntityID(tmp.id.value, EbicsUsers)
-            }
-
-            assertFalse(found.empty())
-        }
-    }
-}
\ No newline at end of file
diff --git a/sandbox/src/test/kotlin/GeneratePrivateKeyTest.kt 
b/sandbox/src/test/kotlin/GeneratePrivateKeyTest.kt
deleted file mode 100644
index 4dad69c..0000000
--- a/sandbox/src/test/kotlin/GeneratePrivateKeyTest.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package tech.libeufin.sandbox
-
-import org.junit.Test
-import junit.framework.TestCase.assertTrue
-import org.jetbrains.exposed.sql.transactions.transaction
-import org.junit.Before
-import tech.libeufin.sandbox.db.EbicsBankPrivateKey
-import tech.libeufin.sandbox.db.dbCreateTables
-
-class GeneratePrivateKeyTest {
-
-    @Before
-    fun setUp() {
-        dbCreateTables()
-    }
-
-    @Test
-    fun loadOrGeneratePrivateKey() {
-
-        getOrMakePrivateKey()
-
-        assertTrue(
-            transaction {
-                EbicsBankPrivateKey.findById(1)
-            } != null
-        )
-    }
-}
\ No newline at end of file
diff --git a/sandbox/src/test/kotlin/HiaLoadTest.kt 
b/sandbox/src/test/kotlin/HiaLoadTest.kt
index 489685a..9cb3f87 100644
--- a/sandbox/src/test/kotlin/HiaLoadTest.kt
+++ b/sandbox/src/test/kotlin/HiaLoadTest.kt
@@ -11,7 +11,7 @@ class HiaLoadTest {
 
         val processor = XMLUtil()
         val classLoader = ClassLoader.getSystemClassLoader()
-        val hia = classLoader.getResource("HIA.xml")
+        val hia = classLoader.getResource("<?xml version=\"1.0\" 
encoding=\"UTF-8\"?>\n<ebicsUnsecuredRequest xmlns=\"urn:org:ebics:H004\"\n     
                  xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"\n             
          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n             
          xsi:schemaLocation=\"urn:org:ebics:H004 
ebics_keymgmt_request_H004.xsd\"\n                       Version=\"H004\"\n     
                  Revision=\"1\">\n  <header authenticate [...]
         val hiaDom = XMLUtil.parseStringIntoDom(hia.readText())
         val x: Element = hiaDom.getElementsByTagNameNS(
             "urn:org:ebics:H004",
diff --git a/sandbox/src/test/kotlin/InnerIniLoadTest.kt 
b/sandbox/src/test/kotlin/InnerIniLoadTest.kt
index 664ece3..f181d3e 100644
--- a/sandbox/src/test/kotlin/InnerIniLoadTest.kt
+++ b/sandbox/src/test/kotlin/InnerIniLoadTest.kt
@@ -1,24 +1,31 @@
 package tech.libeufin.sandbox
 
 import org.junit.Test
+import tech.libeufin.schema.ebics_h004.EbicsUnsecuredRequest
 import tech.libeufin.schema.ebics_s001.SignaturePubKeyOrderData
+import kotlin.test.assertNotNull
 
 class InnerIniLoadTest {
-
-    val jaxbKey = {
-        val classLoader = ClassLoader.getSystemClassLoader()
-        val file = classLoader.getResource(
-            "ebics_ini_inner_key.xml"
-        )
-        XMLUtil.convertStringToJaxb<SignaturePubKeyOrderData>(file.readText())
-    }()
-
     @Test
     fun loadInnerKey() {
+        val jaxbKey = run {
+            val classLoader = ClassLoader.getSystemClassLoader()
+            val file = classLoader.getResource(
+                "ebics_ini_inner_key.xml"
+            )
+            assertNotNull(file)
+            
XMLUtil.convertStringToJaxb<SignaturePubKeyOrderData>(file.readText())
+        }
 
         val modulus = 
jaxbKey.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.modulus
         val exponent = 
jaxbKey.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.exponent
+        CryptoUtil.loadRsaPublicKeyFromComponents(modulus, exponent)
+    }
 
-        loadRsaPublicKey(modulus, exponent)
+    @Test
+    fun loadIniMessage() {
+        val classLoader = ClassLoader.getSystemClassLoader()
+        val text = 
classLoader.getResource("ebics_ini_request_sample.xml")!!.readText()
+        XMLUtil.convertStringToJaxb<EbicsUnsecuredRequest>(text)
     }
 }
\ No newline at end of file
diff --git a/sandbox/src/test/kotlin/JaxbTest.kt 
b/sandbox/src/test/kotlin/JaxbTest.kt
index 11942ac..fb2271c 100644
--- a/sandbox/src/test/kotlin/JaxbTest.kt
+++ b/sandbox/src/test/kotlin/JaxbTest.kt
@@ -2,10 +2,13 @@ package tech.libeufin.sandbox
 
 import junit.framework.TestCase.assertEquals
 import org.junit.Test
+import tech.libeufin.schema.ebics_h004.EbicsKeyManagementResponse
 import tech.libeufin.schema.ebics_h004.EbicsUnsecuredRequest
+import tech.libeufin.schema.ebics_h004.HIARequestOrderDataType
 import tech.libeufin.schema.ebics_hev.HEVResponse
 import tech.libeufin.schema.ebics_hev.SystemReturnCodeType
 import tech.libeufin.schema.ebics_s001.SignaturePubKeyOrderData
+import kotlin.test.assertTrue
 
 class JaxbTest {
     /**
@@ -65,4 +68,28 @@ class JaxbTest {
             iniDom
         )
     }
+
+    @Test
+    fun testKeyMgmgResponse() {
+        val responseXml = EbicsKeyManagementResponse().apply {
+            header = EbicsKeyManagementResponse.Header().apply {
+                mutable = 
EbicsKeyManagementResponse.Header.KeyManagementResponseMutableHeaderType().apply
 {
+                    reportText = "foo"
+                    returnCode = "bar"
+                }
+                _static = EbicsKeyManagementResponse.Header.EmptyStaticHeader()
+            }
+            version = "H004"
+            body = EbicsKeyManagementResponse.Body()
+        }
+        val text = XMLUtil.convertJaxbToString(responseXml)
+        assertTrue(text.isNotEmpty())
+    }
+
+    @Test
+    fun testParseHiaRequestOrderData() {
+        val classLoader = ClassLoader.getSystemClassLoader()
+        val hia = 
classLoader.getResource("hia_request_order_data.xml")!!.readText()
+        XMLUtil.convertStringToJaxb<HIARequestOrderDataType>(hia)
+    }
 }
\ No newline at end of file
diff --git a/sandbox/src/test/resources/ebics_ini_request_sample.xml 
b/sandbox/src/test/resources/ebics_ini_request_sample.xml
index 3015332..a9237a9 100644
--- a/sandbox/src/test/resources/ebics_ini_request_sample.xml
+++ b/sandbox/src/test/resources/ebics_ini_request_sample.xml
@@ -1,35 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<ebicsUnsecuredRequest Revision="1" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="urn:org:ebics:H004 ebics_keymgmt_request_H004.xsd" 
Version="H004" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"; 
xmlns="urn:org:ebics:H004">
-  <header authenticate="true">
-    <static>
-      <HostID>LIBEUFIN-SANDBOX</HostID>
-      <PartnerID>flokid</PartnerID>
-      <UserID>u1</UserID>
-      <!--
-
-      Such a not allowed renaming like this fixes the import of DOM into JAXB.
-
-      <UnsecuredReqOrderDetails>
-        <OrderType>INI</OrderType>
-        <OrderAttribute>DZNNN</OrderAttribute>
-      </UnsecuredReqOrderDetails
-
-      Also putting the following attribute on OrderDetails fixes it.
-
-       xsi:type="UnsecuredReqOrderDetailsType"
-
-      -->
-      <OrderDetails>
-        <OrderType>INI</OrderType>
-        <OrderAttribute>DZNNN</OrderAttribute>
-      </OrderDetails>
-      <SecurityMedium>0000</SecurityMedium>
-    </static>
-    <mutable />
-  </header>
-  <body>
-    <DataTransfer>
-      
<OrderData>eJx9U1tzmkAUfu9M/wNDH524XIINjprBaLxSUASDL51FlvvFsIus/vpSYm3a1D6e7/vO/ZzeI00T5ogKHOZZn+XbHMugbJ+7Yeb32ZJ4dw/s4+Dzp54R+hkkZYH00lmgk1a4qBhBApnaP8NdisM+GxBy6AJQVVW7Ett54QOB43jwoi6NfYBSeBdmmMBsj1im1ndxAy7zPSRN8nfuyAn3uIlg1BGYmwxozO/4V3Ftil32UpKLb1TEAU4Gtcat3b5c1P/JztbtM8zfA5hlXt4QNfWGWDAp0QWqQRd314byAX9j1NwtkxIPsBSTgy/SSeTsdr61scm2xaEOxVufvxfM6pirYuqVauu1iGdQcnRzslpOO8P1Up6hyM6xHuRKJ6rUoUG1h6UHoY9OuzkRVKmaxsncPoueMiKrwuKdWFrLggZtIO927pRWIrVlkaTS3LMKdbSVR+OFNOQD82w/u1H5DbyWAsD
 [...]
-    </DataTransfer>
-  </body>
-</ebicsUnsecuredRequest>
+<ebicsUnsecuredRequest Revision="1" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+                       xsi:schemaLocation="urn:org:ebics:H004 
ebics_keymgmt_request_H004.xsd" Version="H004"
+                       xmlns="urn:org:ebics:H004">
+    <header authenticate="true">
+        <static>
+            <HostID>myhost</HostID>
+            <PartnerID>k1</PartnerID>
+            <UserID>u1</UserID>
+            <OrderDetails>
+                <OrderType>INI</OrderType>
+                <OrderAttribute>DZNNN</OrderAttribute>
+            </OrderDetails>
+            <SecurityMedium>0000</SecurityMedium>
+        </static>
+        <mutable/>
+    </header>
+    <body>
+        <DataTransfer>
+            <OrderData>
+                
eJx9U1tzmkAUfu9M/wNDH524XIINjprBaOIFCopg8CWzyHK/GHaR1V9fhtg0bWrf9nzfdy57LoN7mqXMEZU4KvIhy3c5lkH5vvCiPBiyFfFv7tj70dcvAzMKckiqEhmVu0QnvfRQOYEEMo1/jvsUR0M2JOTQB6Cu624tdosyAALH8eBZU819iDJ4E+WYwHyPWKbR93ELqsUekjb5B3fkRnvcRjCbCMxVBrTmC/5VXJdij72U5OErFXGAk0Gj8Rq3bxf1f7KzzfcZ5u8GzHO/aImGekNsmFboAjWgh/trU/mEvzFa4VVphUdYSsghEOlT7O52gb1xyLbDoR7F24C/Faz6WGhi5lda57VM5lByDetppc5647Uqz1HsFNgIC6UX19rYpPqd6kMYoNNuQQRNqmdJunDOoq9MyKq0eTeR1rKgQwfIu503o7VIHVkkmbTw7VKbbOXJdCmN+dA6O49eXP0Ar5UA
 [...]
+            </OrderData>
+        </DataTransfer>
+    </body>
+</ebicsUnsecuredRequest>
\ No newline at end of file
diff --git a/sandbox/src/test/resources/ebics_ini_request_sample_patched.xml 
b/sandbox/src/test/resources/ebics_ini_request_sample_patched.xml
deleted file mode 100644
index 821d7fd..0000000
--- a/sandbox/src/test/resources/ebics_ini_request_sample_patched.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ebicsUnsecuredRequest Revision="1" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="urn:org:ebics:H004 ebics_keymgmt_request_H004.xsd" 
Version="H004" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"; 
xmlns="urn:org:ebics:H004">
-  <header authenticate="true">
-    <static>
-      <HostID>foo</HostID>
-      <PartnerID>flokid</PartnerID>
-      <UserID>flouid</UserID>
-      <OrderDetails xsi:type="UnsecuredReqOrderDetailsType">
-        <OrderType>INI</OrderType>
-        <OrderAttribute>DZNNN</OrderAttribute>
-      </OrderDetails>
-      <SecurityMedium>0000</SecurityMedium>
-    </static>
-    <mutable />
-  </header>
-  <body>
-    <DataTransfer>
-      
<OrderData>eJx9U1tzmkAUfu9M/wNDH524XIINjprBaLxSUASDL51FlvvFsIus/vpSYm3a1D6e7/vO/ZzeI00T5ogKHOZZn+XbHMugbJ+7Yeb32ZJ4dw/s4+Dzp54R+hkkZYH00lmgk1a4qBhBApnaP8NdisM+GxBy6AJQVVW7Ett54QOB43jwoi6NfYBSeBdmmMBsj1im1ndxAy7zPSRN8nfuyAn3uIlg1BGYmwxozO/4V3Ftil32UpKLb1TEAU4Gtcat3b5c1P/JztbtM8zfA5hlXt4QNfWGWDAp0QWqQRd314byAX9j1NwtkxIPsBSTgy/SSeTsdr61scm2xaEOxVufvxfM6pirYuqVauu1iGdQcnRzslpOO8P1Up6hyM6xHuRKJ6rUoUG1h6UHoY9OuzkRVKmaxsncPoueMiKrwuKdWFrLggZtIO927pRWIrVlkaTS3LMKdbSVR+OFNOQD82w/u1H5DbyWAsD
 [...]
-    </DataTransfer>
-  </body>
-</ebicsUnsecuredRequest>
diff --git a/sandbox/src/test/resources/HIA.xml 
b/sandbox/src/test/resources/hia_request.xml
similarity index 100%
rename from sandbox/src/test/resources/HIA.xml
rename to sandbox/src/test/resources/hia_request.xml
diff --git a/sandbox/src/test/resources/hia_request_order_data.xml 
b/sandbox/src/test/resources/hia_request_order_data.xml
new file mode 100644
index 0000000..cd1f4e4
--- /dev/null
+++ b/sandbox/src/test/resources/hia_request_order_data.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<HIARequestOrderData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="urn:org:ebics:H004 ebics_orders_H004.xsd" 
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"; xmlns="urn:org:ebics:H004">
+    <AuthenticationPubKeyInfo>
+        <PubKeyValue>
+            <ds:RSAKeyValue>
+                
<ds:Modulus>0Ekicvrcj2+8tsF+DZsWihl9W7AyVwtMLxq3qefSWagpfnV7BVsKYIJ/OhiWpvr3dz6K5lHSatzhG1x//jrZt6VHn5Wkkb0M0vayPUiZbe5s2aLabqfOTrt8TPnHwjZMChDHRmGoKI0OzLyQJ6MIfQrHZ5t61ccWubYO/bgbSnP9H39k8QEp0kmW4Tf4u+28GTLgueNAaaPTdCozZjrST4fH9nyhBUZ3nl+vZ+AiUNdl5UfV109CXhCm3safLboUus6ZcYLm6gTaiwJEdRX7HYbnAQZ5gcoXVz/oyxJqTkicVOLPrTAfi3UmFrnIVF8XBtOPdIXHzSpxZ3yT8gH4zQ==</ds:Modulus>
+                <ds:Exponent>AQAB</ds:Exponent>
+            </ds:RSAKeyValue>
+        </PubKeyValue>
+        <AuthenticationVersion>X002</AuthenticationVersion>
+    </AuthenticationPubKeyInfo>
+    <EncryptionPubKeyInfo>
+        <PubKeyValue>
+            <ds:RSAKeyValue>
+                
<ds:Modulus>0Ekicvrcj2+8tsF+DZsWihl9W7AyVwtMLxq3qefSWagpfnV7BVsKYIJ/OhiWpvr3dz6K5lHSatzhG1x//jrZt6VHn5Wkkb0M0vayPUiZbe5s2aLabqfOTrt8TPnHwjZMChDHRmGoKI0OzLyQJ6MIfQrHZ5t61ccWubYO/bgbSnP9H39k8QEp0kmW4Tf4u+28GTLgueNAaaPTdCozZjrST4fH9nyhBUZ3nl+vZ+AiUNdl5UfV109CXhCm3safLboUus6ZcYLm6gTaiwJEdRX7HYbnAQZ5gcoXVz/oyxJqTkicVOLPrTAfi3UmFrnIVF8XBtOPdIXHzSpxZ3yT8gH4zQ==</ds:Modulus>
+                <ds:Exponent>AQAB</ds:Exponent>
+            </ds:RSAKeyValue>
+        </PubKeyValue>
+        <EncryptionVersion>E002</EncryptionVersion>
+    </EncryptionPubKeyInfo>
+    <PartnerID>PARTNER1</PartnerID>
+    <UserID>USER1</UserID>
+</HIARequestOrderData>
\ No newline at end of file
diff --git a/sandbox/src/test/resources/HPB.xml 
b/sandbox/src/test/resources/hpb_request.xml
similarity index 100%
rename from sandbox/src/test/resources/HPB.xml
rename to sandbox/src/test/resources/hpb_request.xml

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



reply via email to

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