mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-24 11:57:59 +01:00
Refactor WebOfTrust class
This commit is contained in:
parent
f13f310f6b
commit
1b19ba8766
5 changed files with 193 additions and 267 deletions
|
@ -18,7 +18,6 @@ import org.pgpainless.signature.SignatureUtils
|
||||||
import org.pgpainless.signature.consumer.SignatureVerifier
|
import org.pgpainless.signature.consumer.SignatureVerifier
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
|
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
|
||||||
import org.pgpainless.wot.dijkstra.sq.*
|
import org.pgpainless.wot.dijkstra.sq.*
|
||||||
import org.pgpainless.wot.dijkstra.sq.CertificationSet.Companion.fromCertification
|
|
||||||
import org.pgpainless.wot.dijkstra.sq.ReferenceTime.Companion.now
|
import org.pgpainless.wot.dijkstra.sq.ReferenceTime.Companion.now
|
||||||
import org.pgpainless.wot.util.CertificationFactory.Companion.fromCertification
|
import org.pgpainless.wot.util.CertificationFactory.Companion.fromCertification
|
||||||
import org.pgpainless.wot.util.CertificationFactory.Companion.fromDelegation
|
import org.pgpainless.wot.util.CertificationFactory.Companion.fromDelegation
|
||||||
|
@ -46,11 +45,10 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) {
|
||||||
*/
|
*/
|
||||||
constructor(certificateDirectory: PGPCertificateDirectory): this(PGPCertificateStoreAdapter(certificateDirectory))
|
constructor(certificateDirectory: PGPCertificateDirectory): this(PGPCertificateStoreAdapter(certificateDirectory))
|
||||||
|
|
||||||
lateinit var network: Network
|
fun buildNetwork(policy: Policy = PGPainless.getPolicy(), referenceTime: ReferenceTime = now()): Network {
|
||||||
|
|
||||||
fun initialize() {
|
|
||||||
val certificates = getAllCertificatesFromTheStore()
|
val certificates = getAllCertificatesFromTheStore()
|
||||||
network = fromCertificates(certificates, PGPainless.getPolicy(), now())
|
val networkFactory = PGPNetworkFactory.fromCertificates(certificates, policy, referenceTime)
|
||||||
|
return networkFactory.buildNetwork()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAllCertificatesFromTheStore(): Sequence<Certificate> {
|
private fun getAllCertificatesFromTheStore(): Sequence<Certificate> {
|
||||||
|
@ -69,47 +67,181 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) {
|
||||||
return certificates
|
return certificates
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
/**
|
||||||
@JvmStatic
|
* Class for building the [Flow network][Network] from the given set of OpenPGP keys.
|
||||||
fun fromCertificates(certificates: Sequence<Certificate>,
|
*/
|
||||||
policy: Policy,
|
private class PGPNetworkFactory private constructor(validatedCertificates: List<KeyRingInfo>,
|
||||||
referenceTime: ReferenceTime): Network {
|
private val policy: Policy,
|
||||||
return fromValidCertificates(
|
private val referenceTime: ReferenceTime) {
|
||||||
parseValidCertificates(certificates, policy, referenceTime),
|
|
||||||
policy,
|
|
||||||
referenceTime
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
companion object {
|
||||||
fun fromValidCertificates(certificates: List<KeyRingInfo>,
|
@JvmStatic
|
||||||
policy: Policy,
|
private val LOGGER = LoggerFactory.getLogger(PGPNetworkFactory::class.java)
|
||||||
referenceTime: ReferenceTime): Network {
|
|
||||||
val nb = NetworkBuilder(certificates, policy, referenceTime)
|
|
||||||
return nb.buildNetwork()
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
private fun parseValidCertificates(certificates: Sequence<Certificate>,
|
fun fromCertificates(certificates: Sequence<Certificate>,
|
||||||
policy: Policy,
|
policy: Policy,
|
||||||
referenceTime: ReferenceTime): List<KeyRingInfo> {
|
referenceTime: ReferenceTime): PGPNetworkFactory {
|
||||||
return certificates
|
return fromValidCertificates(
|
||||||
.mapNotNull { cert ->
|
parseValidCertificates(certificates, policy, referenceTime),
|
||||||
try {
|
policy,
|
||||||
PGPainless.readKeyRing().publicKeyRing(cert.inputStream)
|
referenceTime
|
||||||
} catch (e: IOException) {
|
)
|
||||||
null
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun fromValidCertificates(certificates: List<KeyRingInfo>,
|
||||||
|
policy: Policy,
|
||||||
|
referenceTime: ReferenceTime): PGPNetworkFactory {
|
||||||
|
return PGPNetworkFactory(certificates, policy, referenceTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
private fun parseValidCertificates(certificates: Sequence<Certificate>,
|
||||||
|
policy: Policy,
|
||||||
|
referenceTime: ReferenceTime): List<KeyRingInfo> {
|
||||||
|
return certificates
|
||||||
|
.mapNotNull {
|
||||||
|
try { PGPainless.readKeyRing().publicKeyRing(it.inputStream) } catch (e: IOException) { null }
|
||||||
}
|
}
|
||||||
}
|
.map { KeyRingInfo(it, policy, referenceTime.timestamp) }
|
||||||
.map { cert ->
|
.toList()
|
||||||
KeyRingInfo(cert, policy, referenceTime.timestamp)
|
}
|
||||||
}
|
|
||||||
.toList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map signature to its revocation state
|
private val networkBuilder: Network.Builder = Network.builder()
|
||||||
@JvmStatic
|
|
||||||
private fun revocationStateFromSignature(revocation: PGPSignature?): RevocationState {
|
// certificates keyed by fingerprint
|
||||||
|
private val byFingerprint: MutableMap<Fingerprint, KeyRingInfo> = HashMap()
|
||||||
|
|
||||||
|
// certificates keyed by (sub-) key-id
|
||||||
|
private val byKeyId: MutableMap<Long, MutableList<KeyRingInfo>> = HashMap()
|
||||||
|
|
||||||
|
// certificate synopses keyed by fingerprint
|
||||||
|
private val certSynopsisMap: MutableMap<Fingerprint, CertSynopsis> = HashMap()
|
||||||
|
|
||||||
|
init {
|
||||||
|
validatedCertificates.forEach { indexAsNode(it) }
|
||||||
|
validatedCertificates.forEach { findEdgesWithTarget(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun indexAsNode(cert: KeyRingInfo) {
|
||||||
|
|
||||||
|
// index by fingerprint
|
||||||
|
val certFingerprint = Fingerprint(cert.fingerprint)
|
||||||
|
if (!byFingerprint.containsKey(certFingerprint)) {
|
||||||
|
byFingerprint[certFingerprint] = cert
|
||||||
|
}
|
||||||
|
|
||||||
|
// index by key-ID
|
||||||
|
var certsWithKey = byKeyId[cert.keyId]
|
||||||
|
// noinspection Java8MapApi
|
||||||
|
if (certsWithKey == null) {
|
||||||
|
certsWithKey = mutableListOf()
|
||||||
|
// TODO: Something is fishy here...
|
||||||
|
for (key in cert.validSubkeys) {
|
||||||
|
byKeyId[key.keyID] = certsWithKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
certsWithKey.add(cert)
|
||||||
|
val userIds: MutableMap<String, RevocationState> = HashMap()
|
||||||
|
for (userId in cert.userIds) {
|
||||||
|
val state = RevocationState(cert.getUserIdRevocation(userId))
|
||||||
|
userIds[userId] = state
|
||||||
|
}
|
||||||
|
|
||||||
|
// index synopses
|
||||||
|
val expirationDate: Date? = try {
|
||||||
|
cert.getExpirationDateForUse(KeyFlag.CERTIFY_OTHER)
|
||||||
|
} catch (e: NoSuchElementException) {
|
||||||
|
// Some keys are malformed and have no KeyFlags
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val node = CertSynopsis(certFingerprint,
|
||||||
|
expirationDate,
|
||||||
|
RevocationState(cert.revocationSelfSignature),
|
||||||
|
userIds)
|
||||||
|
certSynopsisMap[certFingerprint] = node
|
||||||
|
networkBuilder.addNode(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findEdgesWithTarget(validatedTarget: KeyRingInfo) {
|
||||||
|
val validatedTargetKeyRing = KeyRingUtils.publicKeys(validatedTarget.keys)
|
||||||
|
val targetFingerprint = Fingerprint(OpenPgpFingerprint.of(validatedTargetKeyRing))
|
||||||
|
val targetPrimaryKey = validatedTargetKeyRing.publicKey!!
|
||||||
|
val target = certSynopsisMap[targetFingerprint]!!
|
||||||
|
|
||||||
|
// Direct-Key Signatures (delegations) by X on Y
|
||||||
|
val delegations = SignatureUtils.getDelegations(validatedTargetKeyRing)
|
||||||
|
for (delegation in delegations) {
|
||||||
|
processDelegation(targetPrimaryKey, target, delegation)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Certification Signatures by X on Y over user-ID U
|
||||||
|
val userIds = targetPrimaryKey.userIDs
|
||||||
|
while (userIds.hasNext()) {
|
||||||
|
val userId = userIds.next()
|
||||||
|
val userIdSigs = SignatureUtils.get3rdPartyCertificationsFor(userId, validatedTargetKeyRing)
|
||||||
|
userIdSigs.forEach {
|
||||||
|
processCertificationOnUserId(targetPrimaryKey, target, userId, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processDelegation(targetPrimaryKey: PGPPublicKey,
|
||||||
|
target: CertSynopsis,
|
||||||
|
delegation: PGPSignature) {
|
||||||
|
val issuerCandidates = byKeyId[delegation.keyID]
|
||||||
|
?: return
|
||||||
|
for (candidate in issuerCandidates) {
|
||||||
|
val issuerKeyRing = KeyRingUtils.publicKeys(candidate.keys)
|
||||||
|
val issuerFingerprint = Fingerprint(OpenPgpFingerprint.of(issuerKeyRing))
|
||||||
|
val issuerSigningKey = issuerKeyRing.getPublicKey(delegation.keyID)
|
||||||
|
val issuer = certSynopsisMap[issuerFingerprint]
|
||||||
|
?: continue
|
||||||
|
try {
|
||||||
|
val valid = SignatureVerifier.verifyDirectKeySignature(delegation, issuerSigningKey,
|
||||||
|
targetPrimaryKey, policy, referenceTime.timestamp)
|
||||||
|
if (valid) {
|
||||||
|
networkBuilder.addEdge(fromDelegation(issuer, target, delegation))
|
||||||
|
}
|
||||||
|
} catch (e: SignatureValidationException) {
|
||||||
|
val targetFingerprint = OpenPgpFingerprint.of(targetPrimaryKey)
|
||||||
|
LOGGER.warn("Cannot verify signature by $issuerFingerprint on cert of $targetFingerprint", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processCertificationOnUserId(targetPrimaryKey: PGPPublicKey,
|
||||||
|
target: CertSynopsis,
|
||||||
|
userId: String,
|
||||||
|
certification: PGPSignature) {
|
||||||
|
val issuerCandidates = byKeyId[certification.keyID]
|
||||||
|
?: return
|
||||||
|
for (candidate in issuerCandidates) {
|
||||||
|
val issuerKeyRing = KeyRingUtils.publicKeys(candidate.keys)
|
||||||
|
val issuerFingerprint = Fingerprint(OpenPgpFingerprint.of(issuerKeyRing))
|
||||||
|
val issuerSigningKey = issuerKeyRing.getPublicKey(certification.keyID)
|
||||||
|
?: continue
|
||||||
|
val issuer = certSynopsisMap[issuerFingerprint]
|
||||||
|
?: continue
|
||||||
|
try {
|
||||||
|
val valid = SignatureVerifier.verifySignatureOverUserId(userId, certification,
|
||||||
|
issuerSigningKey, targetPrimaryKey, policy, referenceTime.timestamp)
|
||||||
|
if (valid) {
|
||||||
|
networkBuilder.addEdge(fromCertification(issuer, target, userId, certification))
|
||||||
|
}
|
||||||
|
} catch (e: SignatureValidationException) {
|
||||||
|
LOGGER.warn("Cannot verify signature for '$userId' by $issuerFingerprint" +
|
||||||
|
" on cert of ${target.fingerprint}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Fingerprint(fingerprint: OpenPgpFingerprint) = Fingerprint(fingerprint.toString())
|
||||||
|
|
||||||
|
private fun RevocationState(revocation: PGPSignature?): RevocationState {
|
||||||
if (revocation == null) {
|
if (revocation == null) {
|
||||||
return RevocationState.notRevoked()
|
return RevocationState.notRevoked()
|
||||||
}
|
}
|
||||||
|
@ -121,209 +253,13 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) {
|
||||||
RevocationState.softRevoked(revocation.creationTime)
|
RevocationState.softRevoked(revocation.creationTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
private fun OpenPgpFingerprint.map(): Fingerprint {
|
|
||||||
return Fingerprint(toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for building the [Flow network][Network] from the given set of OpenPGP keys.
|
* Return the constructed, initialized [Network].
|
||||||
*
|
*
|
||||||
|
* @return finished network
|
||||||
*/
|
*/
|
||||||
private class NetworkBuilder constructor(validatedCertificates: List<KeyRingInfo>,
|
fun buildNetwork(): Network {
|
||||||
private val policy: Policy,
|
return networkBuilder.build()
|
||||||
private val referenceTime: ReferenceTime) {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
private val LOGGER = LoggerFactory.getLogger(NetworkBuilder::class.java)
|
|
||||||
}
|
|
||||||
|
|
||||||
// certificates keyed by fingerprint
|
|
||||||
private val byFingerprint: MutableMap<Fingerprint, KeyRingInfo> = HashMap()
|
|
||||||
|
|
||||||
// certificates keyed by (sub-) key-id
|
|
||||||
private val byKeyId: MutableMap<Long, MutableList<KeyRingInfo>> = HashMap()
|
|
||||||
|
|
||||||
// certificate synopses keyed by fingerprint
|
|
||||||
private val certSynopsisMap: MutableMap<Fingerprint, CertSynopsis> = HashMap()
|
|
||||||
|
|
||||||
// Issuer -> Targets, edges keyed by issuer
|
|
||||||
private val edges: MutableMap<Fingerprint, MutableList<CertificationSet>> = HashMap()
|
|
||||||
|
|
||||||
// Target -> Issuers, edges keyed by target
|
|
||||||
private val reverseEdges: MutableMap<Fingerprint, MutableList<CertificationSet>> = HashMap()
|
|
||||||
|
|
||||||
init {
|
|
||||||
synopsizeCertificates(validatedCertificates)
|
|
||||||
findEdges(validatedCertificates)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun synopsizeCertificates(validatedCertificates: List<KeyRingInfo>) {
|
|
||||||
for (cert in validatedCertificates) {
|
|
||||||
synopsize(cert)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun synopsize(cert: KeyRingInfo) {
|
|
||||||
|
|
||||||
// index by fingerprint
|
|
||||||
val certFingerprint = cert.fingerprint.map()
|
|
||||||
if (!byFingerprint.containsKey(certFingerprint)) {
|
|
||||||
byFingerprint[certFingerprint] = cert
|
|
||||||
}
|
|
||||||
|
|
||||||
// index by key-ID
|
|
||||||
var certsWithKey = byKeyId[cert.keyId]
|
|
||||||
// noinspection Java8MapApi
|
|
||||||
if (certsWithKey == null) {
|
|
||||||
certsWithKey = mutableListOf()
|
|
||||||
// TODO: Something is fishy here...
|
|
||||||
for (key in cert.validSubkeys) {
|
|
||||||
byKeyId[key.keyID] = certsWithKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
certsWithKey.add(cert)
|
|
||||||
val userIds: MutableMap<String, RevocationState> = HashMap()
|
|
||||||
for (userId in cert.userIds) {
|
|
||||||
val state: RevocationState = revocationStateFromSignature(cert.getUserIdRevocation(userId))
|
|
||||||
userIds[userId] = state
|
|
||||||
}
|
|
||||||
|
|
||||||
// index synopses
|
|
||||||
val expirationDate: Date? = try {
|
|
||||||
cert.getExpirationDateForUse(KeyFlag.CERTIFY_OTHER)
|
|
||||||
} catch (e: NoSuchElementException) {
|
|
||||||
// Some keys are malformed and have no KeyFlags
|
|
||||||
return
|
|
||||||
}
|
|
||||||
certSynopsisMap[certFingerprint] = CertSynopsis(certFingerprint,
|
|
||||||
expirationDate,
|
|
||||||
revocationStateFromSignature(cert.revocationSelfSignature),
|
|
||||||
userIds)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findEdges(validatedCertificates: List<KeyRingInfo>) {
|
|
||||||
// Identify certifications and delegations
|
|
||||||
// Target = cert carrying a signature
|
|
||||||
for (validatedTarget in validatedCertificates) {
|
|
||||||
findEdgesWithTarget(validatedTarget)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findEdgesWithTarget(validatedTarget: KeyRingInfo) {
|
|
||||||
val validatedTargetKeyRing = KeyRingUtils.publicKeys(validatedTarget.keys)
|
|
||||||
val targetFingerprint = OpenPgpFingerprint.of(validatedTargetKeyRing).map()
|
|
||||||
val targetPrimaryKey = validatedTargetKeyRing.publicKey!!
|
|
||||||
val target = certSynopsisMap[targetFingerprint]!!
|
|
||||||
|
|
||||||
// Direct-Key Signatures (delegations) by X on Y
|
|
||||||
val delegations = SignatureUtils.getDelegations(validatedTargetKeyRing)
|
|
||||||
for (delegation in delegations) {
|
|
||||||
processDelegation(targetPrimaryKey, target, delegation)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Certification Signatures by X on Y over user-ID U
|
|
||||||
val userIds = targetPrimaryKey.userIDs
|
|
||||||
while (userIds.hasNext()) {
|
|
||||||
val userId = userIds.next()
|
|
||||||
val userIdSigs = SignatureUtils.get3rdPartyCertificationsFor(userId, validatedTargetKeyRing)
|
|
||||||
processCertification(targetPrimaryKey, target, userId, userIdSigs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processDelegation(targetPrimaryKey: PGPPublicKey,
|
|
||||||
target: CertSynopsis,
|
|
||||||
delegation: PGPSignature) {
|
|
||||||
val issuerCandidates = byKeyId[delegation.keyID]
|
|
||||||
?: return
|
|
||||||
for (candidate in issuerCandidates) {
|
|
||||||
val issuerKeyRing = KeyRingUtils.publicKeys(candidate.keys)
|
|
||||||
val issuerFingerprint = OpenPgpFingerprint.of(issuerKeyRing).map()
|
|
||||||
val issuerSigningKey = issuerKeyRing.getPublicKey(delegation.keyID)
|
|
||||||
val issuer = certSynopsisMap[issuerFingerprint]
|
|
||||||
?: continue
|
|
||||||
try {
|
|
||||||
val valid = SignatureVerifier.verifyDirectKeySignature(delegation, issuerSigningKey,
|
|
||||||
targetPrimaryKey, policy, referenceTime.timestamp)
|
|
||||||
if (valid) {
|
|
||||||
indexEdge(fromDelegation(issuer, target, delegation))
|
|
||||||
}
|
|
||||||
} catch (e: SignatureValidationException) {
|
|
||||||
val targetFingerprint = OpenPgpFingerprint.of(targetPrimaryKey)
|
|
||||||
LOGGER.warn("Cannot verify signature by $issuerFingerprint on cert of $targetFingerprint", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processCertification(targetPrimaryKey: PGPPublicKey,
|
|
||||||
target: CertSynopsis,
|
|
||||||
userId: String,
|
|
||||||
userIdSigs: List<PGPSignature>) {
|
|
||||||
for (certification in userIdSigs) {
|
|
||||||
val issuerCandidates = byKeyId[certification.keyID]
|
|
||||||
?: continue
|
|
||||||
for (candidate in issuerCandidates) {
|
|
||||||
val issuerKeyRing = KeyRingUtils.publicKeys(candidate.keys)
|
|
||||||
val issuerFingerprint = OpenPgpFingerprint.of(issuerKeyRing).map()
|
|
||||||
val issuerSigningKey = issuerKeyRing.getPublicKey(certification.keyID)
|
|
||||||
?: continue
|
|
||||||
val issuer = certSynopsisMap[issuerFingerprint]
|
|
||||||
?: continue
|
|
||||||
try {
|
|
||||||
val valid = SignatureVerifier.verifySignatureOverUserId(userId, certification,
|
|
||||||
issuerSigningKey, targetPrimaryKey, policy, referenceTime.timestamp)
|
|
||||||
if (valid) {
|
|
||||||
indexEdge(fromCertification(issuer, target, userId, certification))
|
|
||||||
}
|
|
||||||
} catch (e: SignatureValidationException) {
|
|
||||||
LOGGER.warn("Cannot verify signature for '$userId' by $issuerFingerprint" +
|
|
||||||
" on cert of ${target.fingerprint}", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun indexEdge(certification: Certification) {
|
|
||||||
// Index edge as outgoing edge for issuer
|
|
||||||
val issuer = certification.issuer.fingerprint
|
|
||||||
edges.getOrPut(issuer) { mutableListOf() }.also { indexOutEdge(it, certification) }
|
|
||||||
|
|
||||||
// Index edge as incoming edge for target
|
|
||||||
val target = certification.target.fingerprint
|
|
||||||
reverseEdges.getOrPut(target) { mutableListOf() }.also { indexInEdge(it, certification) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun indexOutEdge(outEdges: MutableList<CertificationSet>, certification: Certification) {
|
|
||||||
val target = certification.target.fingerprint
|
|
||||||
for (outEdge in outEdges) {
|
|
||||||
if (target == outEdge.target.fingerprint) {
|
|
||||||
outEdge.add(certification)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outEdges.add(fromCertification(certification))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun indexInEdge(inEdges: MutableList<CertificationSet>, certification: Certification) {
|
|
||||||
val issuer = certification.issuer.fingerprint
|
|
||||||
for (inEdge in inEdges) {
|
|
||||||
if (issuer == inEdge.issuer.fingerprint) {
|
|
||||||
inEdge.add(certification)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inEdges.add(fromCertification(certification))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the constructed, initialized [Network].
|
|
||||||
*
|
|
||||||
* @return finished network
|
|
||||||
*/
|
|
||||||
fun buildNetwork(): Network {
|
|
||||||
return Network(certSynopsisMap, edges, reverseEdges, referenceTime)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ class AdHocTest {
|
||||||
@Test
|
@Test
|
||||||
fun test() {
|
fun test() {
|
||||||
val store = AdHocVectors.BestViaRoot().pgpCertificateStore
|
val store = AdHocVectors.BestViaRoot().pgpCertificateStore
|
||||||
val wot = WebOfTrust(store).also { it.initialize() }
|
val network = WebOfTrust(store).buildNetwork()
|
||||||
val network = wot.network
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,9 +33,7 @@ class WebOfTrustTest {
|
||||||
@Test
|
@Test
|
||||||
fun testWithTwoNodesAndOneDelegation() {
|
fun testWithTwoNodesAndOneDelegation() {
|
||||||
val certD = TestCertificateStores.oneDelegationGraph()
|
val certD = TestCertificateStores.oneDelegationGraph()
|
||||||
val wot = WebOfTrust(certD)
|
val network = WebOfTrust(certD).buildNetwork()
|
||||||
wot.initialize()
|
|
||||||
val network = wot.network
|
|
||||||
|
|
||||||
assertEquals(2, network.nodes.size)
|
assertEquals(2, network.nodes.size)
|
||||||
assertHasEdge(network, fooBankAdmin, barBankCa)
|
assertHasEdge(network, fooBankAdmin, barBankCa)
|
||||||
|
@ -48,9 +46,7 @@ class WebOfTrustTest {
|
||||||
@Test
|
@Test
|
||||||
fun testWithCrossSignedCertificates() {
|
fun testWithCrossSignedCertificates() {
|
||||||
val certD = TestCertificateStores.disconnectedGraph()
|
val certD = TestCertificateStores.disconnectedGraph()
|
||||||
val wot = WebOfTrust(certD)
|
val network = WebOfTrust(certD).buildNetwork()
|
||||||
wot.initialize()
|
|
||||||
val network = wot.network
|
|
||||||
|
|
||||||
assertEquals(5, network.nodes.size)
|
assertEquals(5, network.nodes.size)
|
||||||
assertTrue {
|
assertTrue {
|
||||||
|
@ -81,9 +77,7 @@ class WebOfTrustTest {
|
||||||
@Test
|
@Test
|
||||||
fun testWotCreationOfEmptyCertificates() {
|
fun testWotCreationOfEmptyCertificates() {
|
||||||
val certD = TestCertificateStores.emptyGraph()
|
val certD = TestCertificateStores.emptyGraph()
|
||||||
val wot = WebOfTrust(certD)
|
val network = WebOfTrust(certD).buildNetwork()
|
||||||
wot.initialize()
|
|
||||||
val network = wot.network
|
|
||||||
|
|
||||||
assertTrue { network.nodes.isEmpty() }
|
assertTrue { network.nodes.isEmpty() }
|
||||||
assertTrue { network.edges.isEmpty() }
|
assertTrue { network.edges.isEmpty() }
|
||||||
|
@ -93,9 +87,7 @@ class WebOfTrustTest {
|
||||||
@Test
|
@Test
|
||||||
fun testWotWithAnomaly() {
|
fun testWotWithAnomaly() {
|
||||||
val store = TestCertificateStores.anomalyGraph()
|
val store = TestCertificateStores.anomalyGraph()
|
||||||
val wot = WebOfTrust(store)
|
val network = WebOfTrust(store).buildNetwork()
|
||||||
wot.initialize()
|
|
||||||
val network = wot.network
|
|
||||||
|
|
||||||
assertEquals(1, network.nodes.size)
|
assertEquals(1, network.nodes.size)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,14 +9,13 @@ import org.junit.jupiter.api.assertThrows
|
||||||
import org.pgpainless.wot.dijkstra.sq.*
|
import org.pgpainless.wot.dijkstra.sq.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFalse
|
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class CertificationSetTest {
|
class CertificationSetTest {
|
||||||
|
|
||||||
private val alice = CertSynopsis(Fingerprint("0000000000000000000000000000000000000000"), null, RevocationState.notRevoked(), mapOf())
|
private val alice = CertSynopsis(Fingerprint("A"), null, RevocationState.notRevoked(), mapOf())
|
||||||
private val bob = CertSynopsis(Fingerprint("1111111111111111111111111111111111111111"), null, RevocationState.notRevoked(), mapOf())
|
private val bob = CertSynopsis(Fingerprint("B"), null, RevocationState.notRevoked(), mapOf())
|
||||||
private val charlie = CertSynopsis(Fingerprint("2222222222222222222222222222222222222222"), null, RevocationState.notRevoked(), mapOf())
|
private val charlie = CertSynopsis(Fingerprint("C"), null, RevocationState.notRevoked(), mapOf())
|
||||||
|
|
||||||
private val aliceSignsBob = Certification(alice, null, bob, Date())
|
private val aliceSignsBob = Certification(alice, null, bob, Date())
|
||||||
private val aliceSignsBobUserId = Certification(alice, "Bob <bob@example.org>", bob, Date())
|
private val aliceSignsBobUserId = Certification(alice, "Bob <bob@example.org>", bob, Date())
|
||||||
|
@ -105,8 +104,8 @@ class CertificationSetTest {
|
||||||
val twoCerts = CertificationSet.fromCertification(aliceSignsBob)
|
val twoCerts = CertificationSet.fromCertification(aliceSignsBob)
|
||||||
twoCerts.add(aliceSignsBobUserId)
|
twoCerts.add(aliceSignsBobUserId)
|
||||||
|
|
||||||
assertEquals("0000000000000000000000000000000000000000 delegates to 1111111111111111111111111111111111111111\n" +
|
assertEquals("A certifies binding: null <-> B [120]\n" +
|
||||||
"0000000000000000000000000000000000000000 certifies [Bob <bob@example.org>] 1111111111111111111111111111111111111111", twoCerts.toString())
|
"A certifies binding: Bob <bob@example.org> <-> B [120]", twoCerts.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -11,17 +11,17 @@ import kotlin.test.assertEquals
|
||||||
class CertificationTest {
|
class CertificationTest {
|
||||||
|
|
||||||
private val alice = CertSynopsis(
|
private val alice = CertSynopsis(
|
||||||
Fingerprint("0000000000000000000000000000000000000000"),
|
Fingerprint("A"),
|
||||||
null,
|
null,
|
||||||
RevocationState.notRevoked(),
|
RevocationState.notRevoked(),
|
||||||
mapOf(Pair("Alice <alice@pgpainless.org>", RevocationState.notRevoked())))
|
mapOf(Pair("Alice <alice@pgpainless.org>", RevocationState.notRevoked())))
|
||||||
private val bob = CertSynopsis(
|
private val bob = CertSynopsis(
|
||||||
Fingerprint("1111111111111111111111111111111111111111"),
|
Fingerprint("B"),
|
||||||
null,
|
null,
|
||||||
RevocationState.notRevoked(),
|
RevocationState.notRevoked(),
|
||||||
mapOf(Pair("Bob <bob@example.org>", RevocationState.notRevoked())))
|
mapOf(Pair("Bob <bob@example.org>", RevocationState.notRevoked())))
|
||||||
private val charlie = CertSynopsis(
|
private val charlie = CertSynopsis(
|
||||||
Fingerprint("22222222222222222222222222222222222222222222"),
|
Fingerprint("C"),
|
||||||
null,
|
null,
|
||||||
RevocationState.notRevoked(),
|
RevocationState.notRevoked(),
|
||||||
mapOf())
|
mapOf())
|
||||||
|
@ -29,21 +29,21 @@ class CertificationTest {
|
||||||
@Test
|
@Test
|
||||||
fun `verify result of toString() on certification`() {
|
fun `verify result of toString() on certification`() {
|
||||||
val certification = Certification(alice, "Bob <bob@example.org>", bob, Date())
|
val certification = Certification(alice, "Bob <bob@example.org>", bob, Date())
|
||||||
assertEquals("0000000000000000000000000000000000000000 (Alice <alice@pgpainless.org>) certifies [Bob <bob@example.org>] 1111111111111111111111111111111111111111",
|
assertEquals("A certifies binding: Bob <bob@example.org> <-> B [120]",
|
||||||
certification.toString())
|
certification.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `verify result of toString() on delegation`() {
|
fun `verify result of toString() on delegation`() {
|
||||||
val delegation = Certification(alice, null, bob, Date())
|
val delegation = Certification(alice, null, bob, Date())
|
||||||
assertEquals("0000000000000000000000000000000000000000 (Alice <alice@pgpainless.org>) delegates to 1111111111111111111111111111111111111111",
|
assertEquals("A certifies binding: null <-> B [120]",
|
||||||
delegation.toString())
|
delegation.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `verify result of toString() on delegation with userId-less issuer`() {
|
fun `verify result of toString() on delegation with userId-less issuer`() {
|
||||||
val delegation = Certification(charlie, null, bob, Date())
|
val delegation = Certification(charlie, null, bob, Date())
|
||||||
assertEquals("22222222222222222222222222222222222222222222 delegates to 1111111111111111111111111111111111111111",
|
assertEquals("C certifies binding: null <-> B [120]",
|
||||||
delegation.toString())
|
delegation.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue