From 8974c44b516772484bb4bb444f63a73b86c4f327 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Tue, 4 Jul 2023 16:34:29 +0200 Subject: [PATCH] Port WebOfTrustTest to Kotlin --- pgpainless-wot/build.gradle | 2 +- .../org/pgpainless/wot/WebOfTrustTest.java | 168 ------------------ .../org/pgpainless/wot/WebOfTrustTest.kt | 139 +++++++++++++++ 3 files changed, 140 insertions(+), 169 deletions(-) delete mode 100644 pgpainless-wot/src/test/java/org/pgpainless/wot/WebOfTrustTest.java create mode 100644 pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustTest.kt diff --git a/pgpainless-wot/build.gradle b/pgpainless-wot/build.gradle index 04baf940..49323cd2 100644 --- a/pgpainless-wot/build.gradle +++ b/pgpainless-wot/build.gradle @@ -29,7 +29,7 @@ dependencies { // JUnit testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" testImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion" + testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:$kotlinVersion" testFixturesImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" testFixturesImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion" diff --git a/pgpainless-wot/src/test/java/org/pgpainless/wot/WebOfTrustTest.java b/pgpainless-wot/src/test/java/org/pgpainless/wot/WebOfTrustTest.java deleted file mode 100644 index e19f3dff..00000000 --- a/pgpainless-wot/src/test/java/org/pgpainless/wot/WebOfTrustTest.java +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.wot; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.util.List; - -import org.bouncycastle.openpgp.PGPPublicKeyRing; -import org.junit.jupiter.api.Test; -import org.pgpainless.key.OpenPgpFingerprint; -import org.pgpainless.wot.dijkstra.sq.CertificationSet; -import org.pgpainless.wot.dijkstra.sq.Fingerprint; -import org.pgpainless.wot.dijkstra.sq.Network; -import org.pgpainless.wot.testfixtures.TestCertificateStores; -import org.pgpainless.wot.testfixtures.WotTestVectors; -import pgp.cert_d.PGPCertificateDirectory; -import pgp.certificate_store.exception.BadDataException; - -public class WebOfTrustTest { - - Fingerprint fooBankCa = fingerprintOf(WotTestVectors.getTestVectors().getFreshFooBankCaCert()); - Fingerprint fooBankEmployee = fingerprintOf(WotTestVectors.getTestVectors().getFreshFooBankEmployeeCert()); - Fingerprint fooBankAdmin = fingerprintOf(WotTestVectors.getTestVectors().getFreshFooBankAdminCert()); - Fingerprint barBankCa = fingerprintOf(WotTestVectors.getTestVectors().getFreshBarBankCaCert()); - Fingerprint barBankEmployee = fingerprintOf(WotTestVectors.getTestVectors().getFreshBarBankEmployeeCert()); - - public WebOfTrustTest() throws IOException { - - } - - private static Fingerprint fingerprintOf(PGPPublicKeyRing cert) { - return new Fingerprint(OpenPgpFingerprint.of(cert).toString()); - } - - @Test - public void testWithTwoNodesAndOneDelegation() throws BadDataException, IOException, InterruptedException { - PGPCertificateDirectory certD = TestCertificateStores.oneDelegationGraph(); - WebOfTrust wot = new WebOfTrust(certD); - wot.initialize(); - Network network = wot.getNetwork(); - - assertEquals(2, network.getNodes().size()); - - assertHasEdge(network, fooBankAdmin, barBankCa); - assertHasReverseEdge(network, fooBankAdmin, barBankCa); - - assertHasNoEdge(network, barBankCa, fooBankAdmin); - assertHasNoReverseEdge(network, barBankCa, fooBankAdmin); - } - - @Test - public void testWithCrossSignedCertificates() - throws BadDataException, IOException, InterruptedException { - PGPCertificateDirectory certD = TestCertificateStores.disconnectedGraph(); - WebOfTrust wot = new WebOfTrust(certD); - wot.initialize(); - Network network = wot.getNetwork(); - - assertEquals(5, network.getNodes().size()); - assertTrue(network.getNodes().containsKey(fooBankCa)); - assertTrue(network.getNodes().containsKey(fooBankEmployee)); - assertTrue(network.getNodes().containsKey(fooBankAdmin)); - assertTrue(network.getNodes().containsKey(barBankCa)); - assertTrue(network.getNodes().containsKey(barBankEmployee)); - - // Exemplary edge - List fooBankCaEdges = network.getEdges().get(fooBankCa); - assertEquals(2, fooBankCaEdges.size()); - - CertificationSet fbc2fbe = getEdgeFromTo(network, fooBankCa, fooBankEmployee); - assertNotNull(fbc2fbe); - CertificationSet fbc2fba = getEdgeFromTo(network, fooBankCa, fooBankAdmin); - assertNotNull(fbc2fba); - - assertHasIssuerAndTarget(fbc2fba, fooBankCa, fooBankAdmin); - assertHasIssuerAndTarget(fbc2fbe, fooBankCa, fooBankEmployee); - - assertHasEdge(network, barBankCa, barBankEmployee); - assertHasReverseEdge(network, barBankCa, barBankEmployee); - - assertHasNoEdge(network, fooBankCa, barBankCa); - assertHasNoReverseEdge(network, fooBankCa, barBankCa); - - // CHECKSTYLE:OFF - System.out.println(wot); - // CHECKSTYLE:ON - } - - private void assertHasIssuerAndTarget(CertificationSet certifications, Fingerprint issuer, Fingerprint target) { - assertEquals(issuer, certifications.getIssuer().getFingerprint()); - assertEquals(target, certifications.getTarget().getFingerprint()); - } - - private void assertHasEdge(Network network, Fingerprint issuer, Fingerprint target) { - assertNotNull(getEdgeFromTo(network, issuer, target), "Expected edge from " + issuer + " to " + target + " but got none."); - } - - private void assertHasReverseEdge(Network network, Fingerprint issuer, Fingerprint target) { - assertNotNull(getReverseEdgeFromTo(network, issuer, target), "Expected reverse edge to " + target + " from " + issuer + " but got none."); - } - - private void assertHasNoEdge(Network network, Fingerprint issuer, Fingerprint target) { - CertificationSet edge = getEdgeFromTo(network, issuer, target); - assertNull(edge, "Expected no edge from " + issuer + " to " + target + " but got " + edge); - } - - private void assertHasNoReverseEdge(Network network, Fingerprint issuer, Fingerprint target) { - CertificationSet reverseEdge = getReverseEdgeFromTo(network, issuer, target); - assertNull(reverseEdge, "Expected no reverse edge on " + target + " from " + issuer + " but got " + reverseEdge); - } - - private CertificationSet getEdgeFromTo(Network network, Fingerprint issuer, Fingerprint target) { - List edges = network.getEdges().get(issuer); - if (edges == null) { - return null; - } - - for (CertificationSet certifications : edges) { - if (target.equals(certifications.getTarget().getFingerprint())) { - return certifications; - } - } - return null; - } - - private CertificationSet getReverseEdgeFromTo(Network network, Fingerprint issuer, Fingerprint target) { - List revEdges = network.getReverseEdges().get(target); - if (revEdges == null) { - return null; - } - - for (CertificationSet certifications : revEdges) { - if (issuer.equals(certifications.getIssuer().getFingerprint())) { - return certifications; - } - } - return null; - } - - @Test - public void testWotCreationOfEmptyCertificates() { - PGPCertificateDirectory certD = TestCertificateStores.emptyGraph(); - WebOfTrust wot = new WebOfTrust(certD); - wot.initialize(); - Network network = wot.getNetwork(); - - assertTrue(network.getNodes().isEmpty()); - assertTrue(network.getEdges().isEmpty()); - assertTrue(network.getReverseEdges().isEmpty()); - } - - @Test - public void testWotWithAnomaly() throws BadDataException, IOException, InterruptedException { - PGPCertificateDirectory store = TestCertificateStores.anomalyGraph(); - WebOfTrust wot = new WebOfTrust(store); - wot.initialize(); - Network network = wot.getNetwork(); - - assertEquals(1, network.getNodes().size()); - } -} diff --git a/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustTest.kt b/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustTest.kt new file mode 100644 index 00000000..df70ee6c --- /dev/null +++ b/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustTest.kt @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: 2023 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.wot + +import org.bouncycastle.openpgp.PGPPublicKeyRing + +import org.pgpainless.key.OpenPgpFingerprint +import org.pgpainless.wot.dijkstra.sq.CertificationSet +import org.pgpainless.wot.dijkstra.sq.Fingerprint +import org.pgpainless.wot.dijkstra.sq.Network +import org.pgpainless.wot.testfixtures.TestCertificateStores +import org.pgpainless.wot.testfixtures.WotTestVectors +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull +import kotlin.test.assertTrue +import kotlin.test.Test + +class WebOfTrustTest { + + private val fooBankCa = fingerprintOf(WotTestVectors.getTestVectors().freshFooBankCaCert) + private val fooBankEmployee = fingerprintOf(WotTestVectors.getTestVectors().freshFooBankEmployeeCert) + private val fooBankAdmin = fingerprintOf(WotTestVectors.getTestVectors().freshFooBankAdminCert) + private val barBankCa = fingerprintOf(WotTestVectors.getTestVectors().freshBarBankCaCert) + private val barBankEmployee = fingerprintOf(WotTestVectors.getTestVectors().freshBarBankEmployeeCert) + + private fun fingerprintOf(cert: PGPPublicKeyRing): Fingerprint { + return Fingerprint(OpenPgpFingerprint.of(cert).toString()) + } + + @Test + fun testWithTwoNodesAndOneDelegation() { + val certD = TestCertificateStores.oneDelegationGraph() + val wot = WebOfTrust(certD) + wot.initialize() + val network = wot.network + + assertEquals(2, network.nodes.size) + assertHasEdge(network, fooBankAdmin, barBankCa) + assertHasReverseEdge(network, fooBankAdmin, barBankCa) + + assertHasNoEdge(network, barBankCa, fooBankAdmin) + assertHasNoReverseEdge(network, barBankCa, fooBankAdmin) + } + + @Test + fun testWithCrossSignedCertificates() { + val certD = TestCertificateStores.disconnectedGraph() + val wot = WebOfTrust(certD) + wot.initialize() + val network = wot.network + + assertEquals(5, network.nodes.size) + assertTrue { + listOf(fooBankCa, fooBankEmployee, fooBankAdmin, barBankCa, barBankEmployee).all { + network.nodes.containsKey(it) + } + } + + val fooBankCaEdges = network.edges[fooBankCa]!! + assertEquals(2, fooBankCaEdges.size) + + val fbc2fbe = getEdgeFromTo(network, fooBankCa, fooBankEmployee) + assertNotNull(fbc2fbe) + + val fbc2fba = getEdgeFromTo(network, fooBankCa, fooBankAdmin) + assertNotNull(fbc2fba) + + assertHasIssuerAndTarget(fbc2fbe, fooBankCa, fooBankEmployee) + assertHasIssuerAndTarget(fbc2fba, fooBankCa, fooBankAdmin) + + assertHasEdge(network, barBankCa, barBankEmployee) + assertHasReverseEdge(network, barBankCa, barBankEmployee) + + assertHasNoEdge(network, fooBankCa, barBankCa) + assertHasNoReverseEdge(network, fooBankCa, barBankCa) + } + + @Test + fun testWotCreationOfEmptyCertificates() { + val certD = TestCertificateStores.emptyGraph() + val wot = WebOfTrust(certD) + wot.initialize() + val network = wot.network + + assertTrue { network.nodes.isEmpty() } + assertTrue { network.edges.isEmpty() } + assertTrue { network.reverseEdges.isEmpty() } + } + + @Test + fun testWotWithAnomaly() { + val store = TestCertificateStores.anomalyGraph() + val wot = WebOfTrust(store) + wot.initialize() + val network = wot.network + + assertEquals(1, network.nodes.size) + } + + + private fun assertHasIssuerAndTarget( + certifications: CertificationSet, + issuer: Fingerprint, + target: Fingerprint) { + assertEquals(issuer, certifications.issuer.fingerprint) + assertEquals(target, certifications.target.fingerprint) + } + + private fun assertHasEdge(network: Network, issuer: Fingerprint, target: Fingerprint) { + assertNotNull(getEdgeFromTo(network, issuer, target), "Expected edge from $issuer to $target but got none.") + } + + private fun assertHasReverseEdge(network: Network, issuer: Fingerprint, target: Fingerprint) { + assertNotNull(getReverseEdgeFromTo(network, issuer, target), "Expected reverse edge to $target from $issuer but got none.") + } + + private fun assertHasNoEdge(network: Network, issuer: Fingerprint, target: Fingerprint) { + val edge = getEdgeFromTo(network, issuer, target) + assertNull(edge, "Expected no edge from $issuer to $target but got $edge") + } + + private fun assertHasNoReverseEdge(network: Network, issuer: Fingerprint, target: Fingerprint) { + val reverseEdge = getReverseEdgeFromTo(network, issuer, target) + assertNull(reverseEdge, "Expected no reverse edge on $target from $issuer but got $reverseEdge") + } + + private fun getEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): CertificationSet? { + val edges = network.edges[issuer] ?: return null + return edges.find { target == it.target.fingerprint } + } + + private fun getReverseEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): CertificationSet? { + val revEdges = network.reverseEdges[target] ?: return null + return revEdges.find { issuer == it.issuer.fingerprint } + } +} \ No newline at end of file