diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/builder/SignatureBuilder.java b/pgpainless-core/src/main/java/org/pgpainless/signature/builder/SignatureBuilder.java index e211e098..f64c0302 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/signature/builder/SignatureBuilder.java +++ b/pgpainless-core/src/main/java/org/pgpainless/signature/builder/SignatureBuilder.java @@ -12,13 +12,15 @@ import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSignature; import org.pgpainless.algorithm.KeyFlag; +import org.pgpainless.exception.WrongPassphraseException; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.signature.subpackets.BindingSignatureCallback; +import org.pgpainless.signature.subpackets.SelfSignatureCallback; import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; public class SignatureBuilder { - public SubkeyBindingSignatureBuilder subkeyBindingSignatureBuilder( + public SubkeyBindingSignatureBuilder bindSubkey( PGPSecretKey primaryKey, SecretKeyRingProtector primaryKeyProtector, PGPSecretKey subkey, @@ -30,45 +32,97 @@ public class SignatureBuilder { if (flags.length == 0) { throw new IllegalArgumentException("Keyflags for subkey binding cannot be empty."); } - SubkeyBindingSignatureBuilder subkeyBindingBuilder = new SubkeyBindingSignatureBuilder(primaryKey, primaryKeyProtector); + SubkeyBindingSignatureBuilder subkeyBinder = new SubkeyBindingSignatureBuilder(primaryKey, primaryKeyProtector); - SelfSignatureSubpackets hashedSubpackets = subkeyBindingBuilder.getHashedSubpackets(); + SelfSignatureSubpackets hashedSubpackets = subkeyBinder.getHashedSubpackets(); + SelfSignatureSubpackets unhashedSubpackets = subkeyBinder.getUnhashedSubpackets(); hashedSubpackets.setKeyFlags(flags); - boolean isSigningKey = false; - for (KeyFlag flag : flags) { - if (flag == KeyFlag.SIGN_DATA) { - isSigningKey = true; - break; - } - } - if (isSigningKey) { - PGPSignature backsig = primaryKeyBindingSignature( - subkey, subkeyProtector, primaryKey.getPublicKey(), primaryKeyBindingSubpacketsCallback); + if (hasSignDataFlag(flags)) { + PGPSignature backsig = createPrimaryKeyBinding( + subkey, subkeyProtector, primaryKeyBindingSubpacketsCallback, primaryKey.getPublicKey()); hashedSubpackets.addEmbeddedSignature(backsig); } if (subkeyBindingSubpacketsCallback != null) { - subkeyBindingSubpacketsCallback.modifyHashedSubpackets(subkeyBindingBuilder.getHashedSubpackets()); - subkeyBindingSubpacketsCallback.modifyUnhashedSubpackets(subkeyBindingBuilder.getUnhashedSubpackets()); + subkeyBindingSubpacketsCallback.modifyHashedSubpackets(hashedSubpackets); + subkeyBindingSubpacketsCallback.modifyUnhashedSubpackets(unhashedSubpackets); } - return subkeyBindingBuilder; + return subkeyBinder; } - public PGPSignature primaryKeyBindingSignature( + public PrimaryKeyBindingSignatureBuilder bindPrimaryKey( PGPSecretKey subkey, SecretKeyRingProtector subkeyProtector, - PGPPublicKey primaryKey, - BindingSignatureCallback primaryKeyBindingSubpacketsCallback) throws PGPException { + @Nullable BindingSignatureCallback primaryKeyBindingSubpacketsCallback) throws WrongPassphraseException { + PrimaryKeyBindingSignatureBuilder primaryKeyBinder = new PrimaryKeyBindingSignatureBuilder(subkey, subkeyProtector); - PrimaryKeyBindingSignatureBuilder builder = new PrimaryKeyBindingSignatureBuilder(subkey, subkeyProtector); if (primaryKeyBindingSubpacketsCallback != null) { - primaryKeyBindingSubpacketsCallback.modifyHashedSubpackets(builder.getHashedSubpackets()); - primaryKeyBindingSubpacketsCallback.modifyUnhashedSubpackets(builder.getUnhashedSubpackets()); + primaryKeyBindingSubpacketsCallback.modifyHashedSubpackets(primaryKeyBinder.getHashedSubpackets()); + primaryKeyBindingSubpacketsCallback.modifyUnhashedSubpackets(primaryKeyBinder.getUnhashedSubpackets()); } - return builder.build(primaryKey); + return primaryKeyBinder; } + public PGPSignature createPrimaryKeyBinding( + PGPSecretKey subkey, + SecretKeyRingProtector subkeyProtector, + @Nullable BindingSignatureCallback primaryKeyBindingSubpacketsCallback, + PGPPublicKey primaryKey) + throws PGPException { + return bindPrimaryKey(subkey, subkeyProtector, primaryKeyBindingSubpacketsCallback) + .build(primaryKey); + } + + public CertificationSignatureBuilder selfCertifyUserId( + PGPSecretKey primaryKey, + SecretKeyRingProtector primaryKeyProtector, + @Nullable SelfSignatureCallback selfSignatureCallback, + KeyFlag... flags) throws WrongPassphraseException { + + CertificationSignatureBuilder certifier = new CertificationSignatureBuilder(primaryKey, primaryKeyProtector); + certifier.getHashedSubpackets().setKeyFlags(flags); + if (selfSignatureCallback != null) { + selfSignatureCallback.modifyHashedSubpackets(certifier.getHashedSubpackets()); + selfSignatureCallback.modifyUnhashedSubpackets(certifier.getUnhashedSubpackets()); + } + return certifier; + } + + public CertificationSignatureBuilder renewSelfCertification( + PGPSecretKey primaryKey, + SecretKeyRingProtector primaryKeyProtector, + @Nullable SelfSignatureCallback selfSignatureCallback, + PGPSignature oldCertification) throws WrongPassphraseException { + CertificationSignatureBuilder certifier = + new CertificationSignatureBuilder(primaryKey, primaryKeyProtector, oldCertification); + + // TODO + return null; + } + + public PGPSignature createUserIdSelfCertification( + String userId, + PGPSecretKey primaryKey, + SecretKeyRingProtector primaryKeyProtector, + @Nullable SelfSignatureCallback selfSignatureCallback, + KeyFlag... flags) + throws PGPException { + return selfCertifyUserId(primaryKey, primaryKeyProtector, selfSignatureCallback, flags) + .build(primaryKey.getPublicKey(), userId); + } + + private static boolean hasSignDataFlag(KeyFlag... flags) { + if (flags == null) { + return false; + } + for (KeyFlag flag : flags) { + if (flag == KeyFlag.SIGN_DATA) { + return true; + } + } + return false; + } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureSubpacketCallback.java b/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureCallback.java similarity index 85% rename from pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureSubpacketCallback.java rename to pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureCallback.java index a0d5f4c3..fda37510 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureSubpacketCallback.java +++ b/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureCallback.java @@ -4,7 +4,7 @@ package org.pgpainless.signature.subpackets; -public interface SelfSignatureSubpacketCallback { +public interface SelfSignatureCallback { void modifyHashedSubpackets(SelfSignatureSubpackets subpackets); diff --git a/pgpainless-core/src/test/java/org/pgpainless/signature/builder/SubkeyBindingSignatureBuilderTest.java b/pgpainless-core/src/test/java/org/pgpainless/signature/builder/SubkeyBindingSignatureBuilderTest.java index b2c06cfb..79f2471e 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/signature/builder/SubkeyBindingSignatureBuilderTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/signature/builder/SubkeyBindingSignatureBuilderTest.java @@ -31,13 +31,13 @@ public class SubkeyBindingSignatureBuilderTest { PGPSecretKeyRing secretKey = PGPainless.generateKeyRing() .modernKeyRing("Alice ", "passphrase"); KeyRingInfo info = PGPainless.inspectKeyRing(secretKey); - List previousSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.STORAGE_AND_COMMUNICATIONS); + List previousSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.ANY); SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("passphrase"), secretKey); PGPSecretKeyRing tempSubkeyRing = PGPainless.generateKeyRing() .modernKeyRing("Subkeys", null); PGPPublicKey subkey = PGPainless.inspectKeyRing(tempSubkeyRing) - .getEncryptionSubkeys(EncryptionPurpose.STORAGE_AND_COMMUNICATIONS).get(0); + .getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); SubkeyBindingSignatureBuilder skbb = new SubkeyBindingSignatureBuilder(secretKey.getSecretKey(), protector); skbb.getHashedSubpackets().addNotationData(false, "testnotation@pgpainless.org", "hello-world"); @@ -49,7 +49,7 @@ public class SubkeyBindingSignatureBuilderTest { secretKey = PGPSecretKeyRing.insertSecretKey(secretKey, secSubkey); info = PGPainless.inspectKeyRing(secretKey); - List nextSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.STORAGE_AND_COMMUNICATIONS); + List nextSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.ANY); assertEquals(previousSubkeys.size() + 1, nextSubkeys.size()); } }