mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-25 12:27:58 +01:00
Port more test vectors to kotlin
This commit is contained in:
parent
8974c44b51
commit
016c9dfc03
6 changed files with 384 additions and 299 deletions
|
@ -34,16 +34,19 @@ dependencies {
|
||||||
testFixturesImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
|
testFixturesImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
|
||||||
testFixturesImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion"
|
testFixturesImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion"
|
||||||
testFixturesRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
|
testFixturesRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
|
||||||
|
testFixturesApi(project(":pgpainless-core"))
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
testImplementation "ch.qos.logback:logback-classic:$logbackVersion"
|
testImplementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||||
|
|
||||||
implementation(project(":pgpainless-core"))
|
|
||||||
api(project(":wot-dijkstra"))
|
|
||||||
|
|
||||||
// Certificate store
|
// Certificate store
|
||||||
api "org.pgpainless:pgp-certificate-store:$certDJavaVersion"
|
api "org.pgpainless:pgp-certificate-store:$certDJavaVersion"
|
||||||
api "org.pgpainless:pgpainless-cert-d:$pgpainlessCertDVersion"
|
api ("org.pgpainless:pgpainless-cert-d:$pgpainlessCertDVersion") {
|
||||||
|
exclude(group: "org.pgpainless", module: "pgpainless-core")
|
||||||
|
}
|
||||||
|
|
||||||
|
implementation(project(":pgpainless-core"))
|
||||||
|
api(project(":wot-dijkstra"))
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.pgpainless.wot
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.pgpainless.wot.testfixtures.AdHocVectors
|
||||||
|
|
||||||
|
class AdHocTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test() {
|
||||||
|
val store = AdHocVectors.BestViaRoot().pgpCertificateStore
|
||||||
|
val wot = WebOfTrust(store).also { it.initialize() }
|
||||||
|
val network = wot.network
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,11 +20,11 @@ import kotlin.test.Test
|
||||||
|
|
||||||
class WebOfTrustTest {
|
class WebOfTrustTest {
|
||||||
|
|
||||||
private val fooBankCa = fingerprintOf(WotTestVectors.getTestVectors().freshFooBankCaCert)
|
private val fooBankCa = fingerprintOf(WotTestVectors.freshFooBankCaCert)
|
||||||
private val fooBankEmployee = fingerprintOf(WotTestVectors.getTestVectors().freshFooBankEmployeeCert)
|
private val fooBankEmployee = fingerprintOf(WotTestVectors.freshFooBankEmployeeCert)
|
||||||
private val fooBankAdmin = fingerprintOf(WotTestVectors.getTestVectors().freshFooBankAdminCert)
|
private val fooBankAdmin = fingerprintOf(WotTestVectors.freshFooBankAdminCert)
|
||||||
private val barBankCa = fingerprintOf(WotTestVectors.getTestVectors().freshBarBankCaCert)
|
private val barBankCa = fingerprintOf(WotTestVectors.freshBarBankCaCert)
|
||||||
private val barBankEmployee = fingerprintOf(WotTestVectors.getTestVectors().freshBarBankEmployeeCert)
|
private val barBankEmployee = fingerprintOf(WotTestVectors.freshBarBankEmployeeCert)
|
||||||
|
|
||||||
private fun fingerprintOf(cert: PGPPublicKeyRing): Fingerprint {
|
private fun fingerprintOf(cert: PGPPublicKeyRing): Fingerprint {
|
||||||
return Fingerprint(OpenPgpFingerprint.of(cert).toString())
|
return Fingerprint(OpenPgpFingerprint.of(cert).toString())
|
||||||
|
|
|
@ -1,290 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package org.pgpainless.wot.testfixtures;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
|
||||||
import org.pgpainless.PGPainless;
|
|
||||||
import org.pgpainless.algorithm.Trustworthiness;
|
|
||||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
|
||||||
import org.pgpainless.signature.subpackets.CertificationSubpackets;
|
|
||||||
import org.pgpainless.util.Passphrase;
|
|
||||||
|
|
||||||
public class WotTestVectors {
|
|
||||||
|
|
||||||
private static WotTestVectors INSTANCE = null;
|
|
||||||
|
|
||||||
public static WotTestVectors getTestVectors() {
|
|
||||||
if (INSTANCE == null) {
|
|
||||||
INSTANCE = new WotTestVectors();
|
|
||||||
}
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPSecretKeyRing getFreshFooBankCaKey() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().secretKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/foobankCaKey.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getFreshFooBankCaCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/foobankCaCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFooBankCaPassphrase() {
|
|
||||||
return "superS3cureP4ssphrase";
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecretKeyRingProtector getFooBankCaProtector() {
|
|
||||||
return SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword(getFooBankCaPassphrase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPSecretKeyRing getFreshFooBankEmployeeKey() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().secretKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/foobankEmployeeKey.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getFreshFooBankEmployeeCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/foobankEmployeeCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFooBankEmployeePassphrase() {
|
|
||||||
return "iLoveWorking@FooBank";
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecretKeyRingProtector getFooBankEmployeeProtector() {
|
|
||||||
return SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword(getFooBankEmployeePassphrase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPSecretKeyRing getFreshFooBankAdminKey() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().secretKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/foobankAdminKey.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getFreshFooBankAdminCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/foobankAdminCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFooBankAdminPassphrase() {
|
|
||||||
return "keepFooBankSecure";
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecretKeyRingProtector getFooBankAdminProtector() {
|
|
||||||
return SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword(getFooBankAdminPassphrase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPSecretKeyRing getFreshFooBankCustomerKey() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().secretKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/foobankCustomerKey.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getFreshFooBankCustomerCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/foobankCustomerCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPSecretKeyRing getFreshBarBankCaKey() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().secretKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/barbankCaKey.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getFreshBarBankCaCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/barbankCaCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPSecretKeyRing getFreshBarBankEmployeeKey() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().secretKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/barbankEmployeeKey.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getFreshBarBankEmployeeCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/barbankEmployeeCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPSecretKeyRing getFreshFakeFooBankEmployeeKey() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().secretKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/fakeFoobankEmployeeKey.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getFreshFakeFooBankEmployeeCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("test_vectors/freshly_generated/fakeFoobankEmployeeCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getCrossSignedBarBankCaCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("cross_signed/barbankCaCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getCrossSignedBarBankEmployeeCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("cross_signed/barbankEmployeeCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getCrossSignedFooBankAdminCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("cross_signed/foobankAdminCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getCrossSignedFooBankCaCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("cross_signed/foobankCaCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getCrossSignedFooBankEmployeeCert() throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("cross_signed/foobankEmployeeCert.asc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws PGPException, IOException {
|
|
||||||
new WotTestVectors().crossSign();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate cross signed test vectors from freshly generated
|
|
||||||
public void crossSign() throws IOException, PGPException {
|
|
||||||
PGPSecretKeyRing freshFooBankCaKey = getFreshFooBankCaKey();
|
|
||||||
PGPPublicKeyRing freshFooBankCaCert = getFreshFooBankCaCert();
|
|
||||||
|
|
||||||
PGPSecretKeyRing freshFooBankEmployeeKey = getFreshFooBankEmployeeKey();
|
|
||||||
PGPPublicKeyRing freshFooBankEmployeeCert = getFreshFooBankEmployeeCert();
|
|
||||||
|
|
||||||
PGPSecretKeyRing freshFooBankAdminKey = getFreshFooBankAdminKey();
|
|
||||||
PGPPublicKeyRing freshFooBankAdminCert = getFreshFooBankAdminCert();
|
|
||||||
|
|
||||||
PGPSecretKeyRing freshFooBankCustomerKey = getFreshFooBankCustomerKey();
|
|
||||||
PGPPublicKeyRing freshFooBankCustomerCert = getFreshFooBankCustomerCert();
|
|
||||||
|
|
||||||
PGPSecretKeyRing freshBarBankCaKey = getFreshBarBankCaKey();
|
|
||||||
PGPPublicKeyRing freshBarBankCaCert = getFreshBarBankCaCert();
|
|
||||||
|
|
||||||
PGPSecretKeyRing freshBarBankEmployeeKey = getFreshBarBankEmployeeKey();
|
|
||||||
PGPPublicKeyRing freshBarBankEmployeeCert = getFreshBarBankEmployeeCert();
|
|
||||||
|
|
||||||
PGPSecretKeyRing freshFakeFooBankEmployeeKey = getFreshFakeFooBankEmployeeKey();
|
|
||||||
PGPPublicKeyRing freshFakeFooBankEmployeeCert = getFreshFakeFooBankEmployeeCert();
|
|
||||||
|
|
||||||
final String fooBankRegex = "<[^>]+[@.]foobank\\.com>$";
|
|
||||||
final String barBankRegex = "<[^>]+[@.]barbank\\.com>$";
|
|
||||||
|
|
||||||
// Foo CA signs Foo Employee
|
|
||||||
PGPPublicKeyRing caCertifiedFooBankEmployeeCert = PGPainless.certify()
|
|
||||||
.userIdOnCertificate("Foo Bank Employee <employee@foobank.com>", freshFooBankEmployeeCert)
|
|
||||||
.withKey(freshFooBankCaKey, getFooBankCaProtector())
|
|
||||||
.buildWithSubpackets(new CertificationSubpackets.Callback() {
|
|
||||||
@Override
|
|
||||||
public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) {
|
|
||||||
hashedSubpackets.addNotationData(false, "affiliation@foobank.com", "employee");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.getCertifiedCertificate();
|
|
||||||
|
|
||||||
// Foo CA signs Foo Admin
|
|
||||||
PGPPublicKeyRing caCertifiedFooBankAdminCert = PGPainless.certify()
|
|
||||||
.userIdOnCertificate("Foo Bank Admin <admin@foobank.com>", freshFooBankAdminCert)
|
|
||||||
.withKey(freshFooBankCaKey, getFooBankCaProtector())
|
|
||||||
.buildWithSubpackets(new CertificationSubpackets.Callback() {
|
|
||||||
@Override
|
|
||||||
public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) {
|
|
||||||
hashedSubpackets.addNotationData(false, "affiliation@foobank.com", "administrator");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.getCertifiedCertificate();
|
|
||||||
|
|
||||||
// Foo Employee delegates trust to Foo CA
|
|
||||||
PGPPublicKeyRing employeeDelegatedCaCert = PGPainless.certify()
|
|
||||||
.certificate(freshFooBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
|
||||||
.withKey(freshFooBankEmployeeKey, getFooBankEmployeeProtector())
|
|
||||||
.buildWithSubpackets(new CertificationSubpackets.Callback() {
|
|
||||||
@Override
|
|
||||||
public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) {
|
|
||||||
hashedSubpackets.setRegularExpression(fooBankRegex);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.getCertifiedCertificate();
|
|
||||||
|
|
||||||
// Foo Admin delegates trust to Foo CA
|
|
||||||
PGPPublicKeyRing adminDelegatedCaCert = PGPainless.certify()
|
|
||||||
.certificate(freshFooBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
|
||||||
.withKey(freshFooBankAdminKey, getFooBankAdminProtector())
|
|
||||||
.buildWithSubpackets(new CertificationSubpackets.Callback() {
|
|
||||||
@Override
|
|
||||||
public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) {
|
|
||||||
hashedSubpackets.setRegularExpression(fooBankRegex);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.getCertifiedCertificate();
|
|
||||||
|
|
||||||
// Customer delegates trust to Foo CA
|
|
||||||
PGPPublicKeyRing customerDelegatedCaCert = PGPainless.certify()
|
|
||||||
.certificate(freshFooBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
|
||||||
.withKey(freshFooBankCustomerKey, SecretKeyRingProtector.unprotectedKeys())
|
|
||||||
.buildWithSubpackets(new CertificationSubpackets.Callback() {
|
|
||||||
@Override
|
|
||||||
public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) {
|
|
||||||
hashedSubpackets.setRegularExpression(fooBankRegex);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.getCertifiedCertificate();
|
|
||||||
|
|
||||||
PGPPublicKeyRing mergedFooCa = PGPPublicKeyRing.join(employeeDelegatedCaCert, adminDelegatedCaCert);
|
|
||||||
mergedFooCa = PGPPublicKeyRing.join(mergedFooCa, customerDelegatedCaCert);
|
|
||||||
|
|
||||||
// Foo Admin delegates trust to Bar CA
|
|
||||||
PGPPublicKeyRing fooAdminDelegatedBarCa = PGPainless.certify()
|
|
||||||
.certificate(freshBarBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
|
||||||
.withKey(freshFooBankAdminKey, getFooBankAdminProtector())
|
|
||||||
.buildWithSubpackets(new CertificationSubpackets.Callback() {
|
|
||||||
@Override
|
|
||||||
public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) {
|
|
||||||
hashedSubpackets.setRegularExpression("<[^>]+[@.]barbank\\.com>$");
|
|
||||||
}
|
|
||||||
}).getCertifiedCertificate();
|
|
||||||
|
|
||||||
// Bar Employee delegates Bar CA
|
|
||||||
PGPPublicKeyRing barEmployeeDelegatesBarCa = PGPainless.certify()
|
|
||||||
.certificate(freshBarBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
|
||||||
.withKey(freshBarBankEmployeeKey, SecretKeyRingProtector.unprotectedKeys())
|
|
||||||
.buildWithSubpackets(new CertificationSubpackets.Callback() {
|
|
||||||
@Override
|
|
||||||
public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) {
|
|
||||||
hashedSubpackets.setRegularExpression(barBankRegex);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.getCertifiedCertificate();
|
|
||||||
|
|
||||||
PGPPublicKeyRing mergedBarCa = PGPPublicKeyRing.join(fooAdminDelegatedBarCa, barEmployeeDelegatesBarCa);
|
|
||||||
|
|
||||||
// Bar CA signs Bar Employee
|
|
||||||
PGPPublicKeyRing barCaCertifiedEmployeeCert = PGPainless.certify()
|
|
||||||
.userIdOnCertificate("Bar Bank Employee <employee@barbank.com>", freshBarBankEmployeeCert)
|
|
||||||
.withKey(freshBarBankCaKey, SecretKeyRingProtector.unprotectedKeys())
|
|
||||||
.buildWithSubpackets(new CertificationSubpackets.Callback() {
|
|
||||||
@Override
|
|
||||||
public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) {
|
|
||||||
hashedSubpackets.addNotationData(false, "affiliation@barbank.com", "employee");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.getCertifiedCertificate();
|
|
||||||
|
|
||||||
// CHECKSTYLE:OFF
|
|
||||||
System.out.println("Foo Employee");
|
|
||||||
System.out.println(PGPainless.asciiArmor(caCertifiedFooBankEmployeeCert));
|
|
||||||
|
|
||||||
System.out.println("Foo Admin");
|
|
||||||
System.out.println(PGPainless.asciiArmor(caCertifiedFooBankAdminCert));
|
|
||||||
|
|
||||||
System.out.println("Foo CA");
|
|
||||||
System.out.println(PGPainless.asciiArmor(mergedFooCa));
|
|
||||||
|
|
||||||
System.out.println("Bar CA");
|
|
||||||
System.out.println(PGPainless.asciiArmor(mergedBarCa));
|
|
||||||
|
|
||||||
System.out.println("Bar Employee");
|
|
||||||
System.out.println(PGPainless.asciiArmor(barCaCertifiedEmployeeCert));
|
|
||||||
// CHECKSTYLE:ON
|
|
||||||
}
|
|
||||||
|
|
||||||
private static InputStream getTestResourceInputStream(String resource) {
|
|
||||||
InputStream inputStream = WotTestVectors.class.getClassLoader().getResourceAsStream(resource);
|
|
||||||
if (inputStream == null) {
|
|
||||||
throw new IllegalArgumentException(String.format("Unknown resource %s", resource));
|
|
||||||
}
|
|
||||||
return inputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPPublicKeyRing getFelixKey()
|
|
||||||
throws IOException {
|
|
||||||
return PGPainless.readKeyRing().publicKeyRing(getTestResourceInputStream("test_vectors/anomalies/felix.pub"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
package org.pgpainless.wot.testfixtures
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPKeyRing
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing
|
||||||
|
import org.pgpainless.PGPainless
|
||||||
|
import org.pgpainless.key.OpenPgpFingerprint
|
||||||
|
import org.pgpainless.key.generation.type.rsa.RsaLength
|
||||||
|
import org.pgpainless.key.protection.SecretKeyRingProtector
|
||||||
|
import org.pgpainless.signature.subpackets.CertificationSubpackets
|
||||||
|
import org.pgpainless.signature.subpackets.CertificationSubpackets.Callback
|
||||||
|
import org.pgpainless.wot.KeyRingCertificateStore
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||||
|
import pgp.certificate_store.PGPCertificateStore
|
||||||
|
|
||||||
|
interface AdHocVectors {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When doing backwards propagation, we find paths from all nodes to the
|
||||||
|
* target. Since we don't stop when we reach a root, the returned path
|
||||||
|
* should still be optimal. Consider:
|
||||||
|
*
|
||||||
|
* A --- 120/10 ---> B --- 120/10 ---> C --- 120/10 ---> Target
|
||||||
|
* \ /
|
||||||
|
* `--- 50/10 ---> Y --- 50/10 ---> Z --- 50/10 --------'
|
||||||
|
* When the root is B, then the path that we find for A should be A -> B -> C -> Target, not A -> Y -> Z -> Target.
|
||||||
|
*/
|
||||||
|
class BestViaRoot : AdHocVectors {
|
||||||
|
val aliceUID: String = "Alice <alice@pgpainless.org>"
|
||||||
|
val aliceKey: PGPSecretKeyRing = PGPainless.generateKeyRing().modernKeyRing(aliceUID)
|
||||||
|
val aliceCert = PGPPublicKeyRing(aliceKey)
|
||||||
|
val aliceFingerprint = Fingerprint(aliceKey)
|
||||||
|
|
||||||
|
val bobUID = "Bob <bob@pgpainless.org>"
|
||||||
|
val bobKey: PGPSecretKeyRing = PGPainless.generateKeyRing().simpleRsaKeyRing(bobUID, RsaLength._3072)
|
||||||
|
val bobCert = PGPPublicKeyRing(bobKey)
|
||||||
|
val bobFingerprint = Fingerprint(bobKey)
|
||||||
|
|
||||||
|
val carolUID = "Carol <carol@example.com>"
|
||||||
|
val carolKey: PGPSecretKeyRing = PGPainless.generateKeyRing().simpleEcKeyRing(carolUID)
|
||||||
|
val carolCert = PGPPublicKeyRing(carolKey)
|
||||||
|
val carolFingerprint = Fingerprint(carolKey)
|
||||||
|
|
||||||
|
val targetUID = "Tanja <tanja@target.tld>"
|
||||||
|
val targetKey: PGPSecretKeyRing = PGPainless.generateKeyRing().modernKeyRing(targetUID)
|
||||||
|
val targetCert = PGPPublicKeyRing(targetKey)
|
||||||
|
val targetFingerprint = Fingerprint(targetKey)
|
||||||
|
|
||||||
|
val yellowUID = "Yellow <yellow@alternate.path>"
|
||||||
|
val yellowKey: PGPSecretKeyRing = PGPainless.generateKeyRing().modernKeyRing(yellowUID)
|
||||||
|
val yellowCert = PGPPublicKeyRing(yellowKey)
|
||||||
|
val yellowFingerprint = Fingerprint(yellowKey)
|
||||||
|
|
||||||
|
val zebraUID = "Zebra <zebra@alternate.path>"
|
||||||
|
val zebraKey: PGPSecretKeyRing = PGPainless.generateKeyRing().modernKeyRing(zebraUID)
|
||||||
|
val zebraCert = PGPPublicKeyRing(zebraKey)
|
||||||
|
val zebraFingerprint = Fingerprint(zebraKey)
|
||||||
|
|
||||||
|
override val publicKeyRingCollection: PGPPublicKeyRingCollection
|
||||||
|
get() {
|
||||||
|
val signedCerts = listOf(
|
||||||
|
targetCert.let {
|
||||||
|
// C ---120/10--> Target
|
||||||
|
certify(issuer = carolKey, target = it, amount = 120, depth = 10)
|
||||||
|
}.let {
|
||||||
|
// Z ---50/10---> Target
|
||||||
|
certify(issuer = zebraKey, target = it, amount = 50, depth = 10)
|
||||||
|
},
|
||||||
|
carolCert.let {
|
||||||
|
// B ---120/10--> C
|
||||||
|
certify(issuer = bobKey, target = it, amount = 120, depth = 10)
|
||||||
|
},
|
||||||
|
bobCert.let {
|
||||||
|
// A ---120/10--> B
|
||||||
|
certify(issuer = aliceKey, target = it, amount = 120, depth = 10)
|
||||||
|
},
|
||||||
|
zebraCert.let {
|
||||||
|
// Y ---50/10--> Z
|
||||||
|
certify(issuer = yellowKey, target = it, amount = 50, depth = 10)
|
||||||
|
},
|
||||||
|
yellowCert.let {
|
||||||
|
// A ---50/10--> Y
|
||||||
|
certify(issuer = aliceKey, target = it, amount = 50, depth = 10)
|
||||||
|
})
|
||||||
|
return PGPPublicKeyRingCollection(signedCerts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val publicKeyRingCollection: PGPPublicKeyRingCollection
|
||||||
|
|
||||||
|
val pgpCertificateStore: PGPCertificateStore
|
||||||
|
get() = KeyRingCertificateStore(publicKeyRingCollection)
|
||||||
|
|
||||||
|
fun certify(issuer: PGPSecretKeyRing,
|
||||||
|
target: PGPPublicKeyRing,
|
||||||
|
userId: String = target.publicKey.userIDs.next()!!,
|
||||||
|
amount: Int,
|
||||||
|
depth: Int): PGPPublicKeyRing = PGPainless.certify()
|
||||||
|
.userIdOnCertificate(userId, target)
|
||||||
|
.withKey(issuer, SecretKeyRingProtector.unprotectedKeys())
|
||||||
|
.buildWithSubpackets(object : Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets?) {
|
||||||
|
hashedSubpackets!!.setTrust(depth, amount)
|
||||||
|
}
|
||||||
|
}).certifiedCertificate
|
||||||
|
|
||||||
|
fun PGPPublicKeyRing(secretKey: PGPSecretKeyRing): PGPPublicKeyRing =
|
||||||
|
PGPainless.extractCertificate(secretKey)
|
||||||
|
|
||||||
|
fun Fingerprint(keyRing: PGPKeyRing): Fingerprint =
|
||||||
|
Fingerprint(OpenPgpFingerprint.of(keyRing).toString())
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
package org.pgpainless.wot.testfixtures
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing
|
||||||
|
import org.pgpainless.PGPainless
|
||||||
|
import org.pgpainless.algorithm.Trustworthiness
|
||||||
|
import org.pgpainless.key.protection.SecretKeyRingProtector
|
||||||
|
import org.pgpainless.signature.subpackets.CertificationSubpackets
|
||||||
|
import org.pgpainless.util.Passphrase
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
class WotTestVectors {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getTestResource(resource: String): InputStream {
|
||||||
|
val input = WotTestVectors::class.java.classLoader.getResourceAsStream(resource)
|
||||||
|
return requireNotNull(input) {
|
||||||
|
"Unknown resource $resource"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFooBankCaKey: PGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/foobankCaKey.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFooBankCaCert: PGPPublicKeyRing = PGPainless.readKeyRing().publicKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/foobankCaCert.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val fooBankCaPassphrase = "superS3cureP4ssphrase"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val fooBankCaProtector: SecretKeyRingProtector = SecretKeyRingProtector.unlockAnyKeyWith(
|
||||||
|
Passphrase.fromPassword(fooBankCaPassphrase))
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFooBankEmployeeKey: PGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/foobankEmployeeKey.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFooBankEmployeeCert: PGPPublicKeyRing = PGPainless.readKeyRing().publicKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/foobankEmployeeCert.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val fooBankEmployeePassphrase = "iLoveWorking@FooBank"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val fooBankEmployeeProtector: SecretKeyRingProtector = SecretKeyRingProtector.unlockAnyKeyWith(
|
||||||
|
Passphrase.fromPassword(fooBankEmployeePassphrase))
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFooBankAdminKey: PGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/foobankAdminKey.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFooBankAdminCert: PGPPublicKeyRing = PGPainless.readKeyRing().publicKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/foobankAdminCert.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val fooBankAdminPassphrase = "keepFooBankSecure"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val fooBankAdminProtector: SecretKeyRingProtector = SecretKeyRingProtector.unlockAnyKeyWith(
|
||||||
|
Passphrase.fromPassword(fooBankAdminPassphrase))
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFooBankCustomerKey: PGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/foobankCustomerKey.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFooBankCustomerCert: PGPPublicKeyRing = PGPainless.readKeyRing().publicKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/foobankCustomerCert.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val fooBankCustomerProtector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshBarBankCaKey: PGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/barbankCaKey.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshBarBankCaCert: PGPPublicKeyRing = PGPainless.readKeyRing().publicKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/barbankCaCert.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val barBankCaProtector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshBarBankEmployeeKey: PGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/barbankEmployeeKey.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshBarBankEmployeeCert: PGPPublicKeyRing = PGPainless.readKeyRing().publicKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/barbankEmployeeCert.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFakeFooBankEmployeeKey: PGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/fakeFoobankEmployeeKey.asc"))!!
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val freshFakeFooBankEmployeeCert: PGPPublicKeyRing = PGPainless.readKeyRing().publicKeyRing(
|
||||||
|
getTestResource("test_vectors/freshly_generated/fakeFoobankEmployeeCert.asc"))!!
|
||||||
|
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun getCrossSignedBarBankCaCert(): PGPPublicKeyRing? {
|
||||||
|
return PGPainless.readKeyRing().publicKeyRing(getTestResource("cross_signed/barbankCaCert.asc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun getCrossSignedBarBankEmployeeCert(): PGPPublicKeyRing? {
|
||||||
|
return PGPainless.readKeyRing().publicKeyRing(getTestResource("cross_signed/barbankEmployeeCert.asc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun getCrossSignedFooBankAdminCert(): PGPPublicKeyRing? {
|
||||||
|
return PGPainless.readKeyRing().publicKeyRing(getTestResource("cross_signed/foobankAdminCert.asc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun getCrossSignedFooBankCaCert(): PGPPublicKeyRing? {
|
||||||
|
return PGPainless.readKeyRing().publicKeyRing(getTestResource("cross_signed/foobankCaCert.asc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun getCrossSignedFooBankEmployeeCert(): PGPPublicKeyRing? {
|
||||||
|
return PGPainless.readKeyRing().publicKeyRing(getTestResource("cross_signed/foobankEmployeeCert.asc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate cross signed test vectors from freshly generated
|
||||||
|
@Throws(IOException::class, PGPException::class)
|
||||||
|
fun crossSign() {
|
||||||
|
val fooBankRegex = "<[^>]+[@.]foobank\\.com>$"
|
||||||
|
val barBankRegex = "<[^>]+[@.]barbank\\.com>$"
|
||||||
|
|
||||||
|
// Foo CA signs Foo Employee
|
||||||
|
val caCertifiedFooBankEmployeeCert = PGPainless.certify()
|
||||||
|
.userIdOnCertificate("Foo Bank Employee <employee@foobank.com>", freshFooBankEmployeeCert)
|
||||||
|
.withKey(freshFooBankCaKey, fooBankCaProtector)
|
||||||
|
.buildWithSubpackets(object : CertificationSubpackets.Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets) {
|
||||||
|
hashedSubpackets.addNotationData(false, "affiliation@foobank.com", "employee")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.certifiedCertificate
|
||||||
|
|
||||||
|
// Foo CA signs Foo Admin
|
||||||
|
val caCertifiedFooBankAdminCert = PGPainless.certify()
|
||||||
|
.userIdOnCertificate("Foo Bank Admin <admin@foobank.com>", freshFooBankAdminCert)
|
||||||
|
.withKey(freshFooBankCaKey, fooBankCaProtector)
|
||||||
|
.buildWithSubpackets(object : CertificationSubpackets.Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets) {
|
||||||
|
hashedSubpackets.addNotationData(false, "affiliation@foobank.com", "administrator")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.certifiedCertificate
|
||||||
|
|
||||||
|
// Foo Employee delegates trust to Foo CA
|
||||||
|
val employeeDelegatedCaCert = PGPainless.certify()
|
||||||
|
.certificate(freshFooBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
||||||
|
.withKey(freshFooBankEmployeeKey, fooBankEmployeeProtector)
|
||||||
|
.buildWithSubpackets(object : CertificationSubpackets.Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets) {
|
||||||
|
hashedSubpackets.setRegularExpression(fooBankRegex)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.certifiedCertificate
|
||||||
|
|
||||||
|
// Foo Admin delegates trust to Foo CA
|
||||||
|
val adminDelegatedCaCert = PGPainless.certify()
|
||||||
|
.certificate(freshFooBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
||||||
|
.withKey(freshFooBankAdminKey, fooBankAdminProtector)
|
||||||
|
.buildWithSubpackets(object : CertificationSubpackets.Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets) {
|
||||||
|
hashedSubpackets.setRegularExpression(fooBankRegex)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.certifiedCertificate
|
||||||
|
|
||||||
|
// Customer delegates trust to Foo CA
|
||||||
|
val customerDelegatedCaCert = PGPainless.certify()
|
||||||
|
.certificate(freshFooBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
||||||
|
.withKey(freshFooBankCustomerKey, SecretKeyRingProtector.unprotectedKeys())
|
||||||
|
.buildWithSubpackets(object : CertificationSubpackets.Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets) {
|
||||||
|
hashedSubpackets.setRegularExpression(fooBankRegex)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.certifiedCertificate
|
||||||
|
var mergedFooCa = PGPPublicKeyRing.join(employeeDelegatedCaCert, adminDelegatedCaCert)
|
||||||
|
mergedFooCa = PGPPublicKeyRing.join(mergedFooCa, customerDelegatedCaCert)
|
||||||
|
|
||||||
|
// Foo Admin delegates trust to Bar CA
|
||||||
|
val fooAdminDelegatedBarCa = PGPainless.certify()
|
||||||
|
.certificate(freshBarBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
||||||
|
.withKey(freshFooBankAdminKey, fooBankAdminProtector)
|
||||||
|
.buildWithSubpackets(object : CertificationSubpackets.Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets) {
|
||||||
|
hashedSubpackets.setRegularExpression("<[^>]+[@.]barbank\\.com>$")
|
||||||
|
}
|
||||||
|
}).certifiedCertificate
|
||||||
|
|
||||||
|
// Bar Employee delegates Bar CA
|
||||||
|
val barEmployeeDelegatesBarCa = PGPainless.certify()
|
||||||
|
.certificate(freshBarBankCaCert, Trustworthiness.fullyTrusted().introducer())
|
||||||
|
.withKey(freshBarBankEmployeeKey, SecretKeyRingProtector.unprotectedKeys())
|
||||||
|
.buildWithSubpackets(object : CertificationSubpackets.Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets) {
|
||||||
|
hashedSubpackets.setRegularExpression(barBankRegex)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.certifiedCertificate
|
||||||
|
val mergedBarCa = PGPPublicKeyRing.join(fooAdminDelegatedBarCa, barEmployeeDelegatesBarCa)
|
||||||
|
|
||||||
|
// Bar CA signs Bar Employee
|
||||||
|
val barCaCertifiedEmployeeCert = PGPainless.certify()
|
||||||
|
.userIdOnCertificate("Bar Bank Employee <employee@barbank.com>", freshBarBankEmployeeCert)
|
||||||
|
.withKey(freshBarBankCaKey, SecretKeyRingProtector.unprotectedKeys())
|
||||||
|
.buildWithSubpackets(object : CertificationSubpackets.Callback {
|
||||||
|
override fun modifyHashedSubpackets(hashedSubpackets: CertificationSubpackets) {
|
||||||
|
hashedSubpackets.addNotationData(false, "affiliation@barbank.com", "employee")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.certifiedCertificate
|
||||||
|
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
println("Foo Employee")
|
||||||
|
println(PGPainless.asciiArmor(caCertifiedFooBankEmployeeCert))
|
||||||
|
println("Foo Admin")
|
||||||
|
println(PGPainless.asciiArmor(caCertifiedFooBankAdminCert))
|
||||||
|
println("Foo CA")
|
||||||
|
println(PGPainless.asciiArmor(mergedFooCa))
|
||||||
|
println("Bar CA")
|
||||||
|
println(PGPainless.asciiArmor(mergedBarCa))
|
||||||
|
println("Bar Employee")
|
||||||
|
println(PGPainless.asciiArmor(barCaCertifiedEmployeeCert))
|
||||||
|
// CHECKSTYLE:ON
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue