gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] 02/03: signing / verification WIP


From: gnunet
Subject: [libeufin] 02/03: signing / verification WIP
Date: Mon, 28 Oct 2019 22:46:42 +0100

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

dold pushed a commit to branch master
in repository libeufin.

commit 264d6c496a6df8b32a5c7aca7b9ecce1947d3998
Author: Florian Dold <address@hidden>
AuthorDate: Mon Oct 28 18:37:39 2019 +0100

    signing / verification WIP
---
 sandbox/build.gradle                            |  2 ++
 sandbox/src/main/kotlin/Main.kt                 | 16 +++++-----
 sandbox/src/main/kotlin/{XML.kt => XMLUtil.kt}  | 42 ++++++++++++++++++-------
 sandbox/src/test/kotlin/HiaLoadTest.kt          |  4 +--
 sandbox/src/test/kotlin/JaxbTest.kt             |  4 +--
 sandbox/src/test/kotlin/MarshalNonJaxbTest.kt   |  2 +-
 sandbox/src/test/kotlin/ResponseTest.kt         |  2 +-
 sandbox/src/test/kotlin/XmlSigTest.kt           | 24 +++++---------
 sandbox/src/test/kotlin/XmlTest.kt              |  5 +--
 sandbox/src/test/kotlin/XsiTypeAttributeTest.kt |  6 ++--
 10 files changed, 58 insertions(+), 49 deletions(-)

diff --git a/sandbox/build.gradle b/sandbox/build.gradle
index 4c14e89..912ec8c 100644
--- a/sandbox/build.gradle
+++ b/sandbox/build.gradle
@@ -33,6 +33,8 @@ dependencies {
     compile "javax.activation:activation:1.1"
     compile "org.glassfish.jaxb:jaxb-runtime:2.3.1"
     testCompile group: 'junit', name: 'junit', version: '4.12'
+    testImplementation 'org.jetbrains.kotlin:kotlin-test-junit:1.3.50'
+    testImplementation 'org.jetbrains.kotlin:kotlin-test:1.3.50'
     compile 'org.apache.santuario:xmlsec:2.1.4'
     runtime rootProject.files("resources")
 }
diff --git a/sandbox/src/main/kotlin/Main.kt b/sandbox/src/main/kotlin/Main.kt
index 4cca079..9e64892 100644
--- a/sandbox/src/main/kotlin/Main.kt
+++ b/sandbox/src/main/kotlin/Main.kt
@@ -36,6 +36,7 @@ import io.ktor.routing.post
 import io.ktor.routing.routing
 import io.ktor.server.engine.embeddedServer
 import io.ktor.server.netty.Netty
+import io.ktor.util.pipeline.PipelineContext
 import org.jetbrains.exposed.dao.EntityID
 import org.jetbrains.exposed.sql.transactions.transaction
 import org.slf4j.LoggerFactory
@@ -48,17 +49,15 @@ import java.math.BigInteger
 import java.nio.charset.StandardCharsets.US_ASCII
 import java.text.DateFormat
 import java.security.KeyFactory
-import java.security.KeyPairGenerator
 import java.security.PrivateKey
 import java.security.PublicKey
-import java.security.interfaces.RSAPrivateKey
 import java.security.spec.RSAPrivateKeySpec
 import java.security.spec.RSAPublicKeySpec
 import java.util.*
 import java.util.zip.InflaterInputStream
 
 val logger = LoggerFactory.getLogger("tech.libeufin.sandbox")
-val xmlProcess = XML()
+val xmlProcess = XMLUtil()
 val getEbicsHostId = {"LIBEUFIN-SANDBOX"}
 val getEbicsVersion = {"H004"}
 val getEbicsRevision = {1}
