From d2b48e83d921c187eb9609ccce4474fd42bca6b8 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Wed, 11 May 2022 12:27:11 +0200 Subject: [PATCH] Implement certifying of certifications --- .../pgpainless/algorithm/Trustworthiness.java | 32 ++++- .../key/certification/CertifyCertificate.java | 111 ++++++++++++++++-- .../secretkeyring/SecretKeyRingEditor.java | 12 +- .../DirectKeySelfSignatureBuilder.java | 57 +++++++++ ... ThirdPartyDirectKeySignatureBuilder.java} | 6 +- .../algorithm/TrustworthinessTest.java | 74 ++++++++++++ .../certification/CertifyCertificateTest.java | 9 +- ...rdPartyDirectKeySignatureBuilderTest.java} | 7 +- 8 files changed, 277 insertions(+), 31 deletions(-) create mode 100644 pgpainless-core/src/main/java/org/pgpainless/signature/builder/DirectKeySelfSignatureBuilder.java rename pgpainless-core/src/main/java/org/pgpainless/signature/builder/{DirectKeySignatureBuilder.java => ThirdPartyDirectKeySignatureBuilder.java} (81%) create mode 100644 pgpainless-core/src/test/java/org/pgpainless/algorithm/TrustworthinessTest.java rename pgpainless-core/src/test/java/org/pgpainless/signature/builder/{DirectKeySignatureBuilderTest.java => ThirdPartyDirectKeySignatureBuilderTest.java} (94%) diff --git a/pgpainless-core/src/main/java/org/pgpainless/algorithm/Trustworthiness.java b/pgpainless-core/src/main/java/org/pgpainless/algorithm/Trustworthiness.java index 573bbf9d..0df31764 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/algorithm/Trustworthiness.java +++ b/pgpainless-core/src/main/java/org/pgpainless/algorithm/Trustworthiness.java @@ -10,8 +10,8 @@ public class Trustworthiness { private final int depth; public static final int THRESHOLD_FULLY_CONVINCED = 120; - public static final int THRESHOLD_MARGINALLY_CONVINCED = 60; - public static final int THRESHOLD_NOT_TRUSTED = 0; + public static final int MARGINALLY_CONVINCED = 60; + public static final int NOT_TRUSTED = 0; public Trustworthiness(int amount, int depth) { this.amount = capAmount(amount); @@ -26,6 +26,30 @@ public class Trustworthiness { return depth; } + public boolean isNotTrusted() { + return getAmount() == NOT_TRUSTED; + } + + public boolean isMarginallyTrusted() { + return getAmount() > NOT_TRUSTED; + } + + public boolean isFullyTrusted() { + return getAmount() >= THRESHOLD_FULLY_CONVINCED; + } + + public boolean isIntroducer() { + return getDepth() >= 1; + } + + public boolean canIntroduce(int otherDepth) { + return getDepth() > otherDepth; + } + + public boolean canIntroduce(Trustworthiness other) { + return canIntroduce(other.getDepth()); + } + /** * This means that we are fully convinced of the trustworthiness of the key. * @@ -41,7 +65,7 @@ public class Trustworthiness { * @return builder */ public static Builder marginallyTrusted() { - return new Builder(THRESHOLD_MARGINALLY_CONVINCED); + return new Builder(MARGINALLY_CONVINCED); } /** @@ -51,7 +75,7 @@ public class Trustworthiness { * @return builder */ public static Builder untrusted() { - return new Builder(THRESHOLD_NOT_TRUSTED); + return new Builder(NOT_TRUSTED); } public static final class Builder { diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/certification/CertifyCertificate.java b/pgpainless-core/src/main/java/org/pgpainless/key/certification/CertifyCertificate.java index 77dab4e8..8503f8bd 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/certification/CertifyCertificate.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/certification/CertifyCertificate.java @@ -19,7 +19,7 @@ import org.pgpainless.key.OpenPgpFingerprint; import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.util.KeyRingUtils; -import org.pgpainless.signature.builder.DirectKeySignatureBuilder; +import org.pgpainless.signature.builder.ThirdPartyDirectKeySignatureBuilder; import org.pgpainless.signature.builder.ThirdPartyCertificationSignatureBuilder; import org.pgpainless.signature.subpackets.CertificationSubpackets; import org.pgpainless.util.DateUtil; @@ -28,20 +28,60 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Date; +/** + * API for creating certifications and delegations (Signatures) on keys. + * This API can be used to sign another persons OpenPGP key. + * + * A certification over a user-id is thereby used to attest, that the user believes that the user-id really belongs + * to the owner of the certificate. + * A delegation over a key can be used to delegate trust by marking the certificate as a trusted introducer. + */ public class CertifyCertificate { + /** + * Create a certification over a User-Id. + * By default, this method will use {@link CertificationType#GENERIC} to create the signature. + * If you need to create another type of certification, use + * {@link #userIdOnCertificate(String, PGPPublicKeyRing, CertificationType)} instead. + * + * @param userId user-id to certify + * @param certificate certificate + * @return API + */ CertificationOnUserId userIdOnCertificate(@Nonnull String userId, @Nonnull PGPPublicKeyRing certificate) { return new CertificationOnUserId(userId, certificate, CertificationType.GENERIC); } + /** + * Create a certification of the given {@link CertificationType} over a User-Id. + * + * @param userid user-id to certify + * @param certificate certificate + * @param certificationType type of signature + * @return API + */ CertificationOnUserId userIdOnCertificate(@Nonnull String userid, @Nonnull PGPPublicKeyRing certificate, @Nonnull CertificationType certificationType) { return new CertificationOnUserId(userid, certificate, certificationType); } + /** + * Create a delegation (direct key signature) over a certificate. + * + * @param certificate certificate + * @return API + */ DelegationOnCertificate certificate(@Nonnull PGPPublicKeyRing certificate) { return certificate(certificate, null); } + /** + * Create a delegation (direct key signature) containing a {@link org.bouncycastle.bcpg.sig.TrustSignature} packet + * over a certificate. + * + * @param certificate certificate + * @param trustworthiness trustworthiness of the certificate + * @return API + */ DelegationOnCertificate certificate(@Nonnull PGPPublicKeyRing certificate, @Nullable Trustworthiness trustworthiness) { return new DelegationOnCertificate(certificate, trustworthiness); } @@ -58,8 +98,16 @@ public class CertifyCertificate { this.certificationType = certificationType; } + /** + * Create the certification using the given key. + * + * @param certificationKey key used to create the certification + * @param protector protector to unlock the certification key + * @return API + * @throws PGPException in case of an OpenPGP related error + */ CertificationOnUserIdWithSubpackets withKey(@Nonnull PGPSecretKeyRing certificationKey, @Nonnull SecretKeyRingProtector protector) throws PGPException { - PGPSecretKey secretKey = getCertificationSecretKey(certificationKey); + PGPSecretKey secretKey = getCertifyingSecretKey(certificationKey); ThirdPartyCertificationSignatureBuilder sigBuilder = new ThirdPartyCertificationSignatureBuilder( certificationType.asSignatureType(), secretKey, protector); @@ -80,11 +128,24 @@ public class CertifyCertificate { this.sigBuilder = sigBuilder; } - public CertificationResult withSubpackets(@Nonnull CertificationSubpackets.Callback subpacketCallback) throws PGPException { + /** + * Apply the given signature subpackets and build the certification. + * + * @param subpacketCallback callback to modify the signatures subpackets + * @return result + * @throws PGPException in case of an OpenPGP related error + */ + public CertificationResult buildWithSubpackets(@Nonnull CertificationSubpackets.Callback subpacketCallback) throws PGPException { sigBuilder.applyCallback(subpacketCallback); return build(); } + /** + * Build the certification signature. + * + * @return result + * @throws PGPException in case of an OpenPGP related error + */ public CertificationResult build() throws PGPException { PGPSignature signature = sigBuilder.build(certificate, userId); PGPPublicKeyRing certifiedCertificate = KeyRingUtils.injectCertification(certificate, userId, signature); @@ -102,10 +163,18 @@ public class CertifyCertificate { this.trustworthiness = trustworthiness; } + /** + * Build the delegation using the given certification key. + * + * @param certificationKey key to create the certification with + * @param protector protector to unlock the certification key + * @return API + * @throws PGPException in case of an OpenPGP related error + */ public DelegationOnCertificateWithSubpackets withKey(@Nonnull PGPSecretKeyRing certificationKey, @Nonnull SecretKeyRingProtector protector) throws PGPException { - PGPSecretKey secretKey = getCertificationSecretKey(certificationKey); + PGPSecretKey secretKey = getCertifyingSecretKey(certificationKey); - DirectKeySignatureBuilder sigBuilder = new DirectKeySignatureBuilder(secretKey, protector); + ThirdPartyDirectKeySignatureBuilder sigBuilder = new ThirdPartyDirectKeySignatureBuilder(secretKey, protector); if (trustworthiness != null) { sigBuilder.getHashedSubpackets().setTrust(true, trustworthiness.getDepth(), trustworthiness.getAmount()); } @@ -116,18 +185,31 @@ public class CertifyCertificate { public static class DelegationOnCertificateWithSubpackets { private final PGPPublicKeyRing certificate; - private final DirectKeySignatureBuilder sigBuilder; + private final ThirdPartyDirectKeySignatureBuilder sigBuilder; - public DelegationOnCertificateWithSubpackets(@Nonnull PGPPublicKeyRing certificate, @Nonnull DirectKeySignatureBuilder sigBuilder) { + DelegationOnCertificateWithSubpackets(@Nonnull PGPPublicKeyRing certificate, @Nonnull ThirdPartyDirectKeySignatureBuilder sigBuilder) { this.certificate = certificate; this.sigBuilder = sigBuilder; } - public CertificationResult withSubpackets(@Nonnull CertificationSubpackets.Callback subpacketsCallback) throws PGPException { + /** + * Apply the given signature subpackets and build the delegation signature. + * + * @param subpacketsCallback callback to modify the signatures subpackets + * @return result + * @throws PGPException in case of an OpenPGP related error + */ + public CertificationResult buildWithSubpackets(@Nonnull CertificationSubpackets.Callback subpacketsCallback) throws PGPException { sigBuilder.applyCallback(subpacketsCallback); return build(); } + /** + * Build the delegation signature. + * + * @return result + * @throws PGPException in case of an OpenPGP related error + */ public CertificationResult build() throws PGPException { PGPPublicKey delegatedKey = certificate.getPublicKey(); PGPSignature delegation = sigBuilder.build(delegatedKey); @@ -146,18 +228,28 @@ public class CertifyCertificate { this.certification = certification; } + /** + * Return the signature. + * + * @return signature + */ @Nonnull public PGPSignature getCertification() { return certification; } + /** + * Return the certificate, which now contains the signature. + * + * @return certificate + signature + */ @Nonnull public PGPPublicKeyRing getCertifiedCertificate() { return certificate; } } - private static PGPSecretKey getCertificationSecretKey(PGPSecretKeyRing certificationKey) { + private static PGPSecretKey getCertifyingSecretKey(PGPSecretKeyRing certificationKey) { Date now = DateUtil.now(); KeyRingInfo info = PGPainless.inspectKeyRing(certificationKey, now); @@ -179,5 +271,4 @@ public class CertifyCertificate { } return secretKey; } - } diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java index 19d7ffcc..7418401f 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java @@ -56,10 +56,9 @@ import org.pgpainless.key.protection.fixes.S2KUsageFix; import org.pgpainless.key.protection.passphrase_provider.SolitaryPassphraseProvider; import org.pgpainless.key.util.KeyRingUtils; import org.pgpainless.key.util.RevocationAttributes; -import org.pgpainless.signature.builder.DirectKeySignatureBuilder; +import org.pgpainless.signature.builder.DirectKeySelfSignatureBuilder; import org.pgpainless.signature.builder.RevocationSignatureBuilder; import org.pgpainless.signature.builder.SelfSignatureBuilder; -import org.pgpainless.signature.subpackets.CertificationSubpackets; import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets; import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; import org.pgpainless.signature.subpackets.SignatureSubpackets; @@ -613,12 +612,10 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { PGPPublicKey publicKey = primaryKey.getPublicKey(); final Date keyCreationTime = publicKey.getCreationTime(); - DirectKeySignatureBuilder builder = new DirectKeySignatureBuilder(primaryKey, secretKeyRingProtector, prevDirectKeySig); - System.out.println("FIXME"); // will cause checkstyle warning so I remember - /* - builder.applyCallback(new CertificationSubpackets.Callback() { + DirectKeySelfSignatureBuilder builder = new DirectKeySelfSignatureBuilder(primaryKey, secretKeyRingProtector, prevDirectKeySig); + builder.applyCallback(new SelfSignatureSubpackets.Callback() { @Override - public void modifyHashedSubpackets(CertificationSubpackets hashedSubpackets) { + public void modifyHashedSubpackets(SelfSignatureSubpackets hashedSubpackets) { if (expiration != null) { hashedSubpackets.setKeyExpirationTime(keyCreationTime, expiration); } else { @@ -626,7 +623,6 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { } } }); - */ return builder.build(publicKey); } diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/builder/DirectKeySelfSignatureBuilder.java b/pgpainless-core/src/main/java/org/pgpainless/signature/builder/DirectKeySelfSignatureBuilder.java new file mode 100644 index 00000000..cf99f8d6 --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/signature/builder/DirectKeySelfSignatureBuilder.java @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2021 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.signature.builder; + +import javax.annotation.Nullable; + +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureGenerator; +import org.pgpainless.algorithm.SignatureType; +import org.pgpainless.key.protection.SecretKeyRingProtector; +import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; + +public class DirectKeySelfSignatureBuilder extends AbstractSignatureBuilder { + + public DirectKeySelfSignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature) + throws PGPException { + super(certificationKey, protector, archetypeSignature); + } + + public DirectKeySelfSignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) throws PGPException { + super(SignatureType.DIRECT_KEY, signingKey, protector); + } + + public SelfSignatureSubpackets getHashedSubpackets() { + return hashedSubpackets; + } + + public SelfSignatureSubpackets getUnhashedSubpackets() { + return unhashedSubpackets; + } + + public void applyCallback(@Nullable SelfSignatureSubpackets.Callback callback) { + if (callback != null) { + callback.modifyHashedSubpackets(getHashedSubpackets()); + callback.modifyUnhashedSubpackets(getUnhashedSubpackets()); + } + } + + public PGPSignature build(PGPPublicKey key) throws PGPException { + PGPSignatureGenerator signatureGenerator = buildAndInitSignatureGenerator(); + if (key.getKeyID() != publicSigningKey.getKeyID()) { + return signatureGenerator.generateCertification(publicSigningKey, key); + } else { + return signatureGenerator.generateCertification(key); + } + } + + @Override + protected boolean isValidSignatureType(SignatureType type) { + return type == SignatureType.DIRECT_KEY; + } +} diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/builder/DirectKeySignatureBuilder.java b/pgpainless-core/src/main/java/org/pgpainless/signature/builder/ThirdPartyDirectKeySignatureBuilder.java similarity index 81% rename from pgpainless-core/src/main/java/org/pgpainless/signature/builder/DirectKeySignatureBuilder.java rename to pgpainless-core/src/main/java/org/pgpainless/signature/builder/ThirdPartyDirectKeySignatureBuilder.java index 0e5498bd..dd720bce 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/signature/builder/DirectKeySignatureBuilder.java +++ b/pgpainless-core/src/main/java/org/pgpainless/signature/builder/ThirdPartyDirectKeySignatureBuilder.java @@ -15,14 +15,14 @@ import org.pgpainless.algorithm.SignatureType; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.signature.subpackets.CertificationSubpackets; -public class DirectKeySignatureBuilder extends AbstractSignatureBuilder { +public class ThirdPartyDirectKeySignatureBuilder extends AbstractSignatureBuilder { - public DirectKeySignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature) + public ThirdPartyDirectKeySignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature) throws PGPException { super(certificationKey, protector, archetypeSignature); } - public DirectKeySignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) throws PGPException { + public ThirdPartyDirectKeySignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) throws PGPException { super(SignatureType.DIRECT_KEY, signingKey, protector); } diff --git a/pgpainless-core/src/test/java/org/pgpainless/algorithm/TrustworthinessTest.java b/pgpainless-core/src/test/java/org/pgpainless/algorithm/TrustworthinessTest.java new file mode 100644 index 00000000..017126aa --- /dev/null +++ b/pgpainless-core/src/test/java/org/pgpainless/algorithm/TrustworthinessTest.java @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.algorithm; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class TrustworthinessTest { + + @Test + public void fullyTrustedIntroducer() { + Trustworthiness it = Trustworthiness.fullyTrusted().introducer(); + assertTrue(it.isFullyTrusted()); + assertFalse(it.isNotTrusted()); + + assertTrue(it.isIntroducer()); + assertFalse(it.canIntroduce(it)); + } + + @Test + public void marginallyTrustedIntroducer() { + Trustworthiness it = Trustworthiness.marginallyTrusted().introducer(); + assertFalse(it.isFullyTrusted()); + assertTrue(it.isMarginallyTrusted()); + assertFalse(it.isNotTrusted()); + + assertTrue(it.isIntroducer()); + assertFalse(it.canIntroduce(2)); + } + + @Test + public void nonTrustedIntroducer() { + Trustworthiness it = Trustworthiness.untrusted().introducer(); + assertTrue(it.isNotTrusted()); + assertFalse(it.isMarginallyTrusted()); + assertFalse(it.isFullyTrusted()); + + assertTrue(it.isIntroducer()); + } + + @Test + public void trustedMetaIntroducer() { + Trustworthiness it = Trustworthiness.fullyTrusted().metaIntroducer(); + assertTrue(it.isFullyTrusted()); + assertTrue(it.isIntroducer()); + + Trustworthiness that = Trustworthiness.fullyTrusted().introducer(); + assertTrue(it.canIntroduce(that)); + assertFalse(that.canIntroduce(it)); + } + + @Test + public void invalidArguments() { + assertThrows(IllegalArgumentException.class, () -> new Trustworthiness(300, 1)); + assertThrows(IllegalArgumentException.class, () -> new Trustworthiness(60, 300)); + assertThrows(IllegalArgumentException.class, () -> new Trustworthiness(-4, 1)); + assertThrows(IllegalArgumentException.class, () -> new Trustworthiness(120, -1)); + } + + @Test + public void inBetweenValues() { + Trustworthiness it = new Trustworthiness(30, 1); + assertTrue(it.isMarginallyTrusted()); + assertFalse(it.isFullyTrusted()); + + it = new Trustworthiness(140, 1); + assertTrue(it.isFullyTrusted()); + } +} diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/certification/CertifyCertificateTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/certification/CertifyCertificateTest.java index c6028925..4a72276c 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/certification/CertifyCertificateTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/certification/CertifyCertificateTest.java @@ -14,6 +14,7 @@ import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.util.List; +import org.bouncycastle.bcpg.sig.TrustSignature; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; @@ -84,13 +85,19 @@ public class CertifyCertificateTest { assertNotNull(signature); assertEquals(SignatureType.DIRECT_KEY, SignatureType.valueOf(signature.getSignatureType())); assertEquals(alice.getPublicKey().getKeyID(), signature.getKeyID()); + TrustSignature trustSignaturePacket = signature.getHashedSubPackets().getTrust(); + assertNotNull(trustSignaturePacket); + Trustworthiness trustworthiness = new Trustworthiness(trustSignaturePacket.getTrustAmount(), trustSignaturePacket.getDepth()); + assertTrue(trustworthiness.isFullyTrusted()); + assertTrue(trustworthiness.isIntroducer()); + assertFalse(trustworthiness.canIntroduce(1)); assertTrue(SignatureVerifier.verifyDirectKeySignature( signature, alice.getPublicKey(), bob.getPublicKey(), PGPainless.getPolicy(), DateUtil.now())); PGPPublicKeyRing bobCertified = result.getCertifiedCertificate(); PGPPublicKey bobCertifiedKey = bobCertified.getPublicKey(); - + List sigsByAlice = CollectionUtils.iteratorToList( bobCertifiedKey.getSignaturesForKeyID(alice.getPublicKey().getKeyID())); assertEquals(1, sigsByAlice.size()); diff --git a/pgpainless-core/src/test/java/org/pgpainless/signature/builder/DirectKeySignatureBuilderTest.java b/pgpainless-core/src/test/java/org/pgpainless/signature/builder/ThirdPartyDirectKeySignatureBuilderTest.java similarity index 94% rename from pgpainless-core/src/test/java/org/pgpainless/signature/builder/DirectKeySignatureBuilderTest.java rename to pgpainless-core/src/test/java/org/pgpainless/signature/builder/ThirdPartyDirectKeySignatureBuilderTest.java index 6c1c0cf4..46dc1ac5 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/signature/builder/DirectKeySignatureBuilderTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/signature/builder/ThirdPartyDirectKeySignatureBuilderTest.java @@ -29,19 +29,17 @@ import org.pgpainless.key.util.KeyRingUtils; import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil; -public class DirectKeySignatureBuilderTest { +public class ThirdPartyDirectKeySignatureBuilderTest { @Test public void testDirectKeySignatureBuilding() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, InterruptedException { PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() .modernKeyRing("Alice"); - DirectKeySignatureBuilder dsb = new DirectKeySignatureBuilder( + DirectKeySelfSignatureBuilder dsb = new DirectKeySelfSignatureBuilder( secretKeys.getSecretKey(), SecretKeyRingProtector.unprotectedKeys()); - System.out.println("FIXME"); // will cause checkstyle warning, so I remember - /* dsb.applyCallback(new SelfSignatureSubpackets.Callback() { @Override public void modifyHashedSubpackets(SelfSignatureSubpackets hashedSubpackets) { @@ -52,7 +50,6 @@ public class DirectKeySignatureBuilderTest { hashedSubpackets.setFeatures(Feature.MODIFICATION_DETECTION); } }); - */ Thread.sleep(1000);