mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-09-28 18:49:56 +02:00
Merge remote-tracking branch 'hkos/heiko/tests' into wot
This commit is contained in:
commit
ae8cf33a9e
|
@ -0,0 +1,773 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Neal H. Walfield <neal@pep.foundation>, Heiko Schaefer <heiko@schaefer.name>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.pgpainless.wot.query
|
||||||
|
|
||||||
|
import org.pgpainless.wot.network.*
|
||||||
|
import org.sequoia_pgp.wot.vectors.*
|
||||||
|
import java.time.Instant
|
||||||
|
import java.util.Date
|
||||||
|
import kotlin.RuntimeException
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for the authenticate function of the Web of Trust algorithm, as outlined in
|
||||||
|
* https://gitlab.com/sequoia-pgp/sequoia-wot/-/blob/main/spec/sequoia-wot.md
|
||||||
|
*
|
||||||
|
* These tests are ported from https://gitlab.com/sequoia-pgp/sequoia-wot/-/blob/main/src/lib.rs
|
||||||
|
* by Neal H. Walfield <neal@pep.foundation>, licensed under LGPL-2.0-or-later.
|
||||||
|
*/
|
||||||
|
class AuthenticateTest {
|
||||||
|
|
||||||
|
// Authenticates the target.
|
||||||
|
private fun sp(q: Query,
|
||||||
|
targetFpr: Fingerprint,
|
||||||
|
targetUserid: String,
|
||||||
|
expected: List<Pair<Int, List<Fingerprint>>>,
|
||||||
|
minTrustAmount: Int?) {
|
||||||
|
|
||||||
|
println("Authenticating: $targetFpr, $targetUserid");
|
||||||
|
|
||||||
|
val got = q.authenticate(targetFpr, targetUserid, (minTrustAmount ?: 120))
|
||||||
|
|
||||||
|
when (Pair(got.paths.isNotEmpty(), expected.isNotEmpty())) {
|
||||||
|
Pair(false, false) -> {
|
||||||
|
println("Can't authenticate == can't authenticate (good)");
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair(false, true) -> {
|
||||||
|
throw RuntimeException("Couldn't authenticate. Expected paths: $expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair(true, false) -> {
|
||||||
|
throw RuntimeException("Unexpectedly authenticated binding. Got: $got")
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair(true, true) -> {
|
||||||
|
println("Got paths: ${got.items}")
|
||||||
|
println("Expected: $expected")
|
||||||
|
|
||||||
|
assertEquals(expected.size, got.paths.size, "Expected $expected paths, got ${got.paths} [${got.amount}]")
|
||||||
|
got.items.map { (path, amount) ->
|
||||||
|
Pair(amount, path.certificates.map { it.fingerprint }.toList())
|
||||||
|
}.zip(expected).withIndex()
|
||||||
|
.forEach { (i, b) ->
|
||||||
|
val g = b.first
|
||||||
|
var e = b.second
|
||||||
|
|
||||||
|
// Adjust test expectations: sequoia-wot returns 1-step paths for self-signed roots.
|
||||||
|
// We return a 2-step path.
|
||||||
|
if (e.second.size == 1) {
|
||||||
|
val list = e.second.toMutableList()
|
||||||
|
list.add(list[0])
|
||||||
|
e = Pair(e.first, list.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(e, g, "got vs. expected path (#$i)")
|
||||||
|
assertEquals(e.first, g.first, "got vs. expected trust amount (#$i)")
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(expected.sumOf { it.first }, got.amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: we're not checking the validity of the path on the OpenPGP layer
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun printNetwork(n: Network) {
|
||||||
|
println("Network contains " + n.nodes.size + " nodes with " + n.numberOfEdges + " edges built from "
|
||||||
|
+ n.numberOfSignatures + " signatures.")
|
||||||
|
println(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun simple() {
|
||||||
|
val t = SimpleVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
sp(q1, t.aliceFpr, t.aliceUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(100, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
sp(q1, t.daveFpr, t.daveUid, listOf(Pair(100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr))), null)
|
||||||
|
sp(q1, t.ellenFpr, t.ellenUid, listOf(), null)
|
||||||
|
sp(q1, t.frankFpr, t.frankUid, listOf(), null)
|
||||||
|
sp(q1, t.carolFpr, t.bobUid, listOf(), null) // No one authenticated Bob's User ID on Carol's key.
|
||||||
|
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
|
||||||
|
sp(q2, t.aliceFpr, t.aliceUid, listOf(), null)
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.bobFpr))), null)
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(Pair(100, listOf(t.bobFpr, t.carolFpr))), null)
|
||||||
|
sp(q2, t.daveFpr, t.daveUid, listOf(Pair(100, listOf(t.bobFpr, t.carolFpr, t.daveFpr))), null)
|
||||||
|
sp(q2, t.ellenFpr, t.ellenUid, listOf(), null)
|
||||||
|
sp(q2, t.frankFpr, t.frankUid, listOf(), null)
|
||||||
|
sp(q2, t.carolFpr, t.bobUid, listOf(), null) // No one authenticated Bob's User ID on Carol's key.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun cycle() {
|
||||||
|
val t = CycleVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
sp(q1, t.aliceFpr, t.aliceUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
sp(q1, t.daveFpr, t.daveUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr))), null)
|
||||||
|
sp(q1, t.edFpr, t.edUid, listOf(Pair(30, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr, t.edFpr))), null)
|
||||||
|
sp(q1, t.frankFpr, t.frankUid, listOf(), null)
|
||||||
|
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.aliceFpr), Root(t.daveFpr))), false)
|
||||||
|
|
||||||
|
sp(q2, t.aliceFpr, t.aliceUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
|
||||||
|
// The following paths are identical and the sorting depends on the fingerprint.
|
||||||
|
// Thus, regenerating the keys could create a failure.
|
||||||
|
sp(q2, t.bobFpr, t.bobUid,
|
||||||
|
listOf(Pair(120, listOf(t.aliceFpr, t.bobFpr)),
|
||||||
|
Pair(120, listOf(t.daveFpr, t.bobFpr))),
|
||||||
|
300)
|
||||||
|
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
sp(q2, t.edFpr, t.edUid, listOf(Pair(30, listOf(t.daveFpr, t.edFpr))), null)
|
||||||
|
sp(q2, t.frankFpr, t.frankUid, listOf(Pair(30, listOf(t.daveFpr, t.edFpr, t.frankFpr))), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun cliques() {
|
||||||
|
val t1 = CliquesVectors()
|
||||||
|
val n1 = t1.getNetworkAt()
|
||||||
|
printNetwork(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(listOf(Root(t1.rootFpr))), false)
|
||||||
|
|
||||||
|
// root -> a-0 -> a-1 -> b-0 -> ... -> f-0 -> target
|
||||||
|
sp(q1, t1.targetFpr, t1.targetUid,
|
||||||
|
listOf(Pair(120, listOf(t1.rootFpr, t1.a0Fpr, t1.a1Fpr, t1.b0Fpr, t1.b1Fpr, t1.c0Fpr, t1.c1Fpr, t1.d0Fpr, t1.d1Fpr, t1.e0Fpr, t1.f0Fpr, t1.targetFpr))),
|
||||||
|
null)
|
||||||
|
|
||||||
|
val q2 = Query(n1, Roots(listOf(Root(t1.a1Fpr))), false)
|
||||||
|
|
||||||
|
sp(q2, t1.targetFpr, t1.targetUid,
|
||||||
|
listOf(Pair(120, listOf(t1.a1Fpr, t1.b0Fpr, t1.b1Fpr, t1.c0Fpr, t1.c1Fpr, t1.d0Fpr, t1.d1Fpr, t1.e0Fpr, t1.f0Fpr, t1.targetFpr))),
|
||||||
|
null)
|
||||||
|
|
||||||
|
val t2 = CliquesLocalOptimaVectors()
|
||||||
|
val n2 = t2.getNetworkAt()
|
||||||
|
printNetwork(n2)
|
||||||
|
|
||||||
|
val q3 = Query(n2, Roots(listOf(Root(t2.rootFpr))), false)
|
||||||
|
|
||||||
|
// root -> b-0 -> ... -> f-0 -> target
|
||||||
|
sp(q3, t2.targetFpr, t2.targetUid,
|
||||||
|
listOf(Pair(30, listOf(t2.rootFpr, t2.b0Fpr, t2.b1Fpr, t2.c0Fpr, t2.c1Fpr, t2.d0Fpr, t2.d1Fpr, t2.e0Fpr, t2.f0Fpr, t2.targetFpr)),
|
||||||
|
Pair(30, listOf(t2.rootFpr, t2.a1Fpr, t2.b0Fpr, t2.b1Fpr, t2.c0Fpr, t2.c1Fpr, t2.d0Fpr, t2.d1Fpr, t2.e0Fpr, t2.f0Fpr, t2.targetFpr)),
|
||||||
|
Pair(60, listOf(t2.rootFpr, t2.a0Fpr, t2.a1Fpr, t2.b0Fpr, t2.b1Fpr, t2.c0Fpr, t2.c1Fpr, t2.d0Fpr, t2.d1Fpr, t2.e0Fpr, t2.f0Fpr, t2.targetFpr))),
|
||||||
|
null)
|
||||||
|
|
||||||
|
val q4 = Query(n2, Roots(listOf(Root(t2.a1Fpr))), false)
|
||||||
|
|
||||||
|
sp(q4, t2.targetFpr, t2.targetUid,
|
||||||
|
listOf(Pair(120, listOf(t2.a1Fpr, t2.b0Fpr, t2.b1Fpr, t2.c0Fpr, t2.c1Fpr, t2.d0Fpr, t2.d1Fpr, t2.e0Fpr, t2.f0Fpr, t2.targetFpr))),
|
||||||
|
null)
|
||||||
|
|
||||||
|
|
||||||
|
val t3 = CliquesLocalOptima2Vectors()
|
||||||
|
val n3 = t3.getNetworkAt()
|
||||||
|
printNetwork(n3)
|
||||||
|
|
||||||
|
val q5 = Query(n3, Roots(listOf(Root(t3.rootFpr))), false)
|
||||||
|
|
||||||
|
// root -> b-0 -> ... -> f-0 -> target
|
||||||
|
sp(q5, t3.targetFpr, t3.targetUid,
|
||||||
|
listOf(Pair(30, listOf(t3.rootFpr, t3.b0Fpr, t3.b1Fpr, t3.c1Fpr, t3.d0Fpr, t3.d1Fpr, t3.e0Fpr, t3.f0Fpr, t3.targetFpr)),
|
||||||
|
Pair(30, listOf(t3.rootFpr, t3.a1Fpr, t3.b0Fpr, t3.b1Fpr, t3.c0Fpr, t3.c1Fpr, t3.d0Fpr, t3.d1Fpr, t3.e0Fpr, t3.f0Fpr, t3.targetFpr)),
|
||||||
|
Pair(60, listOf(t3.rootFpr, t3.a0Fpr, t3.a1Fpr, t3.b0Fpr, t3.b1Fpr, t3.c0Fpr, t3.c1Fpr, t3.d0Fpr, t3.d1Fpr, t3.e0Fpr, t3.f0Fpr, t3.targetFpr))),
|
||||||
|
null)
|
||||||
|
|
||||||
|
val q6 = Query(n3, Roots(listOf(Root(t3.a1Fpr))), false)
|
||||||
|
|
||||||
|
sp(q6, t3.targetFpr, t3.targetUid,
|
||||||
|
listOf(Pair(30, listOf(t3.a1Fpr, t3.b0Fpr, t3.b1Fpr, t3.c1Fpr, t3.d0Fpr, t3.d1Fpr, t3.e0Fpr, t3.f0Fpr, t3.targetFpr)),
|
||||||
|
Pair(90, listOf(t3.a1Fpr, t3.b0Fpr, t3.b1Fpr, t3.c0Fpr, t3.c1Fpr, t3.d0Fpr, t3.d1Fpr, t3.e0Fpr, t3.f0Fpr, t3.targetFpr))),
|
||||||
|
null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun roundabout() {
|
||||||
|
val t = RoundaboutVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
sp(q1, t.aliceFpr, t.aliceUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.bobFpr, t.bobUid,
|
||||||
|
listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr)),
|
||||||
|
Pair(120, listOf(t.aliceFpr, t.carolFpr, t.daveFpr, t.elmarFpr, t.frankFpr, t.bobFpr))
|
||||||
|
),
|
||||||
|
null)
|
||||||
|
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(120, listOf(t.aliceFpr, t.carolFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.daveFpr, t.daveUid, listOf(Pair(120, listOf(t.aliceFpr, t.carolFpr, t.daveFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.elmarFpr, t.elmarUid, listOf(Pair(120, listOf(t.aliceFpr, t.carolFpr, t.daveFpr, t.elmarFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.frankFpr, t.frankUid, listOf(Pair(120, listOf(t.aliceFpr, t.carolFpr, t.daveFpr, t.elmarFpr, t.frankFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.georgeFpr, t.georgeUid,
|
||||||
|
listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.georgeFpr)),
|
||||||
|
Pair(60, listOf(t.aliceFpr, t.carolFpr, t.daveFpr, t.elmarFpr,
|
||||||
|
t.frankFpr, t.bobFpr, t.georgeFpr))),
|
||||||
|
null)
|
||||||
|
|
||||||
|
sp(q1, t.henryFpr, t.henryUid,
|
||||||
|
listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.georgeFpr, t.henryFpr)),
|
||||||
|
Pair(60, listOf(t.aliceFpr, t.carolFpr, t.daveFpr, t.elmarFpr,
|
||||||
|
t.frankFpr, t.bobFpr, t.georgeFpr, t.henryFpr))),
|
||||||
|
null)
|
||||||
|
|
||||||
|
sp(q1, t.isaacFpr, t.isaacUid,
|
||||||
|
listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.georgeFpr, t.henryFpr, t.isaacFpr))),
|
||||||
|
null)
|
||||||
|
|
||||||
|
sp(q1, t.jennyFpr, t.jennyUid, listOf(), null)
|
||||||
|
|
||||||
|
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.jennyFpr))), false)
|
||||||
|
|
||||||
|
sp(q2, t.aliceFpr, t.aliceUid, listOf(), null)
|
||||||
|
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(Pair(100, listOf(t.jennyFpr, t.elmarFpr, t.frankFpr, t.bobFpr))), null)
|
||||||
|
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(), null)
|
||||||
|
|
||||||
|
sp(q2, t.daveFpr, t.daveUid, listOf(), null)
|
||||||
|
|
||||||
|
sp(q2, t.elmarFpr, t.elmarUid, listOf(Pair(100, listOf(t.jennyFpr, t.elmarFpr))), null)
|
||||||
|
|
||||||
|
sp(q2, t.frankFpr, t.frankUid, listOf(Pair(100, listOf(t.jennyFpr, t.elmarFpr, t.frankFpr))), null)
|
||||||
|
|
||||||
|
sp(q2, t.georgeFpr, t.georgeUid,
|
||||||
|
listOf(Pair(100, listOf(t.jennyFpr, t.georgeFpr)),
|
||||||
|
Pair(100, listOf(t.jennyFpr, t.elmarFpr, t.frankFpr, t.bobFpr, t.georgeFpr))
|
||||||
|
), null)
|
||||||
|
|
||||||
|
sp(q2, t.henryFpr, t.henryUid,
|
||||||
|
listOf(Pair(100, listOf(t.jennyFpr, t.georgeFpr, t.henryFpr)),
|
||||||
|
Pair(20, listOf(t.jennyFpr, t.elmarFpr, t.frankFpr, t.bobFpr, t.georgeFpr, t.henryFpr))
|
||||||
|
), null)
|
||||||
|
|
||||||
|
sp(q2, t.isaacFpr, t.isaacUid, listOf(), null)
|
||||||
|
|
||||||
|
sp(q2, t.jennyFpr, t.jennyUid, listOf(Pair(120, listOf(t.jennyFpr))), null)
|
||||||
|
|
||||||
|
|
||||||
|
val q3 = Query(n, Roots(listOf(Root(t.aliceFpr), Root(t.jennyFpr))), false)
|
||||||
|
|
||||||
|
sp(q3, t.aliceFpr, t.aliceUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
|
||||||
|
// In the first iteration of backwards_propagate, we find two paths:
|
||||||
|
//
|
||||||
|
// A -> B (60)
|
||||||
|
// J -> E -> F -> B (100)
|
||||||
|
//
|
||||||
|
// It doesn't find:
|
||||||
|
//
|
||||||
|
// A -> C -> D -> E -> F -> B (120)
|
||||||
|
//
|
||||||
|
// Query::authenticate chooses the path rooted at J,
|
||||||
|
// because it has more trust. Then we call
|
||||||
|
// backwards_propagate again and find:
|
||||||
|
//
|
||||||
|
// A -> B (60)
|
||||||
|
//
|
||||||
|
// Finally, we call backwards a third time and find:
|
||||||
|
//
|
||||||
|
// A -> C -> D -> E -> F -> B (120 -> 20)
|
||||||
|
sp(q3, t.bobFpr, t.bobUid,
|
||||||
|
listOf(Pair(100, listOf(t.jennyFpr, t.elmarFpr, t.frankFpr, t.bobFpr)),
|
||||||
|
Pair(60, listOf(t.aliceFpr, t.bobFpr)),
|
||||||
|
Pair(20, listOf(t.aliceFpr, t.carolFpr, t.daveFpr, t.elmarFpr, t.frankFpr, t.bobFpr))
|
||||||
|
), 240)
|
||||||
|
|
||||||
|
sp(q3, t.carolFpr, t.carolUid, listOf(Pair(120, listOf(t.aliceFpr, t.carolFpr))), null)
|
||||||
|
|
||||||
|
sp(q3, t.daveFpr, t.daveUid, listOf(Pair(120, listOf(t.aliceFpr, t.carolFpr, t.daveFpr))), null)
|
||||||
|
|
||||||
|
sp(q3, t.elmarFpr, t.elmarUid, listOf(Pair(120, listOf(t.aliceFpr, t.carolFpr, t.daveFpr, t.elmarFpr))), null)
|
||||||
|
|
||||||
|
sp(q3, t.frankFpr, t.frankUid, listOf(Pair(120, listOf(t.aliceFpr, t.carolFpr, t.daveFpr, t.elmarFpr, t.frankFpr))), 240);
|
||||||
|
|
||||||
|
sp(q3, t.georgeFpr, t.georgeUid,
|
||||||
|
listOf(
|
||||||
|
Pair(100, listOf(t.jennyFpr, t.georgeFpr)),
|
||||||
|
Pair(100, listOf(t.jennyFpr, t.elmarFpr, t.frankFpr, t.bobFpr, t.georgeFpr)),
|
||||||
|
Pair(20, listOf(t.aliceFpr, t.bobFpr, t.georgeFpr)),
|
||||||
|
), 240)
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: original expectation from sequoia-wot:
|
||||||
|
// sp(q3, t.henryFpr, t.henryUid,
|
||||||
|
// listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.georgeFpr, t.henryFpr)),
|
||||||
|
// Pair(60, listOf(t.jennyFpr, t.georgeFpr, t.henryFpr))
|
||||||
|
// ), null)
|
||||||
|
|
||||||
|
// NOTE: Adjusted expectation for pgpainless.
|
||||||
|
// sequoia-wot searches for paths in a very specific way:
|
||||||
|
// backward_propagate() gets called twice in succession, from `authenticate()`, with two different search
|
||||||
|
// modes. The results get merged in a very specific way. In this test, that approach leads to a different
|
||||||
|
// distribution of trust amounts found for the two paths, which also happens to switch the ordering of the
|
||||||
|
// two paths.
|
||||||
|
// Note that the authentication result (the trust amount) remains unchanged, the total flow of 120 remains,
|
||||||
|
// it's just distributed differently between the two available paths. Both results are correct.
|
||||||
|
sp(q3, t.henryFpr, t.henryUid,
|
||||||
|
listOf(Pair(100, listOf(t.jennyFpr, t.georgeFpr, t.henryFpr)),
|
||||||
|
Pair(20, listOf(t.aliceFpr, t.bobFpr, t.georgeFpr, t.henryFpr))
|
||||||
|
), null)
|
||||||
|
|
||||||
|
|
||||||
|
sp(q3, t.isaacFpr, t.isaacUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.georgeFpr, t.henryFpr, t.isaacFpr))), null)
|
||||||
|
|
||||||
|
sp(q3, t.jennyFpr, t.jennyUid, listOf(Pair(120, listOf(t.jennyFpr))), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun localOptima() {
|
||||||
|
val t = LocalOptimaVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
sp(q1, t.aliceFpr, t.aliceUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.daveFpr, t.daveUid, listOf(Pair(50, listOf(t.aliceFpr, t.bobFpr, t.daveFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.ellenFpr, t.ellenUid,
|
||||||
|
listOf(
|
||||||
|
Pair(100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.ellenFpr)),
|
||||||
|
Pair(20, listOf(t.aliceFpr, t.bobFpr, t.daveFpr, t.ellenFpr)),
|
||||||
|
), null)
|
||||||
|
|
||||||
|
sp(q1, t.francisFpr, t.francisUid,
|
||||||
|
listOf(
|
||||||
|
Pair(75, listOf(t.aliceFpr, t.bobFpr, t.francisFpr)),
|
||||||
|
Pair(45, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.ellenFpr, t.francisFpr)),
|
||||||
|
), null)
|
||||||
|
|
||||||
|
sp(q1, t.georginaFpr, t.georginaUid, listOf(Pair(30, listOf(t.aliceFpr, t.bobFpr, t.daveFpr, t.ellenFpr, t.georginaFpr))), null)
|
||||||
|
|
||||||
|
sp(q1, t.henryFpr, t.henryUid,
|
||||||
|
listOf(
|
||||||
|
Pair(100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.ellenFpr, t.henryFpr)),
|
||||||
|
Pair(20, listOf(t.aliceFpr, t.bobFpr, t.daveFpr, t.ellenFpr, t.henryFpr)),
|
||||||
|
), null)
|
||||||
|
|
||||||
|
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
|
||||||
|
sp(q2, t.aliceFpr, t.aliceUid, listOf(), null)
|
||||||
|
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.bobFpr))), null)
|
||||||
|
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(Pair(100, listOf(t.bobFpr, t.carolFpr))), null)
|
||||||
|
|
||||||
|
sp(q2, t.daveFpr, t.daveUid, listOf(Pair(50, listOf(t.bobFpr, t.daveFpr))), null)
|
||||||
|
|
||||||
|
sp(q2, t.ellenFpr, t.ellenUid,
|
||||||
|
listOf(
|
||||||
|
Pair(100, listOf(t.bobFpr, t.carolFpr, t.ellenFpr)),
|
||||||
|
Pair(50, listOf(t.bobFpr, t.daveFpr, t.ellenFpr)),
|
||||||
|
), null)
|
||||||
|
|
||||||
|
sp(q2, t.francisFpr, t.francisUid,
|
||||||
|
listOf(
|
||||||
|
Pair(75, listOf(t.bobFpr, t.francisFpr)),
|
||||||
|
Pair(100, listOf(t.bobFpr, t.carolFpr, t.ellenFpr, t.francisFpr)),
|
||||||
|
Pair(20, listOf(t.bobFpr, t.daveFpr, t.ellenFpr, t.francisFpr)),
|
||||||
|
), 240)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun multipleUserids3() {
|
||||||
|
val t = MultipleUserIds3Vectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
sp(q1, t.frankFpr, t.frankUid,
|
||||||
|
listOf(
|
||||||
|
Pair(20, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.frankFpr)),
|
||||||
|
Pair(10, listOf(t.aliceFpr, t.bobFpr, t.daveFpr, t.edFpr, t.frankFpr)),
|
||||||
|
), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun certificationLiveness() {
|
||||||
|
val t = CertificationLivenessVectors()
|
||||||
|
|
||||||
|
for ((i, time) in listOf<Long>(1580598000, 1583103600, 1585778400).withIndex()) {
|
||||||
|
val date = Date(Instant.ofEpochSecond(time).toEpochMilli())
|
||||||
|
println("Trying at #$i $date");
|
||||||
|
|
||||||
|
val n = t.getNetworkAt(ReferenceTime.timestamp(date))
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
val amount = when (i + 1) {
|
||||||
|
1 -> 60
|
||||||
|
2 -> 120
|
||||||
|
3 -> 60
|
||||||
|
else -> throw RuntimeException("")
|
||||||
|
}
|
||||||
|
|
||||||
|
sp(q, t.carolFpr, t.carolUid, listOf(Pair(amount, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun certRevokedSoft() {
|
||||||
|
val t = CertRevokedSoftVectors()
|
||||||
|
|
||||||
|
for ((i, time) in listOf<Long>(1580598000, 1583103600, 1585778400).withIndex()) {
|
||||||
|
// At t1, soft revocations are in the future, so certifications are still valid.
|
||||||
|
//
|
||||||
|
// At t2, B is soft-revoked, so existing certifications are still valid, but we can no longer
|
||||||
|
// authenticate B.
|
||||||
|
//
|
||||||
|
// At t3, A re-certifies B and B re-certifies D. These certifications should be ignored as they are made
|
||||||
|
// after B was revoked.
|
||||||
|
|
||||||
|
val date = Date(Instant.ofEpochSecond(time).toEpochMilli())
|
||||||
|
println("Trying at #$i $date");
|
||||||
|
|
||||||
|
val n = t.getNetworkAt(ReferenceTime.timestamp(date))
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
// Consider just the code path where B is the issuer.
|
||||||
|
//
|
||||||
|
// Covers scenarios #1 at t1, #3 at t2 and t3
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
sp(q1, t.daveFpr, t.daveUid, listOf(Pair(60, listOf(t.bobFpr, t.daveFpr))), null)
|
||||||
|
|
||||||
|
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
// Consider just the code path where B is the target.
|
||||||
|
//
|
||||||
|
// Covers scenarios #2 at t1, #4 at t2 and t3.
|
||||||
|
if (i + 1 == 1) {
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
} else {
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consider the code path where B is both an issuer and a target.
|
||||||
|
//
|
||||||
|
// Covers scenarios #1 & #2 at t1, #3 & #4 at t2 and t3.
|
||||||
|
sp(q2, t.daveFpr, t.daveUid,
|
||||||
|
listOf(
|
||||||
|
Pair(60, listOf(t.aliceFpr, t.bobFpr, t.daveFpr)),
|
||||||
|
Pair(30, listOf(t.aliceFpr, t.carolFpr, t.daveFpr)),
|
||||||
|
), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun certRevokedHard() {
|
||||||
|
val t = CertRevokedHardVectors()
|
||||||
|
|
||||||
|
// At t1, B is hard revoked in the future so all certifications are invalid.
|
||||||
|
//
|
||||||
|
// At t2, B is hard revoked so all certifications are invalid.
|
||||||
|
//
|
||||||
|
// At t3, A re-certifies B and B re-certifies D. These certifications should also be ignored.
|
||||||
|
for ((i, time) in listOf<Long>(1580598000, 1583103600, 1585778400).withIndex()) {
|
||||||
|
val date = Date(Instant.ofEpochSecond(time).toEpochMilli())
|
||||||
|
println("Trying at #$i $date");
|
||||||
|
|
||||||
|
val n = t.getNetworkAt(ReferenceTime.timestamp(date))
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
// Consider just the code path where B is the issuer.
|
||||||
|
//
|
||||||
|
// Covers scenarios #5 at t1, #7 at t2 and t3
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
sp(q1, t.daveFpr, t.daveUid, listOf(), null)
|
||||||
|
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
// Consider just the code path where B is the target.
|
||||||
|
//
|
||||||
|
// Covers scenarios #6 at t1, #8 at t2 and t3.
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(), null)
|
||||||
|
|
||||||
|
// Consider the code path where B is both an issuer and a target.
|
||||||
|
//
|
||||||
|
// Covers scenarios #5 & #6 at t1, #7 & #8 at t2 and t3.
|
||||||
|
sp(q2, t.daveFpr, t.daveUid, listOf(Pair(30, listOf(t.aliceFpr, t.carolFpr, t.daveFpr))), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun certExpired() {
|
||||||
|
val t = CertExpiredVectors()
|
||||||
|
|
||||||
|
for ((i, time) in listOf<Long>(1580598000, 1583103600, 1585778400).withIndex()) {
|
||||||
|
val date = Date(Instant.ofEpochSecond(time).toEpochMilli())
|
||||||
|
println("Trying at #$i $date");
|
||||||
|
|
||||||
|
val n = t.getNetworkAt(ReferenceTime.timestamp(date))
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
// Bob as target.
|
||||||
|
// (Once Bob has expired, it can be used as a trusted introducer for prior certifications, but
|
||||||
|
// bindings cannot be authenticated.)
|
||||||
|
if (i + 1 == 1) {
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
} else {
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bob in the middle.
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
|
||||||
|
// Bob as root.
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(Pair(60, listOf(t.bobFpr, t.carolFpr))), null)
|
||||||
|
|
||||||
|
// Bob's self signature.
|
||||||
|
if (i + 1 == 1) {
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.bobFpr))), null)
|
||||||
|
} else {
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun userIdRevoked() {
|
||||||
|
val t = UserIdRevokedVectors()
|
||||||
|
|
||||||
|
// At t2, B is soft-revoked so all future certifications are invalid.
|
||||||
|
for ((i, time) in listOf<Long>(1580598000, 1583103600, 1585778400).withIndex()) {
|
||||||
|
val date = Date(Instant.ofEpochSecond(time).toEpochMilli())
|
||||||
|
println("Trying at #$i $date");
|
||||||
|
|
||||||
|
val n = t.getNetworkAt(ReferenceTime.timestamp(date))
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
// Revoked User ID on the root.
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
|
||||||
|
if (i + 1 == 1) {
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.bobFpr))), null)
|
||||||
|
} else {
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
if (i + 1 == 1) {
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
} else {
|
||||||
|
// Can't authenticate binding with a revoked User ID.
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can use a delegation even if the certification that it is a part of has had its User ID revoked.
|
||||||
|
if (i + 1 < 3) {
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
} else {
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun certificationsRevoked() {
|
||||||
|
val t = CertificationRevokedVectors()
|
||||||
|
|
||||||
|
for ((i, time) in listOf<Long>(1580598000, 1583103600, 1585778400).withIndex()) {
|
||||||
|
val date = Date(Instant.ofEpochSecond(time).toEpochMilli())
|
||||||
|
println("Trying at #$i $date");
|
||||||
|
|
||||||
|
val n = t.getNetworkAt(ReferenceTime.timestamp(date))
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
// Revoked User ID on the root.
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
sp(q1, t.aliceFpr, t.aliceUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
|
||||||
|
when (i + 1) {
|
||||||
|
1 -> {
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
2 -> {
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(), null)
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
3 -> {
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(120, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> throw RuntimeException() // unreachable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alice, not Bob, revokes Bob's user id. So when Bob is the root, the self-signature should still be good.
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.bobFpr))), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun infinityAndBeyond() {
|
||||||
|
val t = InfinityAndBeyondVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.u1Fpr))), false)
|
||||||
|
|
||||||
|
// This should always work.
|
||||||
|
sp(q1, t.u254Fpr, t.u254Uid, listOf(Pair(120, t.fprs.subList(0, 254))), null)
|
||||||
|
|
||||||
|
// This tests that depth=255 really means infinity.
|
||||||
|
sp(q1, t.u260Fpr, t.u260Uid, listOf(Pair(120, t.fprs)), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun zeroTrust() {
|
||||||
|
val t = ZeroTrustVectors()
|
||||||
|
|
||||||
|
// At t2, B is certified with a trust amount of 0. This should eliminate the path.
|
||||||
|
for ((i, time) in listOf<Long>(1580598000, 1583103600).withIndex()) {
|
||||||
|
val date = Date(Instant.ofEpochSecond(time).toEpochMilli())
|
||||||
|
println("Trying at #$i $date");
|
||||||
|
|
||||||
|
val n = t.getNetworkAt(ReferenceTime.timestamp(date))
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
if (i + 1 == 1) {
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(60, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
} else {
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start with bob and make sure that a certification by a root with a 0 trust amount is also respected.
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
|
||||||
|
if (i + 1 == 1) {
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(Pair(60, listOf(t.bobFpr, t.carolFpr))), null)
|
||||||
|
} else {
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun partiallyTrustedRoots() {
|
||||||
|
val t = SimpleVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr, 90))), false)
|
||||||
|
sp(q1, t.aliceFpr, t.aliceUid, listOf(Pair(90, listOf(t.aliceFpr))), null)
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
sp(q1, t.daveFpr, t.daveUid, listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr))), null)
|
||||||
|
sp(q1, t.ellenFpr, t.ellenUid, listOf(), null)
|
||||||
|
sp(q1, t.frankFpr, t.frankUid, listOf(), null)
|
||||||
|
|
||||||
|
// No one authenticated Bob's User ID on Carol's key.
|
||||||
|
sp(q1, t.carolFpr, t.bobUid, listOf(), null)
|
||||||
|
|
||||||
|
// Multiple partially trusted roots. Check that together they can fully certify a self-signature.
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.aliceFpr, 90), Root(t.bobFpr, 90))), false)
|
||||||
|
|
||||||
|
sp(q2, t.aliceFpr, t.aliceUid, listOf(Pair(90, listOf(t.aliceFpr))), null)
|
||||||
|
|
||||||
|
// NOTE: original expectation from sequoia-wot:
|
||||||
|
// sp(q2, t.bobFpr, t.bobUid,
|
||||||
|
// listOf(Pair(90, listOf(t.bobFpr)),
|
||||||
|
// Pair(90, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
|
||||||
|
// Our changed expectation: the order has changed because we return self-signed roots including the
|
||||||
|
// self-certification edge.
|
||||||
|
// This also happens to result in different ordering of the two paths, in this case.
|
||||||
|
sp(q2, t.bobFpr, t.bobUid,
|
||||||
|
listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr)),
|
||||||
|
Pair(90, listOf(t.bobFpr))
|
||||||
|
), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun selfSigned() {
|
||||||
|
val t = SelfSignedVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
sp(q1, t.bobFpr, t.bobUid, listOf(Pair(100, listOf(t.aliceFpr, t.bobFpr))), null)
|
||||||
|
sp(q1, t.carolFpr, t.carolUid, listOf(Pair(90, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))), null)
|
||||||
|
sp(q1, t.carolFpr, t.carolOtherOrgUid, listOf(), null)
|
||||||
|
sp(q1, t.daveFpr, t.daveUid, listOf(), null)
|
||||||
|
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.bobFpr))), false)
|
||||||
|
sp(q2, t.bobFpr, t.bobUid, listOf(Pair(120, listOf(t.bobFpr))), null)
|
||||||
|
sp(q2, t.carolFpr, t.carolUid, listOf(Pair(90, listOf(t.bobFpr, t.carolFpr))), null)
|
||||||
|
sp(q2, t.carolFpr, t.carolOtherOrgUid, listOf(Pair(90, listOf(t.bobFpr, t.carolFpr, t.carolFpr))), null)
|
||||||
|
sp(q2, t.daveFpr, t.daveUid, listOf(Pair(90, listOf(t.bobFpr, t.carolFpr, t.daveFpr))), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isolatedRoot() {
|
||||||
|
val t = IsolatedRootVectors()
|
||||||
|
|
||||||
|
for ((i, time) in listOf<Long>(1577919600, 1580598000).withIndex()) {
|
||||||
|
val date = Date(Instant.ofEpochSecond(time).toEpochMilli())
|
||||||
|
println("Trying at #$i $date");
|
||||||
|
|
||||||
|
val n = t.getNetworkAt(ReferenceTime.timestamp(date))
|
||||||
|
printNetwork(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(listOf(Root(t.aliceFpr))), false)
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
sp(q1, t.aliceFpr, t.aliceUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
} else {
|
||||||
|
sp(q1, t.aliceFpr, t.aliceUid, listOf(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
sp(q1, t.aliceFpr, t.aliceOtherOrgUid, listOf(Pair(120, listOf(t.aliceFpr))), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,544 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Neal H. Walfield <neal@pep.foundation>, Heiko Schaefer <heiko@schaefer.name>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.pgpainless.wot.query
|
||||||
|
|
||||||
|
import org.pgpainless.wot.network.Fingerprint
|
||||||
|
import org.pgpainless.wot.network.Root
|
||||||
|
import org.pgpainless.wot.network.Roots
|
||||||
|
import org.pgpainless.wot.query.Path
|
||||||
|
import org.sequoia_pgp.wot.vectors.*
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
|
internal const val DEPTH_UNCONSTRAINED = 255
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for the backward propagation function of the Web of Trust algorithm, as outlined in
|
||||||
|
* https://gitlab.com/sequoia-pgp/sequoia-wot/-/blob/main/spec/sequoia-wot.md
|
||||||
|
*
|
||||||
|
* These tests are ported from https://gitlab.com/sequoia-pgp/sequoia-wot/-/blob/main/src/backward_propagation.rs
|
||||||
|
* by Neal H. Walfield <neal@pep.foundation>, licensed under LGPL-2.0-or-later.
|
||||||
|
*/
|
||||||
|
class BackPropagateTest {
|
||||||
|
|
||||||
|
// Compares a computed path and a trust amount with the expected result.
|
||||||
|
private fun checkResult(result: Pair<Path, Int>, residualDepth: Int, amount: Int, expectedPath: List<Fingerprint>) {
|
||||||
|
val (gotPath, gotAmount) = result;
|
||||||
|
val gotCerts: List<Fingerprint> = gotPath.certificates.map { it.fingerprint }
|
||||||
|
|
||||||
|
assertEquals(expectedPath.size, gotCerts.size)
|
||||||
|
assert(gotCerts.zip(expectedPath).none { it.first != it.second }) // FIXME: debug output?
|
||||||
|
|
||||||
|
println("got $gotPath")
|
||||||
|
println("expected $expectedPath")
|
||||||
|
|
||||||
|
assertEquals(amount, gotAmount, "Trust amount mismatch")
|
||||||
|
assertEquals(residualDepth, gotPath.residualDepth.value(), "Residual depth mismatch")
|
||||||
|
|
||||||
|
// NOTE: The Rust tests also check for validity of the path, but we're separating those concerns here.
|
||||||
|
// This package only deals with WoT calculations.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun simple() {
|
||||||
|
val t = SimpleVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n.nodes.size + " nodes with " + n.numberOfEdges + " edges built from " + n.numberOfSignatures + " signatures.")
|
||||||
|
println(n)
|
||||||
|
|
||||||
|
val q = Query(n, Roots(), false)
|
||||||
|
|
||||||
|
val a1 = q.backwardPropagate(t.ellenFpr, t.ellenUid)
|
||||||
|
checkResult(a1[t.daveFpr]!!, 1, 100, listOf(t.daveFpr, t.ellenFpr));
|
||||||
|
checkResult(a1[t.carolFpr]!!, 0, 100, listOf(t.carolFpr, t.daveFpr, t.ellenFpr));
|
||||||
|
|
||||||
|
val a2 = q.backwardPropagate(t.daveFpr, t.daveUid);
|
||||||
|
assertNull(a2[t.ellenFpr]);
|
||||||
|
checkResult(a2[t.carolFpr]!!, 1, 100, listOf(t.carolFpr, t.daveFpr));
|
||||||
|
checkResult(a2[t.bobFpr]!!, 0, 100, listOf(t.bobFpr, t.carolFpr, t.daveFpr));
|
||||||
|
checkResult(a2[t.aliceFpr]!!, 0, 100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr));
|
||||||
|
|
||||||
|
val a3 = q.backwardPropagate(t.daveFpr, t.daveUid);
|
||||||
|
assertNull(a3[t.ellenFpr]);
|
||||||
|
checkResult(a3[t.carolFpr]!!, 1, 100, listOf(t.carolFpr, t.daveFpr));
|
||||||
|
checkResult(a3[t.bobFpr]!!, 0, 100, listOf(t.bobFpr, t.carolFpr, t.daveFpr));
|
||||||
|
|
||||||
|
// This should work even though Bob is the root and the path is via Bob.
|
||||||
|
checkResult(a3[t.aliceFpr]!!, 0, 100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr));
|
||||||
|
|
||||||
|
val a4 = q.backwardPropagate(t.daveFpr, t.daveUid);
|
||||||
|
assertNull(a4[t.ellenFpr])
|
||||||
|
checkResult(a4[t.carolFpr]!!, 1, 100, listOf(t.carolFpr, t.daveFpr));
|
||||||
|
|
||||||
|
// This should work even though Carol is the root is the path is via Carol.
|
||||||
|
checkResult(a4[t.bobFpr]!!, 0, 100, listOf(t.bobFpr, t.carolFpr, t.daveFpr));
|
||||||
|
checkResult(a4[t.aliceFpr]!!, 0, 100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr));
|
||||||
|
|
||||||
|
// Try to authenticate dave's key for a User ID that no one has certified.
|
||||||
|
val a5 = q.backwardPropagate(t.daveFpr, t.ellenUid);
|
||||||
|
assertNull(a5[t.ellenFpr]);
|
||||||
|
assertNull(a5[t.daveFpr]);
|
||||||
|
assertNull(a5[t.carolFpr]);
|
||||||
|
assertNull(a5[t.bobFpr]);
|
||||||
|
assertNull(a5[t.aliceFpr]);
|
||||||
|
|
||||||
|
// A target that is not in the network.
|
||||||
|
val fpr = Fingerprint("0123456789ABCDEF0123456789ABCDEF01234567")
|
||||||
|
val a6 = q.backwardPropagate(fpr, t.ellenUid);
|
||||||
|
assertNull(a6[t.ellenFpr]);
|
||||||
|
assertNull(a6[t.daveFpr]);
|
||||||
|
assertNull(a6[t.carolFpr]);
|
||||||
|
assertNull(a6[t.bobFpr]);
|
||||||
|
assertNull(a6[t.aliceFpr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun cycle() {
|
||||||
|
val t = CycleVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n.nodes.size + " nodes with " + n.numberOfEdges + " edges built from " + n.numberOfSignatures + " signatures.")
|
||||||
|
println(n)
|
||||||
|
|
||||||
|
val q = Query(n, Roots(), false)
|
||||||
|
|
||||||
|
val a1 = q.backwardPropagate(t.frankFpr, t.frankUid);
|
||||||
|
checkResult(a1[t.edFpr]!!, 0, 120, listOf(t.edFpr, t.frankFpr));
|
||||||
|
checkResult(a1[t.daveFpr]!!, 0, 30, listOf(t.daveFpr, t.edFpr, t.frankFpr));
|
||||||
|
checkResult(a1[t.carolFpr]!!, 0, 30, listOf(t.carolFpr, t.daveFpr, t.edFpr, t.frankFpr));
|
||||||
|
checkResult(a1[t.bobFpr]!!, 0, 30, listOf(t.bobFpr, t.carolFpr, t.daveFpr, t.edFpr, t.frankFpr));
|
||||||
|
assertNull(a1[t.aliceFpr])
|
||||||
|
|
||||||
|
val a2 = q.backwardPropagate(t.frankFpr, t.frankUid);
|
||||||
|
checkResult(a2[t.edFpr]!!, 0, 120, listOf(t.edFpr, t.frankFpr));
|
||||||
|
checkResult(a2[t.daveFpr]!!, 0, 30, listOf(t.daveFpr, t.edFpr, t.frankFpr));
|
||||||
|
checkResult(a2[t.carolFpr]!!, 0, 30, listOf(t.carolFpr, t.daveFpr, t.edFpr, t.frankFpr));
|
||||||
|
checkResult(a2[t.bobFpr]!!, 0, 30, listOf(t.bobFpr, t.carolFpr, t.daveFpr, t.edFpr, t.frankFpr));
|
||||||
|
assertNull(a2[t.aliceFpr])
|
||||||
|
|
||||||
|
val a3 = q.backwardPropagate(t.edFpr, t.edUid);
|
||||||
|
assertNull(a3[t.frankFpr])
|
||||||
|
checkResult(a3[t.daveFpr]!!, 1, 30, listOf(t.daveFpr, t.edFpr));
|
||||||
|
checkResult(a3[t.carolFpr]!!, 1, 30, listOf(t.carolFpr, t.daveFpr, t.edFpr));
|
||||||
|
checkResult(a3[t.bobFpr]!!, 1, 30, listOf(t.bobFpr, t.carolFpr, t.daveFpr, t.edFpr));
|
||||||
|
checkResult(a3[t.aliceFpr]!!, 0, 30, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr, t.edFpr));
|
||||||
|
|
||||||
|
val a4 = q.backwardPropagate(t.carolFpr, t.carolUid);
|
||||||
|
assertNull(a4[t.frankFpr]);
|
||||||
|
assertNull(a4[t.edFpr]);
|
||||||
|
checkResult(a4[t.daveFpr]!!, DEPTH_UNCONSTRAINED, 90, listOf(t.daveFpr, t.bobFpr, t.carolFpr));
|
||||||
|
checkResult(a4[t.bobFpr]!!, DEPTH_UNCONSTRAINED, 90, listOf(t.bobFpr, t.carolFpr));
|
||||||
|
|
||||||
|
// The backward propagation algorithm doesn't know that alice
|
||||||
|
// is not reachable from the root (dave).
|
||||||
|
checkResult(a4[t.aliceFpr]!!, 2, 90, listOf(t.aliceFpr, t.bobFpr, t.carolFpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun cliques() {
|
||||||
|
val t1 = CliquesVectors()
|
||||||
|
val n1 = t1.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n1.nodes.size + " nodes with " + n1.numberOfEdges + " edges built from " + n1.numberOfSignatures + " signatures.")
|
||||||
|
println(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(), false)
|
||||||
|
val a1 = q1.backwardPropagate(t1.targetFpr, t1.targetUid);
|
||||||
|
|
||||||
|
// root -> a-0 -> b-0 -> ... -> f-0 -> target
|
||||||
|
checkResult(a1[t1.rootFpr]!!, 90, 120,
|
||||||
|
listOf(t1.rootFpr,
|
||||||
|
t1.a0Fpr,
|
||||||
|
t1.a1Fpr,
|
||||||
|
t1.b0Fpr,
|
||||||
|
t1.b1Fpr,
|
||||||
|
t1.c0Fpr,
|
||||||
|
t1.c1Fpr,
|
||||||
|
t1.d0Fpr,
|
||||||
|
t1.d1Fpr,
|
||||||
|
t1.e0Fpr,
|
||||||
|
t1.f0Fpr,
|
||||||
|
t1.targetFpr));
|
||||||
|
|
||||||
|
val t2 = CliquesLocalOptimaVectors()
|
||||||
|
val n2 = t2.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n2.nodes.size + " nodes with " + n2.numberOfEdges + " edges built from " + n2.numberOfSignatures + " signatures.")
|
||||||
|
println(n2)
|
||||||
|
|
||||||
|
val q2 = Query(n2, Roots(), false)
|
||||||
|
val a2 = q2.backwardPropagate(t2.targetFpr, t2.targetUid);
|
||||||
|
|
||||||
|
// root -> a-0 -> b-0 -> ... -> f-0 -> target
|
||||||
|
checkResult(a2[t2.rootFpr]!!,
|
||||||
|
93, 30,
|
||||||
|
listOf(t2.rootFpr,
|
||||||
|
t2.b0Fpr,
|
||||||
|
t2.b1Fpr,
|
||||||
|
t2.c0Fpr,
|
||||||
|
t2.c1Fpr,
|
||||||
|
t2.d0Fpr,
|
||||||
|
t2.d1Fpr,
|
||||||
|
t2.e0Fpr,
|
||||||
|
t2.f0Fpr,
|
||||||
|
t2.targetFpr));
|
||||||
|
|
||||||
|
val t3 = CliquesLocalOptima2Vectors()
|
||||||
|
val n3 = t3.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n3.nodes.size + " nodes with " + n3.numberOfEdges + " edges built from " + n3.numberOfSignatures + " signatures.")
|
||||||
|
println(n3)
|
||||||
|
|
||||||
|
val q3 = Query(n3, Roots(), false)
|
||||||
|
val a3 = q3.backwardPropagate(t3.targetFpr, t3.targetUid);
|
||||||
|
|
||||||
|
// root -> a-0 -> b-0 -> ... -> f-0 -> target
|
||||||
|
checkResult(a3[t3.rootFpr]!!, 94, 30,
|
||||||
|
listOf(t3.rootFpr,
|
||||||
|
t3.b0Fpr,
|
||||||
|
t3.b1Fpr,
|
||||||
|
t3.c1Fpr,
|
||||||
|
t3.d0Fpr,
|
||||||
|
t3.d1Fpr,
|
||||||
|
t3.e0Fpr,
|
||||||
|
t3.f0Fpr,
|
||||||
|
t3.targetFpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun roundabout() {
|
||||||
|
val t = RoundaboutVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n.nodes.size + " nodes with " + n.numberOfEdges + " edges built from " + n.numberOfSignatures + " signatures.")
|
||||||
|
println(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(), false)
|
||||||
|
val a1 = q1.backwardPropagate(t.isaacFpr, t.isaacUid);
|
||||||
|
|
||||||
|
checkResult(a1[t.aliceFpr]!!, 0, 60, listOf(t.aliceFpr, t.bobFpr, t.georgeFpr, t.henryFpr, t.isaacFpr));
|
||||||
|
assertNull(a1[t.carolFpr])
|
||||||
|
assertNull(a1[t.jennyFpr])
|
||||||
|
|
||||||
|
val a2 = q1.backwardPropagate(t.henryFpr, t.henryUid);
|
||||||
|
|
||||||
|
// The backward propagation algorithm doesn't know that jenny
|
||||||
|
// is not reachable from the root (alice).
|
||||||
|
checkResult(a2[t.jennyFpr]!!, 0, 100, listOf(t.jennyFpr, t.georgeFpr, t.henryFpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun localOptima() {
|
||||||
|
val t = LocalOptimaVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n.nodes.size + " nodes with " + n.numberOfEdges + " edges built from " + n.numberOfSignatures + " signatures.")
|
||||||
|
println(n)
|
||||||
|
|
||||||
|
val q = Query(n, Roots(), false)
|
||||||
|
|
||||||
|
val a1 = q.backwardPropagate(t.henryFpr, t.henryUid);
|
||||||
|
checkResult(a1[t.aliceFpr]!!, 0, 100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.ellenFpr, t.henryFpr));
|
||||||
|
checkResult(a1[t.bobFpr]!!, 0, 100, listOf(t.bobFpr, t.carolFpr, t.ellenFpr, t.henryFpr));
|
||||||
|
checkResult(a1[t.carolFpr]!!, 0, 100, listOf(t.carolFpr, t.ellenFpr, t.henryFpr));
|
||||||
|
checkResult(a1[t.daveFpr]!!, 0, 50, listOf(t.daveFpr, t.ellenFpr, t.henryFpr));
|
||||||
|
checkResult(a1[t.ellenFpr]!!, 0, 120, listOf(t.ellenFpr, t.henryFpr));
|
||||||
|
assertNull(a1[t.francisFpr])
|
||||||
|
assertNull(a1[t.georginaFpr])
|
||||||
|
|
||||||
|
val a2 = q.backwardPropagate(t.francisFpr, t.francisUid);
|
||||||
|
|
||||||
|
// Recall: given a choice, we prefer the forward pointer that has the least depth.
|
||||||
|
checkResult(a2[t.aliceFpr]!!, 149, 75, listOf(t.aliceFpr, t.bobFpr, t.francisFpr));
|
||||||
|
checkResult(a2[t.bobFpr]!!, 200, 75, listOf(t.bobFpr, t.francisFpr));
|
||||||
|
checkResult(a2[t.carolFpr]!!, 49, 100, listOf(t.carolFpr, t.ellenFpr, t.francisFpr));
|
||||||
|
checkResult(a2[t.daveFpr]!!, 99, 50, listOf(t.daveFpr, t.ellenFpr, t.francisFpr));
|
||||||
|
checkResult(a2[t.ellenFpr]!!, 100, 120, listOf(t.ellenFpr, t.francisFpr));
|
||||||
|
assertNull(a2[t.georginaFpr])
|
||||||
|
assertNull(a2[t.henryFpr])
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun bestViaRoot() {
|
||||||
|
val t = BestViaRootVectors()
|
||||||
|
val n = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n.nodes.size + " nodes with " + n.numberOfEdges + " edges built from " + n.numberOfSignatures + " signatures.")
|
||||||
|
println(n)
|
||||||
|
|
||||||
|
val q1 = Query(n, Roots(), false)
|
||||||
|
|
||||||
|
val a1 = q1.backwardPropagate(t.targetFpr, t.targetUid);
|
||||||
|
|
||||||
|
checkResult(a1[t.bobFpr]!!, 9, 120, listOf(t.bobFpr, t.carolFpr, t.targetFpr));
|
||||||
|
checkResult(a1[t.carolFpr]!!, 10, 120, listOf(t.carolFpr, t.targetFpr));
|
||||||
|
checkResult(a1[t.aliceFpr]!!, 8, 120, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.targetFpr));
|
||||||
|
|
||||||
|
val a2 = q1.backwardPropagate(t.targetFpr, t.targetUid);
|
||||||
|
|
||||||
|
checkResult(a2[t.aliceFpr]!!, 8, 120, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.targetFpr));
|
||||||
|
checkResult(a2[t.bobFpr]!!, 9, 120, listOf(t.bobFpr, t.carolFpr, t.targetFpr));
|
||||||
|
checkResult(a2[t.carolFpr]!!, 10, 120, listOf(t.carolFpr, t.targetFpr));
|
||||||
|
|
||||||
|
|
||||||
|
// Again, but this time we specify the roots.
|
||||||
|
val q2 = Query(n, Roots(listOf(Root(t.aliceFpr, 120))), false)
|
||||||
|
val a3 = q2.backwardPropagate(t.targetFpr, t.targetUid);
|
||||||
|
|
||||||
|
checkResult(a3[t.aliceFpr]!!, 8, 120, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.targetFpr));
|
||||||
|
|
||||||
|
// As seen above, the best path from alice to the target is via bob. But when both alice and bob are both fully
|
||||||
|
// trusted roots, the returned path is not via bob, but one that is less optimal.
|
||||||
|
val q3 = Query(n, Roots(listOf(Root(t.aliceFpr), Root(t.bobFpr))), false)
|
||||||
|
val a4 = q3.backwardPropagate(t.targetFpr, t.targetUid);
|
||||||
|
|
||||||
|
checkResult(a4[t.bobFpr]!!, 9, 120, listOf(t.bobFpr, t.carolFpr, t.targetFpr));
|
||||||
|
checkResult(a4[t.aliceFpr]!!, 8, 50, listOf(t.aliceFpr, t.yellowFpr, t.zebraFpr, t.targetFpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun regex1() {
|
||||||
|
val t = Regex1Vectors()
|
||||||
|
val n1 = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n1.nodes.size + " nodes with " + n1.numberOfEdges + " t.edges built from " + n1.numberOfSignatures + " signatures.")
|
||||||
|
println(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(), false)
|
||||||
|
|
||||||
|
// alice as root.
|
||||||
|
val a1 = q1.backwardPropagate(t.bobFpr, t.bobUid);
|
||||||
|
checkResult(a1[t.aliceFpr]!!, 3, 100, listOf(t.aliceFpr, t.bobFpr));
|
||||||
|
|
||||||
|
val a2 = q1.backwardPropagate(t.carolFpr, t.carolUid);
|
||||||
|
checkResult(a2[t.aliceFpr]!!, 1, 100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr));
|
||||||
|
|
||||||
|
val a3 = q1.backwardPropagate(t.daveFpr, t.daveUid);
|
||||||
|
|
||||||
|
// There is no path, because t.dave@example.org does not match the constraint on t.bob (domain: example.org).
|
||||||
|
assertNull(a3[t.aliceFpr])
|
||||||
|
|
||||||
|
val a4 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
|
||||||
|
// There is no path, because t.ed@example.org does not match the constraint on t.dave (domain: other.org).
|
||||||
|
assertNull(a4[t.aliceFpr])
|
||||||
|
|
||||||
|
val a5 = q1.backwardPropagate(t.frankFpr, t.frankUid)
|
||||||
|
|
||||||
|
// There is no path, because t.frank@other.org does not match the constraint on t.bob (domain: example.org).
|
||||||
|
assertNull(a5[t.aliceFpr])
|
||||||
|
|
||||||
|
|
||||||
|
// bob as root.
|
||||||
|
val a6 = q1.backwardPropagate(t.carolFpr, t.carolUid)
|
||||||
|
checkResult(a6[t.bobFpr]!!, 1, 100, listOf(t.bobFpr, t.carolFpr))
|
||||||
|
|
||||||
|
val a7 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
checkResult(a7[t.bobFpr]!!, 1, 100, listOf(t.bobFpr, t.daveFpr))
|
||||||
|
|
||||||
|
val a8 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
// There is no path, because t.ed@example.org does not match the constraint on t.dave (domain: other.org).
|
||||||
|
assertNull(a8[t.bobFpr])
|
||||||
|
|
||||||
|
val a9 = q1.backwardPropagate(t.frankFpr, t.frankUid)
|
||||||
|
checkResult(a9[t.bobFpr]!!, 0, 100, listOf(t.bobFpr, t.daveFpr, t.frankFpr))
|
||||||
|
|
||||||
|
// dave as root.
|
||||||
|
val a10 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
checkResult(a10[t.daveFpr]!!, 1, 100, listOf(t.daveFpr, t.edFpr));
|
||||||
|
|
||||||
|
val a11 = q1.backwardPropagate(t.frankFpr, t.frankUid)
|
||||||
|
checkResult(a11[t.daveFpr]!!, 1, 100, listOf(t.daveFpr, t.frankFpr))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun regex2() {
|
||||||
|
val t = Regex2Vectors()
|
||||||
|
val n1 = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n1.nodes.size + " nodes with " + n1.numberOfEdges + " t.edges built from " + n1.numberOfSignatures + " signatures.")
|
||||||
|
println(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(), false)
|
||||||
|
|
||||||
|
val a1 = q1.backwardPropagate(t.bobFpr, t.bobUid)
|
||||||
|
checkResult(a1[t.aliceFpr]!!, 7, 100, listOf(t.aliceFpr, t.bobFpr))
|
||||||
|
|
||||||
|
val a2 = q1.backwardPropagate(t.carolFpr, t.carolUid)
|
||||||
|
// There is no path, because carol@other.org does not match the constraint on carol (domain: example.org).
|
||||||
|
assertNull(a2[t.aliceFpr])
|
||||||
|
|
||||||
|
val a3 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
// There is no path, because dave@their.org does not match the constraint on carol (domain: example.org).
|
||||||
|
assertNull(a3[t.aliceFpr])
|
||||||
|
|
||||||
|
val a4 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
checkResult(a4[t.aliceFpr]!!, 4, 100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr, t.edFpr))
|
||||||
|
|
||||||
|
val a5 = q1.backwardPropagate(t.carolFpr, t.carolUid);
|
||||||
|
// There is no path, because carol@other.org does not match
|
||||||
|
// the constraint on carol (domain: example.org).
|
||||||
|
assertNull(a5[t.bobFpr])
|
||||||
|
|
||||||
|
val a6 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
// There is no path, because dave@their.org does not match the constraint on carol (domain: example.org).
|
||||||
|
assertNull(a6[t.bobFpr])
|
||||||
|
|
||||||
|
val a7 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
checkResult(a7[t.bobFpr]!!, 5, 100, listOf(t.bobFpr, t.carolFpr, t.daveFpr, t.edFpr))
|
||||||
|
|
||||||
|
val a8 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
checkResult(a8[t.carolFpr]!!, 7, 100, listOf(t.carolFpr, t.daveFpr));
|
||||||
|
|
||||||
|
val a9 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
checkResult(a9[t.carolFpr]!!, 6, 100, listOf(t.carolFpr, t.daveFpr, t.edFpr))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun regex3() {
|
||||||
|
val t = Regex3Vectors()
|
||||||
|
val n1 = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n1.nodes.size + " nodes with " + n1.numberOfEdges + " t.edges built from " + n1.numberOfSignatures + " signatures.")
|
||||||
|
println(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(), false)
|
||||||
|
|
||||||
|
// alice as root.
|
||||||
|
val a1 = q1.backwardPropagate(t.bobFpr, t.bobUid)
|
||||||
|
checkResult(a1[t.aliceFpr]!!, 3, 100, listOf(t.aliceFpr, t.bobFpr))
|
||||||
|
|
||||||
|
val a2 = q1.backwardPropagate(t.carolFpr, t.carolUid)
|
||||||
|
checkResult(a2[t.aliceFpr]!!, 1, 100, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))
|
||||||
|
|
||||||
|
val a3 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
checkResult(a3[t.aliceFpr]!!, 1, 100, listOf(t.aliceFpr, t.bobFpr, t.daveFpr))
|
||||||
|
|
||||||
|
val a4 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
// There is no path, because ed@example.org does not match the constraint on dave (domain: other.org).
|
||||||
|
assertNull(a4[t.aliceFpr])
|
||||||
|
|
||||||
|
val a5 = q1.backwardPropagate(t.frankFpr, t.frankUid)
|
||||||
|
checkResult(a5[t.aliceFpr]!!, 0, 100, listOf(t.aliceFpr, t.bobFpr, t.daveFpr, t.frankFpr))
|
||||||
|
|
||||||
|
val a6 = q1.backwardPropagate(t.georgeFpr, t.georgeUid)
|
||||||
|
assertNull(a6[t.aliceFpr])
|
||||||
|
|
||||||
|
val a7 = q1.backwardPropagate(t.henryFpr, t.henryUid)
|
||||||
|
assertNull(a7[t.aliceFpr])
|
||||||
|
|
||||||
|
|
||||||
|
// bob as root.
|
||||||
|
val a8 = q1.backwardPropagate(t.carolFpr, t.carolUid)
|
||||||
|
checkResult(a8[t.bobFpr]!!, 1, 100, listOf(t.bobFpr, t.carolFpr))
|
||||||
|
|
||||||
|
val a9 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
checkResult(a9[t.bobFpr]!!, 1, 100, listOf(t.bobFpr, t.daveFpr))
|
||||||
|
|
||||||
|
val a10 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
// There is no path, because ed@example.org does not match the constraint on dave (domain: other.org).
|
||||||
|
assertNull(a10[t.bobFpr])
|
||||||
|
|
||||||
|
val a11 = q1.backwardPropagate(t.frankFpr, t.frankUid)
|
||||||
|
checkResult(a11[t.bobFpr]!!, 0, 100, listOf(t.bobFpr, t.daveFpr, t.frankFpr))
|
||||||
|
|
||||||
|
val a12 = q1.backwardPropagate(t.georgeFpr, t.georgeUid)
|
||||||
|
checkResult(a12[t.bobFpr]!!, 0, 100, listOf(t.bobFpr, t.daveFpr, t.georgeFpr))
|
||||||
|
|
||||||
|
val a13 = q1.backwardPropagate(t.henryFpr, t.henryUid)
|
||||||
|
checkResult(a13[t.bobFpr]!!, 1, 100, listOf(t.bobFpr, t.henryFpr))
|
||||||
|
|
||||||
|
|
||||||
|
// dave as root.
|
||||||
|
val a14 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
checkResult(a14[t.daveFpr]!!, 1, 100, listOf(t.daveFpr, t.edFpr))
|
||||||
|
|
||||||
|
val a15 = q1.backwardPropagate(t.frankFpr, t.frankUid)
|
||||||
|
checkResult(a15[t.daveFpr]!!, 1, 100, listOf(t.daveFpr, t.frankFpr))
|
||||||
|
|
||||||
|
val a16 = q1.backwardPropagate(t.georgeFpr, t.georgeUid)
|
||||||
|
checkResult(a16[t.daveFpr]!!, 1, 100, listOf(t.daveFpr, t.georgeFpr))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun multipleUserids1() {
|
||||||
|
val t = MultipleUserIds1Vectors()
|
||||||
|
val n1 = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n1.nodes.size + " nodes with " + n1.numberOfEdges + " t.edges built from " + n1.numberOfSignatures + " signatures.")
|
||||||
|
println(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(), false)
|
||||||
|
|
||||||
|
val a1 = q1.backwardPropagate(t.carolFpr, t.carolUid)
|
||||||
|
checkResult(a1[t.aliceFpr]!!, 0, 70, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))
|
||||||
|
|
||||||
|
val a2 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
checkResult(a2[t.aliceFpr]!!, 0, 50, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun multipleUserids2() {
|
||||||
|
val t = MultipleUserIds2Vectors()
|
||||||
|
val n1 = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n1.nodes.size + " nodes with " + n1.numberOfEdges + " t.edges built from " + n1.numberOfSignatures + " signatures.")
|
||||||
|
println(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(), false)
|
||||||
|
|
||||||
|
|
||||||
|
val a1 = q1.backwardPropagate(t.bobFpr, t.bobUid)
|
||||||
|
checkResult(a1[t.aliceFpr]!!, DEPTH_UNCONSTRAINED, 70, listOf(t.aliceFpr, t.bobFpr))
|
||||||
|
|
||||||
|
val a2 = q1.backwardPropagate(t.bobFpr, t.bobSomeOrgUid)
|
||||||
|
checkResult(a2[t.aliceFpr]!!, 1, 50, listOf(t.aliceFpr, t.bobFpr))
|
||||||
|
|
||||||
|
val a3 = q1.backwardPropagate(t.carolFpr, t.carolUid)
|
||||||
|
checkResult(a3[t.aliceFpr]!!, 0, 50, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))
|
||||||
|
|
||||||
|
val a4 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
checkResult(a4[t.aliceFpr]!!, 0, 70, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr))
|
||||||
|
|
||||||
|
val a5 = q1.backwardPropagate(t.edFpr, t.edUid)
|
||||||
|
assertNull(a5[t.aliceFpr])
|
||||||
|
|
||||||
|
val a6 = q1.backwardPropagate(t.frankFpr, t.frankUid)
|
||||||
|
checkResult(a6[t.aliceFpr]!!, 0, 70, listOf(t.aliceFpr, t.bobFpr, t.frankFpr))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun multipleUserids3() {
|
||||||
|
val t = MultipleUserIds3Vectors()
|
||||||
|
val n1 = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n1.nodes.size + " nodes with " + n1.numberOfEdges + " edges built from " + n1.numberOfSignatures + " signatures.")
|
||||||
|
println(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(), false)
|
||||||
|
|
||||||
|
val auth = q1.backwardPropagate(t.frankFpr, t.frankUid)
|
||||||
|
checkResult(auth[t.aliceFpr]!!, 0, 20, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.frankFpr))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun multipleCertifications1() {
|
||||||
|
val t = MultipleCertifications1Vectors()
|
||||||
|
val n1 = t.getNetworkAt()
|
||||||
|
|
||||||
|
println("Network contains " + n1.nodes.size + " nodes with " + n1.numberOfEdges + " edges built from " + n1.numberOfSignatures + " signatures.")
|
||||||
|
println(n1)
|
||||||
|
|
||||||
|
val q1 = Query(n1, Roots(), false)
|
||||||
|
|
||||||
|
val a1 = q1.backwardPropagate(t.carolFpr, t.carolUid)
|
||||||
|
checkResult(a1[t.aliceFpr]!!, 0, 70, listOf(t.aliceFpr, t.bobFpr, t.carolFpr))
|
||||||
|
|
||||||
|
val a2 = q1.backwardPropagate(t.daveFpr, t.daveUid)
|
||||||
|
checkResult(a2[t.aliceFpr]!!, 0, 50, listOf(t.aliceFpr, t.bobFpr, t.carolFpr, t.daveFpr))
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ class BestViaRoot : TestCase(BestViaRootVectors()) {
|
||||||
val keyRing = tempKeyRingFile.absolutePath
|
val keyRing = tempKeyRingFile.absolutePath
|
||||||
val v = vectors as BestViaRootVectors
|
val v = vectors as BestViaRootVectors
|
||||||
val p = Runtime.getRuntime().exec(
|
val p = Runtime.getRuntime().exec(
|
||||||
"$executable --keyring=$keyRing -r ${v.alice_fpr} --full authenticate ${v.target_fpr} ${v.target_uid}",
|
"$executable --keyring=$keyRing -r ${v.aliceFpr} --full authenticate ${v.targetFpr} ${v.targetUid}",
|
||||||
env)
|
env)
|
||||||
val output = p.inputStream.let {
|
val output = p.inputStream.let {
|
||||||
val bOut = ByteArrayOutputStream()
|
val bOut = ByteArrayOutputStream()
|
||||||
|
|
|
@ -38,7 +38,7 @@ interface ArtifactVectors {
|
||||||
|
|
||||||
fun getResourceName(): String
|
fun getResourceName(): String
|
||||||
|
|
||||||
fun getNetworkAt(referenceTime: ReferenceTime, policy: Policy = PGPainless.getPolicy()): Network {
|
fun getNetworkAt(referenceTime: ReferenceTime = ReferenceTime.now(), policy: Policy = PGPainless.getPolicy()): Network {
|
||||||
val inputStream = keyRingInputStream()
|
val inputStream = keyRingInputStream()
|
||||||
val keyRing = PGPainless.readKeyRing().publicKeyRingCollection(inputStream)
|
val keyRing = PGPainless.readKeyRing().publicKeyRingCollection(inputStream)
|
||||||
val store = KeyRingCertificateStore(keyRing)
|
val store = KeyRingCertificateStore(keyRing)
|
||||||
|
|
|
@ -26,28 +26,28 @@ import org.pgpainless.wot.network.Fingerprint
|
||||||
*/
|
*/
|
||||||
class BestViaRootVectors: ArtifactVectors {
|
class BestViaRootVectors: ArtifactVectors {
|
||||||
|
|
||||||
val alice_fpr = Fingerprint("B95FF5B1D055D26F758FD4E3BF12C4D1D28FDFFB")
|
val aliceFpr = Fingerprint("B95FF5B1D055D26F758FD4E3BF12C4D1D28FDFFB")
|
||||||
val alice_uid = "<alice@example.org>"
|
val aliceUid = "<alice@example.org>"
|
||||||
|
|
||||||
val bob_fpr = Fingerprint("6A8B9EC7D0A1B297B5D4A7A1C048DFF96601D9BD")
|
val bobFpr = Fingerprint("6A8B9EC7D0A1B297B5D4A7A1C048DFF96601D9BD")
|
||||||
val bob_uid = "<bob@example.org>"
|
val bobUid = "<bob@example.org>"
|
||||||
// Certified by: B95FF5B1D055D26F758FD4E3BF12C4D1D28FDFFB
|
// Certified by: B95FF5B1D055D26F758FD4E3BF12C4D1D28FDFFB
|
||||||
|
|
||||||
val carol_fpr = Fingerprint("77A6F7D4BEE0369F70B249579D2987669F792B35")
|
val carolFpr = Fingerprint("77A6F7D4BEE0369F70B249579D2987669F792B35")
|
||||||
val carol_uid = "<carol@example.org>"
|
val carolUid = "<carol@example.org>"
|
||||||
// Certified by: 6A8B9EC7D0A1B297B5D4A7A1C048DFF96601D9BD
|
// Certified by: 6A8B9EC7D0A1B297B5D4A7A1C048DFF96601D9BD
|
||||||
|
|
||||||
val target_fpr = Fingerprint("2AB08C06FC795AC26673B23CAD561ABDCBEBFDF0")
|
val targetFpr = Fingerprint("2AB08C06FC795AC26673B23CAD561ABDCBEBFDF0")
|
||||||
val target_uid = "<target@example.org>"
|
val targetUid = "<target@example.org>"
|
||||||
// Certified by: 77A6F7D4BEE0369F70B249579D2987669F792B35
|
// Certified by: 77A6F7D4BEE0369F70B249579D2987669F792B35
|
||||||
// Certified by: 56D44411F982758169E4681B402E8D5D9D7D6567
|
// Certified by: 56D44411F982758169E4681B402E8D5D9D7D6567
|
||||||
|
|
||||||
val yellow_fpr = Fingerprint("86CB4639D1FE096BA941D05822B8AF50198C49DD")
|
val yellowFpr = Fingerprint("86CB4639D1FE096BA941D05822B8AF50198C49DD")
|
||||||
val yellow_uid = "<yellow@example.org>"
|
val yellowUid = "<yellow@example.org>"
|
||||||
// Certified by: B95FF5B1D055D26F758FD4E3BF12C4D1D28FDFFB
|
// Certified by: B95FF5B1D055D26F758FD4E3BF12C4D1D28FDFFB
|
||||||
|
|
||||||
val zebra_fpr = Fingerprint("56D44411F982758169E4681B402E8D5D9D7D6567")
|
val zebraFpr = Fingerprint("56D44411F982758169E4681B402E8D5D9D7D6567")
|
||||||
val zebra_uid = "<zebra@example.org>"
|
val zebraUid = "<zebra@example.org>"
|
||||||
// Certified by: 86CB4639D1FE096BA941D05822B8AF50198C49DD
|
// Certified by: 86CB4639D1FE096BA941D05822B8AF50198C49DD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,7 +16,7 @@ class IsolatedRootVectors: ArtifactVectors {
|
||||||
|
|
||||||
val aliceFpr = Fingerprint("DCF3020AAB76ECC7F0E5AC0D375DCE1BEE264B87")
|
val aliceFpr = Fingerprint("DCF3020AAB76ECC7F0E5AC0D375DCE1BEE264B87")
|
||||||
val aliceUid = "<alice@example.org>"
|
val aliceUid = "<alice@example.org>"
|
||||||
val aliceOtherOrguid = "<alice@other.org>"
|
val aliceOtherOrgUid = "<alice@other.org>"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A is created.
|
* A is created.
|
||||||
|
|
|
@ -26,21 +26,21 @@ import org.pgpainless.wot.network.Fingerprint
|
||||||
*/
|
*/
|
||||||
class MultipleCertifications1Vectors: ArtifactVectors {
|
class MultipleCertifications1Vectors: ArtifactVectors {
|
||||||
|
|
||||||
val alice_fpr = Fingerprint("9219941467AA737C6EC1207959A2CEFC112C359A")
|
val aliceFpr = Fingerprint("9219941467AA737C6EC1207959A2CEFC112C359A")
|
||||||
val alice_uid = "<alice@example.org>"
|
val aliceUid = "<alice@example.org>"
|
||||||
|
|
||||||
val bob_fpr = Fingerprint("72CAA0F0A4A020F5FA20CD8CB5CC04473AA88123")
|
val bobFpr = Fingerprint("72CAA0F0A4A020F5FA20CD8CB5CC04473AA88123")
|
||||||
val bob_uid = "<bob@example.org>"
|
val bobUid = "<bob@example.org>"
|
||||||
// Certified by: 9219941467AA737C6EC1207959A2CEFC112C359A
|
// Certified by: 9219941467AA737C6EC1207959A2CEFC112C359A
|
||||||
// Certified by: 9219941467AA737C6EC1207959A2CEFC112C359A
|
// Certified by: 9219941467AA737C6EC1207959A2CEFC112C359A
|
||||||
// Certified by: 9219941467AA737C6EC1207959A2CEFC112C359A
|
// Certified by: 9219941467AA737C6EC1207959A2CEFC112C359A
|
||||||
|
|
||||||
val carol_fpr = Fingerprint("853304031E7B0B116BBD0B398734F11945313904")
|
val carolFpr = Fingerprint("853304031E7B0B116BBD0B398734F11945313904")
|
||||||
val carol_uid = "<carol@example.org>"
|
val carolUid = "<carol@example.org>"
|
||||||
// Certified by: 72CAA0F0A4A020F5FA20CD8CB5CC04473AA88123
|
// Certified by: 72CAA0F0A4A020F5FA20CD8CB5CC04473AA88123
|
||||||
|
|
||||||
val dave_fpr = Fingerprint("4C77ABDBE4F855E0C3C7A7D549F6B2BFDA83E424")
|
val daveFpr = Fingerprint("4C77ABDBE4F855E0C3C7A7D549F6B2BFDA83E424")
|
||||||
val dave_uid = "<dave@example.org>"
|
val daveUid = "<dave@example.org>"
|
||||||
// Certified by: 853304031E7B0B116BBD0B398734F11945313904
|
// Certified by: 853304031E7B0B116BBD0B398734F11945313904
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -38,21 +38,21 @@ import org.pgpainless.wot.network.Fingerprint
|
||||||
*/
|
*/
|
||||||
class MultipleUserIds1Vectors: ArtifactVectors {
|
class MultipleUserIds1Vectors: ArtifactVectors {
|
||||||
|
|
||||||
val alice_fpr = Fingerprint("2A2A4A23A7EEC119BC0B46642B3825DC02A05FEA")
|
val aliceFpr = Fingerprint("2A2A4A23A7EEC119BC0B46642B3825DC02A05FEA")
|
||||||
val alice_uid = "<alice@example.org>"
|
val aliceUid = "<alice@example.org>"
|
||||||
|
|
||||||
val bob_fpr = Fingerprint("03182611B91B1E7E20B848E83DFC151ABFAD85D5")
|
val bobFpr = Fingerprint("03182611B91B1E7E20B848E83DFC151ABFAD85D5")
|
||||||
val bob_uid = "<bob@other.org>"
|
val bobUid = "<bob@other.org>"
|
||||||
// Certified by: 2A2A4A23A7EEC119BC0B46642B3825DC02A05FEA
|
// Certified by: 2A2A4A23A7EEC119BC0B46642B3825DC02A05FEA
|
||||||
val bob_some_org_uid = "<bob@some.org>"
|
val bob_some_orgUid = "<bob@some.org>"
|
||||||
// Certified by: 2A2A4A23A7EEC119BC0B46642B3825DC02A05FEA
|
// Certified by: 2A2A4A23A7EEC119BC0B46642B3825DC02A05FEA
|
||||||
|
|
||||||
val carol_fpr = Fingerprint("9CA36907B46FE7B6B9EE9601E78064C12B6D7902")
|
val carolFpr = Fingerprint("9CA36907B46FE7B6B9EE9601E78064C12B6D7902")
|
||||||
val carol_uid = "<carol@example.org>"
|
val carolUid = "<carol@example.org>"
|
||||||
// Certified by: 03182611B91B1E7E20B848E83DFC151ABFAD85D5
|
// Certified by: 03182611B91B1E7E20B848E83DFC151ABFAD85D5
|
||||||
|
|
||||||
val dave_fpr = Fingerprint("C1BC6794A6C6281B968A6A41ACE2055D610CEA03")
|
val daveFpr = Fingerprint("C1BC6794A6C6281B968A6A41ACE2055D610CEA03")
|
||||||
val dave_uid = "<dave@other.org>"
|
val daveUid = "<dave@other.org>"
|
||||||
// Certified by: 9CA36907B46FE7B6B9EE9601E78064C12B6D7902
|
// Certified by: 9CA36907B46FE7B6B9EE9601E78064C12B6D7902
|
||||||
|
|
||||||
override fun getResourceName(): String {
|
override fun getResourceName(): String {
|
||||||
|
|
|
@ -29,29 +29,29 @@ import org.pgpainless.wot.network.Fingerprint
|
||||||
*/
|
*/
|
||||||
class MultipleUserIds2Vectors: ArtifactVectors {
|
class MultipleUserIds2Vectors: ArtifactVectors {
|
||||||
|
|
||||||
val alice_fpr = Fingerprint("F1C99C4019837703DD17C45440F8A0141DF278EA")
|
val aliceFpr = Fingerprint("F1C99C4019837703DD17C45440F8A0141DF278EA")
|
||||||
val alice_uid = "<alice@example.org>"
|
val aliceUid = "<alice@example.org>"
|
||||||
|
|
||||||
val bob_fpr = Fingerprint("5528B9E5DAFC519ED2E37F0377B332E4111456CB")
|
val bobFpr = Fingerprint("5528B9E5DAFC519ED2E37F0377B332E4111456CB")
|
||||||
val bob_uid = "<bob@other.org>"
|
val bobUid = "<bob@other.org>"
|
||||||
// Certified by: F1C99C4019837703DD17C45440F8A0141DF278EA
|
// Certified by: F1C99C4019837703DD17C45440F8A0141DF278EA
|
||||||
val bob_some_org_uid = "<bob@some.org>"
|
val bobSomeOrgUid = "<bob@some.org>"
|
||||||
// Certified by: F1C99C4019837703DD17C45440F8A0141DF278EA
|
// Certified by: F1C99C4019837703DD17C45440F8A0141DF278EA
|
||||||
|
|
||||||
val carol_fpr = Fingerprint("6F8291428420AB53576BAB4BEFF6477D3E348D71")
|
val carolFpr = Fingerprint("6F8291428420AB53576BAB4BEFF6477D3E348D71")
|
||||||
val carol_uid = "<carol@example.org>"
|
val carolUid = "<carol@example.org>"
|
||||||
// Certified by: 5528B9E5DAFC519ED2E37F0377B332E4111456CB
|
// Certified by: 5528B9E5DAFC519ED2E37F0377B332E4111456CB
|
||||||
|
|
||||||
val dave_fpr = Fingerprint("62C57D90DAD253DEA01D5A86C7382FD6285C18F0")
|
val daveFpr = Fingerprint("62C57D90DAD253DEA01D5A86C7382FD6285C18F0")
|
||||||
val dave_uid = "<dave@other.org>"
|
val daveUid = "<dave@other.org>"
|
||||||
// Certified by: 6F8291428420AB53576BAB4BEFF6477D3E348D71
|
// Certified by: 6F8291428420AB53576BAB4BEFF6477D3E348D71
|
||||||
|
|
||||||
val ed_fpr = Fingerprint("0E974D0ACBA0C4D8F51D7CF68F048FF83B173504")
|
val edFpr = Fingerprint("0E974D0ACBA0C4D8F51D7CF68F048FF83B173504")
|
||||||
val ed_uid = "<ed@example.org>"
|
val edUid = "<ed@example.org>"
|
||||||
// Certified by: 6F8291428420AB53576BAB4BEFF6477D3E348D71
|
// Certified by: 6F8291428420AB53576BAB4BEFF6477D3E348D71
|
||||||
|
|
||||||
val frank_fpr = Fingerprint("5BEE3D41F85B2FCBC300DE4E18CB2BDA65465F03")
|
val frankFpr = Fingerprint("5BEE3D41F85B2FCBC300DE4E18CB2BDA65465F03")
|
||||||
val frank_uid = "<frank@other.org>"
|
val frankUid = "<frank@other.org>"
|
||||||
// Certified by: 5528B9E5DAFC519ED2E37F0377B332E4111456CB
|
// Certified by: 5528B9E5DAFC519ED2E37F0377B332E4111456CB
|
||||||
|
|
||||||
override fun getResourceName(): String {
|
override fun getResourceName(): String {
|
||||||
|
|
|
@ -28,30 +28,30 @@ import org.pgpainless.wot.network.Fingerprint
|
||||||
*/
|
*/
|
||||||
class MultipleUserIds3Vectors: ArtifactVectors {
|
class MultipleUserIds3Vectors: ArtifactVectors {
|
||||||
|
|
||||||
val alice_fpr = Fingerprint("DA3CFC60BD4B8835702A66782C7A431946C12DF7")
|
val aliceFpr = Fingerprint("DA3CFC60BD4B8835702A66782C7A431946C12DF7")
|
||||||
val alice_uid = "<alice@example.org>"
|
val aliceUid = "<alice@example.org>"
|
||||||
|
|
||||||
val bob_fpr = Fingerprint("28C108707090FCDFF630D1E141FB02F0E397D55E")
|
val bobFpr = Fingerprint("28C108707090FCDFF630D1E141FB02F0E397D55E")
|
||||||
val bob_uid = "<bob@other.org>"
|
val bobUid = "<bob@other.org>"
|
||||||
// Certified by: DA3CFC60BD4B8835702A66782C7A431946C12DF7
|
// Certified by: DA3CFC60BD4B8835702A66782C7A431946C12DF7
|
||||||
val bob_some_org_uid = "<bob@some.org>"
|
val bobSomeOrgUid = "<bob@some.org>"
|
||||||
// Certified by: DA3CFC60BD4B8835702A66782C7A431946C12DF7
|
// Certified by: DA3CFC60BD4B8835702A66782C7A431946C12DF7
|
||||||
val bob_third_org_uid = "<bob@third.org>"
|
val bobThirdOrgUid = "<bob@third.org>"
|
||||||
|
|
||||||
val carol_fpr = Fingerprint("9FB1D2F41AB5C478378E728C8DD5A5A434EEAAB8")
|
val carolFpr = Fingerprint("9FB1D2F41AB5C478378E728C8DD5A5A434EEAAB8")
|
||||||
val carol_uid = "<carol@example.org>"
|
val carolUid = "<carol@example.org>"
|
||||||
// Certified by: 28C108707090FCDFF630D1E141FB02F0E397D55E
|
// Certified by: 28C108707090FCDFF630D1E141FB02F0E397D55E
|
||||||
|
|
||||||
val dave_fpr = Fingerprint("0C131F8959F45D08B6136FDAAD2E16A26F73D48E")
|
val daveFpr = Fingerprint("0C131F8959F45D08B6136FDAAD2E16A26F73D48E")
|
||||||
val dave_uid = "<dave@example.org>"
|
val daveUid = "<dave@example.org>"
|
||||||
// Certified by: 28C108707090FCDFF630D1E141FB02F0E397D55E
|
// Certified by: 28C108707090FCDFF630D1E141FB02F0E397D55E
|
||||||
|
|
||||||
val ed_fpr = Fingerprint("296935FAE420CCCF3AEDCEC9232BFF0AE9A7E5DB")
|
val edFpr = Fingerprint("296935FAE420CCCF3AEDCEC9232BFF0AE9A7E5DB")
|
||||||
val ed_uid = "<ed@example.org>"
|
val edUid = "<ed@example.org>"
|
||||||
// Certified by: 0C131F8959F45D08B6136FDAAD2E16A26F73D48E
|
// Certified by: 0C131F8959F45D08B6136FDAAD2E16A26F73D48E
|
||||||
|
|
||||||
val frank_fpr = Fingerprint("A72AA1B7D9D8CB04D988F1520A404E37A7766608")
|
val frankFpr = Fingerprint("A72AA1B7D9D8CB04D988F1520A404E37A7766608")
|
||||||
val frank_uid = "<frank@example.org>"
|
val frankUid = "<frank@example.org>"
|
||||||
// Certified by: 9FB1D2F41AB5C478378E728C8DD5A5A434EEAAB8
|
// Certified by: 9FB1D2F41AB5C478378E728C8DD5A5A434EEAAB8
|
||||||
// Certified by: 296935FAE420CCCF3AEDCEC9232BFF0AE9A7E5DB
|
// Certified by: 296935FAE420CCCF3AEDCEC9232BFF0AE9A7E5DB
|
||||||
|
|
||||||
|
|
|
@ -27,27 +27,27 @@ import org.pgpainless.wot.network.Fingerprint
|
||||||
*/
|
*/
|
||||||
class Regex1Vectors: ArtifactVectors {
|
class Regex1Vectors: ArtifactVectors {
|
||||||
|
|
||||||
val alice_fpr = Fingerprint("3AD1F297E4B150F75DBFC43476FB81BFE0665C3A")
|
val aliceFpr = Fingerprint("3AD1F297E4B150F75DBFC43476FB81BFE0665C3A")
|
||||||
val alice_uid = "<alice@some.org>"
|
val aliceUid = "<alice@some.org>"
|
||||||
|
|
||||||
val bob_fpr = Fingerprint("20C812117FB2A3940EAE9160FEE6B4E47A096FD1")
|
val bobFpr = Fingerprint("20C812117FB2A3940EAE9160FEE6B4E47A096FD1")
|
||||||
val bob_uid = "<bob@example.org>"
|
val bobUid = "<bob@example.org>"
|
||||||
// Certified by: 3AD1F297E4B150F75DBFC43476FB81BFE0665C3A
|
// Certified by: 3AD1F297E4B150F75DBFC43476FB81BFE0665C3A
|
||||||
|
|
||||||
val carol_fpr = Fingerprint("BC30978345D789CADECDE492F54B42E1625E1A1D")
|
val carolFpr = Fingerprint("BC30978345D789CADECDE492F54B42E1625E1A1D")
|
||||||
val carol_uid = "<carol@example.org>"
|
val carolUid = "<carol@example.org>"
|
||||||
// Certified by: 20C812117FB2A3940EAE9160FEE6B4E47A096FD1
|
// Certified by: 20C812117FB2A3940EAE9160FEE6B4E47A096FD1
|
||||||
|
|
||||||
val dave_fpr = Fingerprint("319810FAD46CBE96DAD7F1F5B014902592999B21")
|
val daveFpr = Fingerprint("319810FAD46CBE96DAD7F1F5B014902592999B21")
|
||||||
val dave_uid = "<dave@other.org>"
|
val daveUid = "<dave@other.org>"
|
||||||
// Certified by: 20C812117FB2A3940EAE9160FEE6B4E47A096FD1
|
// Certified by: 20C812117FB2A3940EAE9160FEE6B4E47A096FD1
|
||||||
|
|
||||||
val ed_fpr = Fingerprint("23D7418EA0C6A42A54C32DBE8D4FE4911ED08467")
|
val edFpr = Fingerprint("23D7418EA0C6A42A54C32DBE8D4FE4911ED08467")
|
||||||
val ed_uid = "<ed@example.org>"
|
val edUid = "<ed@example.org>"
|
||||||
// Certified by: 319810FAD46CBE96DAD7F1F5B014902592999B21
|
// Certified by: 319810FAD46CBE96DAD7F1F5B014902592999B21
|
||||||
|
|
||||||
val frank_fpr = Fingerprint("7FAE20D68EE87F74368AF275A0C40E741FC1C50F")
|
val frankFpr = Fingerprint("7FAE20D68EE87F74368AF275A0C40E741FC1C50F")
|
||||||
val frank_uid = "<frank@other.org>"
|
val frankUid = "<frank@other.org>"
|
||||||
// Certified by: 319810FAD46CBE96DAD7F1F5B014902592999B21
|
// Certified by: 319810FAD46CBE96DAD7F1F5B014902592999B21
|
||||||
|
|
||||||
override fun getResourceName(): String {
|
override fun getResourceName(): String {
|
||||||
|
|
|
@ -23,23 +23,23 @@ import org.pgpainless.wot.network.Fingerprint
|
||||||
*/
|
*/
|
||||||
class Regex2Vectors: ArtifactVectors {
|
class Regex2Vectors: ArtifactVectors {
|
||||||
|
|
||||||
val alice_fpr = Fingerprint("5C396C920399898461F17CB747FDBF3EB3453919")
|
val aliceFpr = Fingerprint("5C396C920399898461F17CB747FDBF3EB3453919")
|
||||||
val alice_uid = "<alice@some.org>"
|
val aliceUid = "<alice@some.org>"
|
||||||
|
|
||||||
val bob_fpr = Fingerprint("584D195AD89CE0354D2CCBAEBCDD9EBC09692780")
|
val bobFpr = Fingerprint("584D195AD89CE0354D2CCBAEBCDD9EBC09692780")
|
||||||
val bob_uid = "<bob@some.org>"
|
val bobUid = "<bob@some.org>"
|
||||||
// Certified by: 5C396C920399898461F17CB747FDBF3EB3453919
|
// Certified by: 5C396C920399898461F17CB747FDBF3EB3453919
|
||||||
|
|
||||||
val carol_fpr = Fingerprint("FC7A96D4810D0CF477031956AED58C644370C183")
|
val carolFpr = Fingerprint("FC7A96D4810D0CF477031956AED58C644370C183")
|
||||||
val carol_uid = "<carol@other.org>"
|
val carolUid = "<carol@other.org>"
|
||||||
// Certified by: 584D195AD89CE0354D2CCBAEBCDD9EBC09692780
|
// Certified by: 584D195AD89CE0354D2CCBAEBCDD9EBC09692780
|
||||||
|
|
||||||
val dave_fpr = Fingerprint("58077E659732526C1B8BF9837EFC0EDE07B506A8")
|
val daveFpr = Fingerprint("58077E659732526C1B8BF9837EFC0EDE07B506A8")
|
||||||
val dave_uid = "<dave@their.org>"
|
val daveUid = "<dave@their.org>"
|
||||||
// Certified by: FC7A96D4810D0CF477031956AED58C644370C183
|
// Certified by: FC7A96D4810D0CF477031956AED58C644370C183
|
||||||
|
|
||||||
val ed_fpr = Fingerprint("36089C49F18BF6FC6BCA35E3BB85877766C009E4")
|
val edFpr = Fingerprint("36089C49F18BF6FC6BCA35E3BB85877766C009E4")
|
||||||
val ed_uid = "<ed@example.org>"
|
val edUid = "<ed@example.org>"
|
||||||
// Certified by: 58077E659732526C1B8BF9837EFC0EDE07B506A8
|
// Certified by: 58077E659732526C1B8BF9837EFC0EDE07B506A8
|
||||||
|
|
||||||
override fun getResourceName(): String {
|
override fun getResourceName(): String {
|
||||||
|
|
|
@ -22,35 +22,35 @@ import org.pgpainless.wot.network.Fingerprint
|
||||||
*/
|
*/
|
||||||
class Regex3Vectors: ArtifactVectors {
|
class Regex3Vectors: ArtifactVectors {
|
||||||
|
|
||||||
val alice_fpr = Fingerprint("D8CFEBBA006E2ED57CF45CC413F0BAE09D94FE4E")
|
val aliceFpr = Fingerprint("D8CFEBBA006E2ED57CF45CC413F0BAE09D94FE4E")
|
||||||
val alice_uid = "<alice@some.org>"
|
val aliceUid = "<alice@some.org>"
|
||||||
|
|
||||||
val bob_fpr = Fingerprint("A75DC1A1EDA5282F3A7381B51824E46BBCC801F0")
|
val bobFpr = Fingerprint("A75DC1A1EDA5282F3A7381B51824E46BBCC801F0")
|
||||||
val bob_uid = "<bob@example.org>"
|
val bobUid = "<bob@example.org>"
|
||||||
// Certified by: D8CFEBBA006E2ED57CF45CC413F0BAE09D94FE4E
|
// Certified by: D8CFEBBA006E2ED57CF45CC413F0BAE09D94FE4E
|
||||||
|
|
||||||
val carol_fpr = Fingerprint("4BCD4325BDACA452F0301227A30CB4BCC329E769")
|
val carolFpr = Fingerprint("4BCD4325BDACA452F0301227A30CB4BCC329E769")
|
||||||
val carol_uid = "<carol@example.org>"
|
val carolUid = "<carol@example.org>"
|
||||||
// Certified by: A75DC1A1EDA5282F3A7381B51824E46BBCC801F0
|
// Certified by: A75DC1A1EDA5282F3A7381B51824E46BBCC801F0
|
||||||
|
|
||||||
val dave_fpr = Fingerprint("2E1AAA8D9A22C94ACCA362A22B34031CD5CB9380")
|
val daveFpr = Fingerprint("2E1AAA8D9A22C94ACCA362A22B34031CD5CB9380")
|
||||||
val dave_uid = "<dave@other.org>"
|
val daveUid = "<dave@other.org>"
|
||||||
// Certified by: A75DC1A1EDA5282F3A7381B51824E46BBCC801F0
|
// Certified by: A75DC1A1EDA5282F3A7381B51824E46BBCC801F0
|
||||||
|
|
||||||
val ed_fpr = Fingerprint("F645D081F480BE26C7D2C84D941B3E2CE53FAF16")
|
val edFpr = Fingerprint("F645D081F480BE26C7D2C84D941B3E2CE53FAF16")
|
||||||
val ed_uid = "<ed@example.org>"
|
val edUid = "<ed@example.org>"
|
||||||
// Certified by: 2E1AAA8D9A22C94ACCA362A22B34031CD5CB9380
|
// Certified by: 2E1AAA8D9A22C94ACCA362A22B34031CD5CB9380
|
||||||
|
|
||||||
val frank_fpr = Fingerprint("AFAB11F1A37FD20C85CF8093F4941D1A0EC5749F")
|
val frankFpr = Fingerprint("AFAB11F1A37FD20C85CF8093F4941D1A0EC5749F")
|
||||||
val frank_uid = "<frank@other.org>"
|
val frankUid = "<frank@other.org>"
|
||||||
// Certified by: 2E1AAA8D9A22C94ACCA362A22B34031CD5CB9380
|
// Certified by: 2E1AAA8D9A22C94ACCA362A22B34031CD5CB9380
|
||||||
|
|
||||||
val george_fpr = Fingerprint("D01C8752D9BA9F3F5F06B21F394E911938D6DB0A")
|
val georgeFpr = Fingerprint("D01C8752D9BA9F3F5F06B21F394E911938D6DB0A")
|
||||||
val george_uid = "<george@their.org>"
|
val georgeUid = "<george@their.org>"
|
||||||
// Certified by: 2E1AAA8D9A22C94ACCA362A22B34031CD5CB9380
|
// Certified by: 2E1AAA8D9A22C94ACCA362A22B34031CD5CB9380
|
||||||
|
|
||||||
val henry_fpr = Fingerprint("B99A8696FD820192CEEE285D3A253E49F1D97109")
|
val henryFpr = Fingerprint("B99A8696FD820192CEEE285D3A253E49F1D97109")
|
||||||
val henry_uid = "<henry@their.org>"
|
val henryUid = "<henry@their.org>"
|
||||||
// Certified by: A75DC1A1EDA5282F3A7381B51824E46BBCC801F0
|
// Certified by: A75DC1A1EDA5282F3A7381B51824E46BBCC801F0
|
||||||
|
|
||||||
override fun getResourceName(): String {
|
override fun getResourceName(): String {
|
||||||
|
|
|
@ -34,7 +34,7 @@ class SelfSignedVectors: ArtifactVectors {
|
||||||
val carolFpr = Fingerprint("830230061426EE99A0455E6ADA869CF879A5630D")
|
val carolFpr = Fingerprint("830230061426EE99A0455E6ADA869CF879A5630D")
|
||||||
val carolUid = "<carol@example.org>"
|
val carolUid = "<carol@example.org>"
|
||||||
// Certified by: 7A7B5DE6C8F464CAB78BEFB9CE14BEE51D4DEC01
|
// Certified by: 7A7B5DE6C8F464CAB78BEFB9CE14BEE51D4DEC01
|
||||||
val carol_other_orgUid = "<carol@other.org>"
|
val carolOtherOrgUid = "<carol@other.org>"
|
||||||
|
|
||||||
val daveFpr = Fingerprint("51A5E15F87AC6ECAFBEA930FA5F30AF6EB6EF14A")
|
val daveFpr = Fingerprint("51A5E15F87AC6ECAFBEA930FA5F30AF6EB6EF14A")
|
||||||
val daveUid = "<dave@example.org>"
|
val daveUid = "<dave@example.org>"
|
||||||
|
|
Loading…
Reference in a new issue