@@ -149,7 +148,7 @@ object OkHelper {
  * @return the modified document
  */
 fun downcastXml(document: Document, node: String, type: String) : Document {
-    logger.debug("Downcasting: ${XML.convertDomToString(document)}")
+    logger.debug("Downcasting: ${XMLUtil.convertDomToString(document)}")
     val x: Element = document.getElementsByTagNameNS(
         "urn:org:ebics:H004",
         "OrderDetails"
@@ -234,7 +233,7 @@ private suspend fun ApplicationCall.adminCustomers() {
     logger.info(body.toString())
 
     val returnId = transaction {
-        var myUserId = EbicsUser.new { }
+        val myUserId = EbicsUser.new { }
         val myPartnerId = EbicsPartner.new { }
         val mySystemId = EbicsSystem.new { }
         val subscriber = EbicsSubscriber.new {
@@ -395,10 +394,10 @@ private suspend fun ApplicationCall.ebicsweb() {
     val body: String = receiveText()
     logger.debug("Data received: $body")
 
-    val bodyDocument: Document? = XML.parseStringIntoDom(body)
+    val bodyDocument: Document? = XMLUtil.parseStringIntoDom(body)
 
     if (bodyDocument == null || (!xmlProcess.validateFromDom(bodyDocument))) {
-        var response = EbicsResponse(
+        val response = EbicsResponse(
             returnCode = InvalidXmlHelper.getCode(),
             reportText = InvalidXmlHelper.getMessage()
         )
@@ -493,7 +492,7 @@ private suspend fun ApplicationCall.ebicsweb() {
              */
             if (zkey.isEmpty()) {
                 logger.info("0-length key element given, invalid request")
-                var response = KeyManagementResponse(
+                val response = KeyManagementResponse(
                     returnCode = InvalidXmlHelper.getCode(),
                     reportText = InvalidXmlHelper.getMessage("Key field was 
empty")
                 )
@@ -678,6 +677,7 @@ private suspend fun ApplicationCall.ebicsweb() {
     }
 }
 
+
 fun main() {
     dbCreateTables()
     val server = embeddedServer(Netty, port = 5000) {
diff --git a/sandbox/src/main/kotlin/XML.kt b/sandbox/src/main/kotlin/XMLUtil.kt
similarity index 89%
rename from sandbox/src/main/kotlin/XML.kt
rename to sandbox/src/main/kotlin/XMLUtil.kt
index 5d0b124..5f16bf9 100644
--- a/sandbox/src/main/kotlin/XML.kt
+++ b/sandbox/src/main/kotlin/XMLUtil.kt
@@ -42,6 +42,7 @@ import javax.xml.crypto.*
 import javax.xml.crypto.dom.DOMURIReference
 import javax.xml.crypto.dsig.*
 import javax.xml.crypto.dsig.dom.DOMSignContext
+import javax.xml.crypto.dsig.dom.DOMValidateContext
 import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec
 import javax.xml.crypto.dsig.spec.TransformParameterSpec
 import javax.xml.parsers.DocumentBuilderFactory
@@ -58,10 +59,13 @@ import javax.xml.xpath.XPathConstants
 import javax.xml.xpath.XPathFactory
 
 /**
- * This class takes care of importing XSDs and validate
- * XMLs against those.
+ * Helpers for dealing with XML in EBICS.
  */
-class XML {
+class XMLUtil {
+    /**
+     * This URI dereferencer allows handling the resource reference used for
+     * XML signatures in EBICS.
+     */
     private class EbicsSigUriDereferencer : URIDereferencer {
         override fun dereference(myRef: URIReference?, myCtx: 
XMLCryptoContext?): Data {
             val ebicsXpathExpr = "//*[@authenticate='true']"
@@ -141,15 +145,11 @@ class XML {
     fun validate(xmlDoc: StreamSource): Boolean {
         try {
             validator?.validate(xmlDoc)
-        } catch (e: SAXException) {
-            println(e.message)
-            return false
-        } catch (e: IOException) {
-            e.printStackTrace()
+        } catch (e: Exception) {
+            logger.warn("Validation failed: {}", e)
             return false
         }
-
-        return true
+        return true;
     }
 
     /**
@@ -321,6 +321,9 @@ class XML {
         }
 
 
+        /**
+         * Sign an EBICS document with the authentication and identity 
signature.
+         */
         fun signEbicsDocument(doc: Document, signingPriv: PrivateKey): Unit {
             val xpath = XPathFactory.newInstance().newXPath()
             val authSigNode = 
xpath.compile("/*[1]/AuthSignature").evaluate(doc, XPathConstants.NODE)
@@ -355,7 +358,24 @@ class XML {
         }
 
         fun verifyEbicsDocument(doc: Document, signingPub: PublicKey): Boolean 
{
-            return false
+            val xpath = XPathFactory.newInstance().newXPath()
+            val doc2: Document = doc.cloneNode(true) as Document
+            val authSigNode = 
xpath.compile("/*[1]/AuthSignature").evaluate(doc2, XPathConstants.NODE)
+            if (authSigNode !is Node)
+                throw java.lang.Exception("no AuthSignature")
+            val sigEl = 
doc2.createElementNS("http://www.w3.org/2000/09/xmldsig#";, "ds:Signature")
+            authSigNode.parentNode.insertBefore(sigEl, authSigNode)
+            while (authSigNode.hasChildNodes()) {
+                sigEl.appendChild(authSigNode.firstChild)
+            }
+            authSigNode.parentNode.removeChild(authSigNode)
+            val fac = XMLSignatureFactory.getInstance("DOM")
+            println(convertDomToString(doc2))
+            val dvc = DOMValidateContext(signingPub, sigEl)
+            dvc.uriDereferencer = EbicsSigUriDereferencer()
+            val sig = fac.unmarshalXMLSignature(dvc)
+            // FIXME: check that parameters are okay!
+            return sig.validate(dvc)
         }
     }
 }
\ No newline at end of file
diff --git a/sandbox/src/test/kotlin/HiaLoadTest.kt 
b/sandbox/src/test/kotlin/HiaLoadTest.kt
index 89810a1..bf34ccb 100644
--- a/sandbox/src/test/kotlin/HiaLoadTest.kt
+++ b/sandbox/src/test/kotlin/HiaLoadTest.kt
@@ -9,10 +9,10 @@ class HiaLoadTest {
     @Test
     fun hiaLoad() {
 
-        val processor = XML()
+        val processor = XMLUtil()
         val classLoader = ClassLoader.getSystemClassLoader()
         val hia = classLoader.getResource("HIA.xml")
-        val hiaDom = XML.parseStringIntoDom(hia.readText())
+        val hiaDom = XMLUtil.parseStringIntoDom(hia.readText())
         val x: Element = hiaDom.getElementsByTagNameNS(
             "urn:org:ebics:H004",
             "OrderDetails"
diff --git a/sandbox/src/test/kotlin/JaxbTest.kt 
b/sandbox/src/test/kotlin/JaxbTest.kt
index f4c9f90..a5a788f 100644
--- a/sandbox/src/test/kotlin/JaxbTest.kt
+++ b/sandbox/src/test/kotlin/JaxbTest.kt
@@ -7,7 +7,7 @@ import 
tech.libeufin.messages.ebics.keyrequest.SignaturePubKeyOrderDataType
 
 class JaxbTest {
 
-    val processor = XML()
+    val processor = XMLUtil()
     val classLoader = ClassLoader.getSystemClassLoader()
     val hevResponseJaxb = HEVResponse(
         "000000",
@@ -81,7 +81,7 @@ class JaxbTest {
     @Test
     fun domToJaxb() {
         val ini = 
classLoader.getResource("ebics_ini_request_sample_patched.xml")
-        val iniDom = XML.parseStringIntoDom(ini.readText())
+        val iniDom = XMLUtil.parseStringIntoDom(ini.readText())
         processor.convertDomToJaxb<EbicsUnsecuredRequest>(
             EbicsUnsecuredRequest::class.java,
             iniDom
diff --git a/sandbox/src/test/kotlin/MarshalNonJaxbTest.kt 
b/sandbox/src/test/kotlin/MarshalNonJaxbTest.kt
index cc4759b..ce88953 100644
--- a/sandbox/src/test/kotlin/MarshalNonJaxbTest.kt
+++ b/sandbox/src/test/kotlin/MarshalNonJaxbTest.kt
@@ -34,7 +34,7 @@ class MarshalNonJaxbTest {
             "EBICS_NON_OK"
         )
 
-        val proc = XML()
+        val proc = XMLUtil()
         println(proc.convertJaxbToString(obj.get()))
     }
 }
\ No newline at end of file
diff --git a/sandbox/src/test/kotlin/ResponseTest.kt 
b/sandbox/src/test/kotlin/ResponseTest.kt
index 8a5d942..d13c1c3 100644
--- a/sandbox/src/test/kotlin/ResponseTest.kt
+++ b/sandbox/src/test/kotlin/ResponseTest.kt
@@ -4,7 +4,7 @@ import org.junit.Test
 
 class ResponseTest {
 
-    val xmlprocess = XML()
+    val xmlprocess = XMLUtil()
 
     @Test
     fun loadResponse() {
diff --git a/sandbox/src/test/kotlin/XmlSigTest.kt 
b/sandbox/src/test/kotlin/XmlSigTest.kt
index e80b880..febd0b2 100644
--- a/sandbox/src/test/kotlin/XmlSigTest.kt
+++ b/sandbox/src/test/kotlin/XmlSigTest.kt
@@ -1,27 +1,16 @@
 package tech.libeufin.sandbox
 
 import org.junit.Test
-import org.w3c.dom.Node
-import org.w3c.dom.NodeList
 import java.security.KeyPairGenerator
-import java.util.*
-import javax.xml.crypto.NodeSetData
-import javax.xml.crypto.URIDereferencer
-import javax.xml.crypto.dom.DOMURIReference
-import javax.xml.crypto.dsig.*
-import javax.xml.crypto.dsig.dom.DOMSignContext
-import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec
-import javax.xml.crypto.dsig.spec.TransformParameterSpec
-import javax.xml.xpath.XPath
-import javax.xml.xpath.XPathConstants
-import javax.xml.xpath.XPathFactory
+import kotlin.test.*
+
 
 
 class XmlSigTest {
 
     @Test
     fun basicSigningTest() {
-        val doc = XML.parseStringIntoDom("""
+        val doc = XMLUtil.parseStringIntoDom("""
             <foo xmlns:ds="http://www.w3.org/2000/09/xmldsig#";>
                 <AuthSignature />
                 <bar authenticate='true'>bla</bar>Hello World
@@ -35,7 +24,10 @@ class XmlSigTest {
         val kpg = KeyPairGenerator.getInstance("RSA")
         kpg.initialize(2048)
         val pair = kpg.genKeyPair()
-        XML.signEbicsDocument(doc, pair.private)
-        println(XML.convertDomToString(doc))
+        val otherPair = kpg.genKeyPair()
+        XMLUtil.signEbicsDocument(doc, pair.private)
+        println(XMLUtil.convertDomToString(doc))
+        assertTrue(XMLUtil.verifyEbicsDocument(doc, pair.public))
+        assertFalse(XMLUtil.verifyEbicsDocument(doc, otherPair.public))
     }
 }
\ No newline at end of file
diff --git a/sandbox/src/test/kotlin/XmlTest.kt 
b/sandbox/src/test/kotlin/XmlTest.kt
index ca3176b..121e198 100644
--- a/sandbox/src/test/kotlin/XmlTest.kt
+++ b/sandbox/src/test/kotlin/XmlTest.kt
@@ -1,15 +1,12 @@
 package tech.libeufin.sandbox
 
-import org.junit.Assert
 import org.junit.Test
 import org.junit.Assert.*
-import java.io.File
-import javax.xml.transform.Source
 import javax.xml.transform.stream.StreamSource
 
 class XmlTest {
 
-    val processor = tech.libeufin.sandbox.XML()
+    val processor = tech.libeufin.sandbox.XMLUtil()
 
     @Test
     fun hevValidation(){
diff --git a/sandbox/src/test/kotlin/XsiTypeAttributeTest.kt 
b/sandbox/src/test/kotlin/XsiTypeAttributeTest.kt
index 030f9a9..84eb1eb 100644
--- a/sandbox/src/test/kotlin/XsiTypeAttributeTest.kt
+++ b/sandbox/src/test/kotlin/XsiTypeAttributeTest.kt
@@ -3,18 +3,16 @@ package tech.libeufin.sandbox
 import org.junit.Test
 import org.w3c.dom.Element
 import tech.libeufin.messages.ebics.keyrequest.EbicsUnsecuredRequest
-import tech.libeufin.messages.ebics.keyrequest.OrderDetailsType
-import tech.libeufin.messages.ebics.keyrequest.UnsecuredReqOrderDetailsType
 
 class XsiTypeAttributeTest {
 
     @Test
     fun domToJaxb() {
 
-        val processor = XML()
+        val processor = XMLUtil()
         val classLoader = ClassLoader.getSystemClassLoader()
         val ini = classLoader.getResource("ebics_ini_request_sample.xml")
-        val iniDom = XML.parseStringIntoDom(ini.readText())
+        val iniDom = XMLUtil.parseStringIntoDom(ini.readText())
         val x: Element = iniDom.getElementsByTagName("OrderDetails")?.item(0) 
as Element
 
         x.setAttributeNS(

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



reply via email to

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