libeufin

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

commit 827b4bcfec2be5030f277119bf929ab5e6e46008
parent d213843ce31f97d68c76ffc3602b4c649a832a5e
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Fri, 18 Oct 2019 18:35:29 +0200

Storing keys as their modulus and exponent (and state).

Diffstat:
Msandbox/src/main/kotlin/DB.kt | 10++++++----
Asandbox/src/main/kotlin/INIResponse.kt | 13+++++++++++++
Msandbox/src/main/kotlin/Main.kt | 61+++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msandbox/src/test/kotlin/DbTest.kt | 4+---
4 files changed, 71 insertions(+), 17 deletions(-)

diff --git a/sandbox/src/main/kotlin/DB.kt b/sandbox/src/main/kotlin/DB.kt @@ -8,7 +8,8 @@ const val CUSTOMER_NAME_MAX_LENGTH = 20 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_LENGTH = 256 // FIXME review this value! +const val PUBLIC_KEY_MAX_MODULUS_LENGTH = 256 // FIXME review this value! +const val PUBLIC_KEY_MAX_EXPONENT_LENGTH = 256 // FIXME review this value! const val PRIV_KEY_MAX_LENGTH = 512 // FIXME review this value! const val SQL_ENUM_SUBSCRIBER_STATES = "ENUM('NEW', 'PARTIALLI_INITIALIZED_INI', 'PARTIALLY_INITIALIZED_HIA', 'INITIALIZED', 'READY')" @@ -151,7 +152,8 @@ class EbicsSystem(id: EntityID<Int>) : IntEntity(id) { * This table stores RSA public keys. */ object EbicsPublicKeys: IntIdTable() { - val pub = binary("pub", PUBLIC_KEY_MAX_LENGTH) + val modulus = binary("modulus", PUBLIC_KEY_MAX_MODULUS_LENGTH) + val exponent = binary("exponent", PUBLIC_KEY_MAX_EXPONENT_LENGTH) val state = customEnumeration( "state", "ENUM('MISSING', 'NEW', 'RELEASED')", @@ -165,7 +167,8 @@ object EbicsPublicKeys: IntIdTable() { */ class EbicsPublicKey(id: EntityID<Int>) : IntEntity(id) { companion object : IntEntityClass<EbicsPublicKey>(EbicsPublicKeys) - var pub by EbicsPublicKeys.pub + var modulus by EbicsPublicKeys.modulus + var exponent by EbicsPublicKeys.exponent var state by EbicsPublicKeys.state } @@ -175,7 +178,6 @@ class EbicsPublicKey(id: EntityID<Int>) : IntEntity(id) { */ object EbicsSubscribers: IntIdTable() { - val userId = reference("userId", EbicsUsers) val partnerId = reference("partnerId", EbicsPartners) val systemId = reference("systemId", EbicsSystems) diff --git a/sandbox/src/main/kotlin/INIResponse.kt b/sandbox/src/main/kotlin/INIResponse.kt @@ -0,0 +1,12 @@ +package tech.libeufin.sandbox + +class INIResponse( + version: String, + returnCode: String, + orderId: String, + reportText: String +) { + + // TODO!! + +} +\ No newline at end of file diff --git a/sandbox/src/main/kotlin/Main.kt b/sandbox/src/main/kotlin/Main.kt @@ -37,6 +37,7 @@ import io.ktor.routing.routing import io.ktor.server.engine.embeddedServer import io.ktor.server.netty.Netty import io.ktor.util.decodeBase64 +import org.jetbrains.exposed.dao.EntityID import org.jetbrains.exposed.sql.transactions.transaction import org.slf4j.LoggerFactory import org.w3c.dom.Document @@ -232,15 +233,6 @@ private suspend fun ApplicationCall.ebicsweb() { logger.info("Processing ${bodyDocument.documentElement.localName}") - val hostId = bodyDocument.getElementsByTagName("HostID").item(0) - if (hostId.nodeValue != getEbicsHostId()) { - respond( - HttpStatusCode.NotFound, - SandboxError("Unknown HostID specified") - ) - return - } - when (bodyDocument.documentElement.localName) { "ebicsUnsecuredRequest" -> { @@ -253,6 +245,25 @@ private suspend fun ApplicationCall.ebicsweb() { ) ) + if (bodyJaxb.value.header.static.hostID != getEbicsHostId()) { + respond( + HttpStatusCode.NotFound, + SandboxError("Unknown HostID specified") + ) + return + } + val ebicsUserID = transaction { + EbicsUser.find { EbicsUsers.userId eq bodyJaxb.value.header.static.userID }.firstOrNull() + } + if (ebicsUserID == null) { + + respond( + HttpStatusCode.NotFound, + SandboxError("Ebics UserID not found") + ) + return + } + logger.info("Serving a ${bodyJaxb.value.header.static.orderDetails.orderType} request") when (bodyJaxb.value.header.static.orderDetails.orderType) { @@ -316,7 +327,37 @@ private suspend fun ApplicationCall.ebicsweb() { return } - // At this point, key is valid, and can be stored in database + // At this point: (1) key is valid and (2) Ebics user exists (check- + // -ed above) => key can be inserted in database. + val ebicsSubscriber = transaction { + EbicsSubscriber.find { + EbicsSubscribers.userId eq EntityID(ebicsUserID.id.value, EbicsUsers) + }.firstOrNull() + } + + /** + * Should _never_ happen, as upon a EBICS' user creation, a EBICS' subscriber + * row is also (via a helper function) added into the EbicsSubscribers table. + */ + if (ebicsSubscriber == null) { + respond( + HttpStatusCode.InternalServerError, + SandboxError("Internal error, please contact customer service") + ) + return + } + + ebicsSubscriber.signatureKey = EbicsPublicKey.new { + modulus = keyObject.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.modulus + exponent = keyObject.value.signaturePubKeyInfo.pubKeyValue.rsaKeyValue.exponent + } + + logger.debug("Signature key inserted in database.") + + // return INI response! + + + } } diff --git a/sandbox/src/test/kotlin/DbTest.kt b/sandbox/src/test/kotlin/DbTest.kt @@ -36,8 +36,6 @@ class DbTest { } } - - @Test fun nestedQuery() { @@ -49,7 +47,7 @@ class DbTest { * }.first() */ - transaction { + transaction { createSubscriber() val tmp = EbicsUser.find { EbicsUsers.userId eq "u1" }.firstOrNull()