mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-24 03:47:57 +01:00
Move the API definition to wot-dijkstra
This commit is contained in:
parent
d7bcfeedb1
commit
a0d206bb15
13 changed files with 64 additions and 39 deletions
|
@ -8,6 +8,8 @@ SPDX-License-Identifier: Apache-2.0
|
|||
|
||||
This module contains a command line interface application that acts as a front-end for
|
||||
[`pgpainless-wot`](../pgpainless-wot).
|
||||
The interface of the application is modelled after the [sq-wot](https://gitlab.com/sequoia-pgp/sequoia-wot/)
|
||||
reference implementation.
|
||||
|
||||
## Build
|
||||
|
||||
|
|
|
@ -6,10 +6,11 @@ package org.pgpainless.wot.cli
|
|||
|
||||
import org.pgpainless.certificate_store.PGPainlessCertD
|
||||
import org.pgpainless.util.DateUtil
|
||||
import org.pgpainless.wot.api.WoTAPI
|
||||
import org.pgpainless.wot.WebOfTrust
|
||||
import org.pgpainless.wot.cli.subcommands.*
|
||||
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||
import org.pgpainless.wot.dijkstra.sq.ReferenceTime
|
||||
import org.pgpainless.wot.dijkstra.sq.api.WoTAPI
|
||||
import pgp.cert_d.PGPCertificateStoreAdapter
|
||||
import pgp.cert_d.subkey_lookup.InMemorySubkeyLookupFactory
|
||||
import pgp.certificate_store.PGPCertificateStore
|
||||
|
@ -19,6 +20,11 @@ import java.io.File
|
|||
import java.util.concurrent.Callable
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
/**
|
||||
* Command Line Interface for pgpainless-wot, modelled after the reference implementation "sq-wot".
|
||||
*
|
||||
* @see <a href="https://gitlab.com/sequoia-pgp/sequoia-wot/">Sequoia Web of Trust Reference Implementation</a>
|
||||
*/
|
||||
@Command(name = "pgpainless-wot",
|
||||
subcommands = [
|
||||
AuthenticateCmd::class,
|
||||
|
@ -110,8 +116,10 @@ class WotCLI: Callable<Int> {
|
|||
|
||||
val api: WoTAPI
|
||||
get() {
|
||||
val network = WebOfTrust(certificateStore)
|
||||
.buildNetwork(referenceTime = referenceTime)
|
||||
return WoTAPI(
|
||||
certStores = listOf(certificateStore),
|
||||
network = network,
|
||||
trustRoots = trustRoots,
|
||||
gossip = false,
|
||||
certificationNetwork = false,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.pgpainless.wot.cli.subcommands
|
||||
|
||||
import org.pgpainless.wot.api.AuthenticateAPI
|
||||
import org.pgpainless.wot.dijkstra.sq.api.AuthenticateAPI
|
||||
import org.pgpainless.wot.cli.WotCLI
|
||||
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||
import org.pgpainless.wot.dijkstra.sq.Path
|
||||
|
@ -15,18 +15,33 @@ import picocli.CommandLine.ParentCommand
|
|||
import java.text.SimpleDateFormat
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
/**
|
||||
* Authenticate a binding between a certification and one of its user-ids.
|
||||
*/
|
||||
@Command(name = "authenticate")
|
||||
class AuthenticateCmd: Callable<Int> {
|
||||
|
||||
/**
|
||||
* Parent command to acquire global options from.
|
||||
*/
|
||||
@ParentCommand
|
||||
lateinit var parent: WotCLI
|
||||
|
||||
/**
|
||||
* Fingerprint of the certificate.
|
||||
*/
|
||||
@Parameters(index = "0")
|
||||
lateinit var fingerprint: String
|
||||
|
||||
/**
|
||||
* User-ID to authenticate.
|
||||
*/
|
||||
@Parameters(index = "1")
|
||||
lateinit var userId: String
|
||||
|
||||
/**
|
||||
* Handle the User-ID as an email address.
|
||||
*/
|
||||
@CommandLine.Option(names = ["--email"], description = ["Consider all user-IDs that contain the given email address."])
|
||||
var email = false
|
||||
|
||||
|
@ -46,6 +61,9 @@ class AuthenticateCmd: Callable<Int> {
|
|||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the [AuthenticateAPI.Result] as a [String] which can be printed to standard out.
|
||||
*/
|
||||
internal fun formatResult(result: AuthenticateAPI.Result): String {
|
||||
if (result.percentage < 100) {
|
||||
return "No paths found."
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.pgpainless.wot.cli.subcommands
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.wot.api.AuthenticateAPI
|
||||
import org.pgpainless.wot.dijkstra.sq.api.AuthenticateAPI
|
||||
import org.pgpainless.wot.dijkstra.sq.*
|
||||
import java.text.SimpleDateFormat
|
||||
import kotlin.test.assertEquals
|
||||
|
|
|
@ -43,14 +43,23 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) {
|
|||
*
|
||||
* @param certificateDirectory PGP-Certificate-Directory instance
|
||||
*/
|
||||
constructor(certificateDirectory: PGPCertificateDirectory): this(PGPCertificateStoreAdapter(certificateDirectory))
|
||||
constructor(certificateDirectory: PGPCertificateDirectory):
|
||||
this(PGPCertificateStoreAdapter(certificateDirectory))
|
||||
|
||||
fun buildNetwork(policy: Policy = PGPainless.getPolicy(), referenceTime: ReferenceTime = now()): Network {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fun buildNetwork(policy: Policy = PGPainless.getPolicy(),
|
||||
referenceTime: ReferenceTime = now()): Network {
|
||||
val certificates = getAllCertificatesFromTheStore()
|
||||
val networkFactory = PGPNetworkFactory.fromCertificates(certificates, policy, referenceTime)
|
||||
return networkFactory.buildNetwork()
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a [Sequence] containing all [Certificates][Certificate] in the [PGPCertificateStore],
|
||||
* with the specially named "trust-root" certificate optionally appended if present.
|
||||
*/
|
||||
private fun getAllCertificatesFromTheStore(): Sequence<Certificate> {
|
||||
var trustRoot: Certificate? = null
|
||||
try {
|
||||
|
@ -157,7 +166,8 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) {
|
|||
while (userIds.hasNext()) {
|
||||
val userId = userIds.next()
|
||||
// There are potentially multiple certifications per user-ID
|
||||
val userIdSigs = SignatureUtils.get3rdPartyCertificationsFor(userId, validatedTargetKeyRing)
|
||||
val userIdSigs = SignatureUtils.get3rdPartyCertificationsFor(
|
||||
userId, validatedTargetKeyRing)
|
||||
userIdSigs.forEach {
|
||||
processCertificationOnUserId(targetPrimaryKey, target, userId, it)
|
||||
}
|
||||
|
@ -194,7 +204,8 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) {
|
|||
}
|
||||
} catch (e: SignatureValidationException) {
|
||||
val targetFingerprint = OpenPgpFingerprint.of(targetPrimaryKey)
|
||||
LOGGER.warn("Cannot verify signature by $issuerFingerprint on cert of $targetFingerprint", e)
|
||||
LOGGER.warn("Cannot verify signature by $issuerFingerprint" +
|
||||
" on cert of $targetFingerprint", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +332,8 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) {
|
|||
referenceTime: ReferenceTime): List<KeyRingInfo> {
|
||||
return certificates
|
||||
.mapNotNull {
|
||||
try { PGPainless.readKeyRing().publicKeyRing(it.inputStream) } catch (e: IOException) { null }
|
||||
try { PGPainless.readKeyRing().publicKeyRing(it.inputStream) }
|
||||
catch (e: IOException) { null }
|
||||
}
|
||||
.map { KeyRingInfo(it, policy, referenceTime.timestamp) }
|
||||
.toList()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.api
|
||||
package org.pgpainless.wot.dijkstra.sq.api
|
||||
|
||||
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||
import org.pgpainless.wot.dijkstra.sq.Paths
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.api
|
||||
package org.pgpainless.wot.dijkstra.sq.api
|
||||
|
||||
/**
|
||||
* Enum for different levels of Trust.
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.cli.subcommands
|
||||
package org.pgpainless.wot.dijkstra.sq.api
|
||||
|
||||
/**
|
||||
* Enum listing possible output formats.
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.api
|
||||
package org.pgpainless.wot.dijkstra.sq.api
|
||||
|
||||
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||
import org.pgpainless.wot.dijkstra.sq.Paths
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.api
|
||||
package org.pgpainless.wot.dijkstra.sq.api
|
||||
|
||||
import org.pgpainless.wot.dijkstra.sq.Paths
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.api
|
||||
package org.pgpainless.wot.dijkstra.sq.api
|
||||
|
||||
import org.pgpainless.wot.dijkstra.sq.Paths
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.api
|
||||
package org.pgpainless.wot.dijkstra.sq.api
|
||||
|
||||
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||
|
|
@ -2,20 +2,16 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.api
|
||||
package org.pgpainless.wot.dijkstra.sq.api
|
||||
|
||||
import org.pgpainless.certificate_store.PGPainlessCertD
|
||||
import org.pgpainless.util.NotationRegistry
|
||||
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||
import org.pgpainless.wot.dijkstra.sq.Network
|
||||
import org.pgpainless.wot.dijkstra.sq.ReferenceTime
|
||||
import pgp.cert_d.PGPCertificateStoreAdapter
|
||||
import pgp.cert_d.subkey_lookup.InMemorySubkeyLookupFactory
|
||||
import pgp.certificate_store.PGPCertificateStore
|
||||
|
||||
/**
|
||||
* Web of Trust API, offering different operations.
|
||||
*
|
||||
* @param certStores one or more [PGPCertificateStores][PGPCertificateStore] to retrieve certificates from.
|
||||
* @param network initialized [Network] containing certificates as nodes and certifications as edges.
|
||||
* @param trustRoots one or more [Fingerprints][Fingerprint] of trust-roots.
|
||||
* @param gossip if true, consider all certificates as weakly trusted trust-roots
|
||||
* @param certificationNetwork if true, all certifications are treated as delegations with infinite trust depth and no regular expressions
|
||||
|
@ -24,35 +20,24 @@ import pgp.certificate_store.PGPCertificateStore
|
|||
* @param knownNotationRegistry registry of known notations
|
||||
*/
|
||||
class WoTAPI(
|
||||
val certStores: List<PGPCertificateStore> = getDefaultCertStores(),
|
||||
val network: Network,
|
||||
val trustRoots: List<Fingerprint>,
|
||||
val gossip: Boolean = false,
|
||||
val certificationNetwork: Boolean = false,
|
||||
val trustAmount: Int = AuthenticationLevel.Fully.amount,
|
||||
val referenceTime: ReferenceTime = ReferenceTime.now(),
|
||||
val knownNotationRegistry: NotationRegistry = NotationRegistry()
|
||||
val referenceTime: ReferenceTime = ReferenceTime.now()
|
||||
): AuthenticateAPI, IdentifyAPI, ListAPI, LookupAPI, PathAPI {
|
||||
|
||||
/**
|
||||
* Secondary constructor, taking an [AuthenticationLevel] instead of an [Int].
|
||||
*/
|
||||
constructor(certStores: List<PGPCertificateStore> = getDefaultCertStores(),
|
||||
constructor(network: Network,
|
||||
trustRoots: List<Fingerprint>,
|
||||
gossip: Boolean = false,
|
||||
certificationNetwork: Boolean = false,
|
||||
trustAmount: AuthenticationLevel = AuthenticationLevel.Fully,
|
||||
referenceTime: ReferenceTime = ReferenceTime.now(),
|
||||
knownNotationRegistry: NotationRegistry = NotationRegistry()):
|
||||
this(certStores,trustRoots, gossip,certificationNetwork, trustAmount.amount, referenceTime, knownNotationRegistry)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getDefaultCertStores(): List<PGPCertificateStore> {
|
||||
val certD = PGPainlessCertD.fileBased(InMemorySubkeyLookupFactory())
|
||||
val asStore = PGPCertificateStoreAdapter(certD)
|
||||
return listOf(asStore)
|
||||
}
|
||||
}
|
||||
referenceTime: ReferenceTime = ReferenceTime.now()):
|
||||
this(network,trustRoots, gossip,certificationNetwork, trustAmount.amount, referenceTime)
|
||||
|
||||
override fun authenticate(arguments: AuthenticateAPI.Arguments): AuthenticateAPI.Result {
|
||||
TODO("Not yet implemented")
|
Loading…
Reference in a new issue