XmlTest.kt (5445B)
1 /* 2 * This file is part of LibEuFin. 3 * Copyright (C) 2024-2025 Taler Systems S.A. 4 5 * LibEuFin is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation; either version 3, or 8 * (at your option) any later version. 9 10 * LibEuFin is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General 13 * Public License for more details. 14 15 * You should have received a copy of the GNU Affero General Public 16 * License along with LibEuFin; see the file COPYING. If not, see 17 * <http://www.gnu.org/licenses/> 18 */ 19 20 import kotlin.test.* 21 import org.w3c.dom.Document 22 import org.junit.Test 23 import tech.libeufin.ebics.* 24 import tech.libeufin.common.asUtf8 25 import tech.libeufin.common.crypto.CryptoUtil 26 import tech.libeufin.common.decodeBase64 27 import tech.libeufin.ebics.XMLUtil 28 import java.security.KeyPairGenerator 29 30 class XmlCombinatorsTest { 31 fun testBuilder(expected: String, root: String, builder: XmlBuilder.() -> Unit): Document { 32 val toBytes = XmlBuilder.toBytes(root, builder) 33 val toDom = XmlBuilder.toDom(root, null, builder) 34 //assertEquals(expected, toString) TODO fix empty tag being closed only with toString 35 assertEquals(expected, XMLUtil.convertDomToBytes(toDom).asUtf8()) 36 return toDom 37 } 38 39 @Test 40 fun testWithModularity() { 41 fun module(base: XmlBuilder) { 42 base.el("module") 43 } 44 testBuilder( 45 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><root><module/></root>", 46 "root" 47 ) { 48 module(this) 49 } 50 } 51 52 @Test 53 fun testWithIterable() { 54 testBuilder( 55 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><iterable><endOfDocument><e1><e11>111</e11></e1><e2><e22>222</e22></e2><e3><e33>333</e33></e3><e4><e44>444</e44></e4><e5><e55>555</e55></e5><e6><e66>666</e66></e6><e7><e77>777</e77></e7><e8><e88>888</e88></e8><e9><e99>999</e99></e9><e10><e1010>101010</e1010></e10></endOfDocument></iterable>", 56 "iterable" 57 ) { 58 el("endOfDocument") { 59 for (i in 1..10) 60 el("e$i/e$i$i", "$i$i$i") 61 } 62 } 63 } 64 65 @Test 66 fun testBasicXmlBuilding() { 67 testBuilder( 68 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><ebicsRequest version=\"H004\"><a><b><c attribute-of=\"c\"><d><e><f nested=\"true\"><g><h/></g></f></e></d></c></b></a><one_more/></ebicsRequest>", 69 "ebicsRequest" 70 ) { 71 attr("version", "H004") 72 el("a/b/c") { 73 attr("attribute-of", "c") 74 el("d/e/f") { 75 attr("nested", "true") 76 el("g/h") 77 } 78 } 79 el("one_more") 80 } 81 } 82 83 @Test 84 fun signed() { 85 val trapped = XmlBuilder.toDom("document", "urn:org:ebics:test") { 86 el("order") { 87 text("not signed") 88 } 89 el("order") { 90 attr("authenticate", "true") 91 text("signed") 92 } 93 el("order") { 94 attr("authenticate", "false") 95 text("not signed 2") 96 } 97 } 98 XmlDestructor.parse(trapped, "document") { 99 assertEquals(3, map("order") { text() }.size) 100 one("order", signed = true) { 101 assertEquals("signed", text()) 102 } 103 } 104 } 105 } 106 107 class XmlUtilTest { 108 109 @Test 110 fun basicSigningTest() { 111 val doc = XMLUtil.parseIntoDom(""" 112 <myMessage xmlns:ebics="urn:org:ebics:H004"> 113 <ebics:AuthSignature /> 114 <foo authenticate="true">Hello World</foo> 115 </myMessage> 116 """.trimIndent().toByteArray().inputStream()) 117 val kpg = KeyPairGenerator.getInstance("RSA") 118 kpg.initialize(2048) 119 val pair = kpg.genKeyPair() 120 val otherPair = kpg.genKeyPair() 121 XMLUtil.signEbicsDocument(doc, pair.private) 122 XMLUtil.verifyEbicsDocument(doc, pair.public) 123 assertFails { XMLUtil.verifyEbicsDocument(doc, otherPair.public) } 124 } 125 126 @Test 127 fun multiAuthSigningTest() { 128 val doc = XMLUtil.parseIntoDom(""" 129 <myMessage xmlns:ebics="urn:org:ebics:H004"> 130 <ebics:AuthSignature /> 131 <foo authenticate="true">Hello World</foo> 132 <bar authenticate="true">Another one!</bar> 133 </myMessage> 134 """.trimIndent().toByteArray().inputStream()) 135 val kpg = KeyPairGenerator.getInstance("RSA") 136 kpg.initialize(2048) 137 val pair = kpg.genKeyPair() 138 XMLUtil.signEbicsDocument(doc, pair.private) 139 XMLUtil.verifyEbicsDocument(doc, pair.public) 140 } 141 142 @Test 143 fun testRefSignature() { 144 val classLoader = ClassLoader.getSystemClassLoader() 145 val docText = classLoader.getResourceAsStream("signature1/doc.xml") 146 val doc = XMLUtil.parseIntoDom(docText) 147 val keyStream = classLoader.getResourceAsStream("signature1/public_key.txt") 148 val keyBytes = keyStream.decodeBase64().readAllBytes() 149 val key = CryptoUtil.loadRSAPublic(keyBytes) 150 XMLUtil.verifyEbicsDocument(doc, key) 151 } 152 }