diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/util/KeyRingUtils.java b/pgpainless-core/src/main/java/org/pgpainless/key/util/KeyRingUtils.java index 7b75e084..c7872589 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/util/KeyRingUtils.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/util/KeyRingUtils.java @@ -21,7 +21,6 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; - import javax.annotation.Nonnull; import org.bouncycastle.openpgp.PGPException; @@ -35,10 +34,6 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.UnlockSecretKey; -import org.pgpainless.util.selection.key.PublicKeySelectionStrategy; -import org.pgpainless.util.selection.key.impl.And; -import org.pgpainless.util.selection.key.impl.KeyBelongsToKeyRing; -import org.pgpainless.util.selection.key.impl.NoRevocation; public class KeyRingUtils { @@ -162,37 +157,6 @@ public class KeyRingUtils { return new PGPSecretKeyRingCollection(Arrays.asList(rings)); } - /** - * Remove all keys from the key ring, are either not having a subkey signature from the master key - * (identified by {@code masterKeyId}), or are revoked ("normal" key revocation, as well as subkey revocation). - * - * @param ring key ring - * @param masterKey master key - * @return "cleaned" key ring - */ - public static PGPSecretKeyRing removeUnassociatedKeysFromKeyRing(@Nonnull PGPSecretKeyRing ring, - @Nonnull PGPPublicKey masterKey) { - if (!masterKey.isMasterKey()) { - throw new IllegalArgumentException("Given key is not a master key."); - } - // Only select keys which are signed by the master key and not revoked. - PublicKeySelectionStrategy selector = new And.PubKeySelectionStrategy( - new KeyBelongsToKeyRing.PubkeySelectionStrategy(masterKey), - new NoRevocation.PubKeySelectionStrategy()); - - PGPSecretKeyRing cleaned = ring; - - Iterator secretKeys = ring.getSecretKeys(); - while (secretKeys.hasNext()) { - PGPSecretKey secretKey = secretKeys.next(); - if (!selector.accept(secretKey.getPublicKey())) { - cleaned = PGPSecretKeyRing.removeSecretKey(cleaned, secretKey); - } - } - - return cleaned; - } - public static boolean keyRingContainsKeyWithId(@Nonnull PGPPublicKeyRing ring, long keyId) { return ring.getPublicKey(keyId) != null; diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/And.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/And.java deleted file mode 100644 index f2f7194e..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/And.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key.impl; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import javax.annotation.Nonnull; - -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.pgpainless.util.selection.key.PublicKeySelectionStrategy; -import org.pgpainless.util.selection.key.SecretKeySelectionStrategy; - -public class And { - - public static class PubKeySelectionStrategy extends PublicKeySelectionStrategy { - - private final Set strategies = new HashSet<>(); - - public PubKeySelectionStrategy(@Nonnull PublicKeySelectionStrategy... strategies) { - this.strategies.addAll(Arrays.asList(strategies)); - } - - @Override - public boolean accept(PGPPublicKey key) { - boolean accept = true; - for (PublicKeySelectionStrategy strategy : strategies) { - accept &= strategy.accept(key); - } - return accept; - } - } - - public static class SecKeySelectionStrategy extends SecretKeySelectionStrategy { - - private final Set strategies = new HashSet<>(); - - public SecKeySelectionStrategy(@Nonnull SecretKeySelectionStrategy... strategies) { - this.strategies.addAll(Arrays.asList(strategies)); - } - - @Override - public boolean accept(PGPSecretKey key) { - boolean accept = true; - for (SecretKeySelectionStrategy strategy : strategies) { - accept &= strategy.accept(key); - } - return accept; - } - } - -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/EncryptionKeySelectionStrategy.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/EncryptionKeySelectionStrategy.java deleted file mode 100644 index 71c5e26e..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/EncryptionKeySelectionStrategy.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key.impl; - -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.annotation.Nonnull; - -import org.bouncycastle.openpgp.PGPPublicKey; -import org.pgpainless.algorithm.KeyFlag; -import org.pgpainless.algorithm.PublicKeyAlgorithm; -import org.pgpainless.util.selection.key.PublicKeySelectionStrategy; - -/** - * Key Selection Strategy that only accepts {@link PGPPublicKey}s which are capable of encryption. - */ -public class EncryptionKeySelectionStrategy extends PublicKeySelectionStrategy { - - public static final Logger LOGGER = Logger.getLogger(EncryptionKeySelectionStrategy.class.getName()); - - private final HasAnyKeyFlagSelectionStrategy.PublicKey keyFlagSelector; - - public EncryptionKeySelectionStrategy(KeyFlag... flags) { - this.keyFlagSelector = new HasAnyKeyFlagSelectionStrategy.PublicKey(flags); - } - - @Override - public boolean accept(@Nonnull PGPPublicKey key) { - if (!key.isEncryptionKey()) { - LOGGER.log(Level.FINE, "Rejecting key " + Long.toHexString(key.getKeyID()) + " as its algorithm (" + - PublicKeyAlgorithm.fromId(key.getAlgorithm()) + ") is not suitable of encryption."); - return false; - } - if (!keyFlagSelector.accept(key)) { - LOGGER.log(Level.FINE, "Rejecting key " + Long.toHexString(key.getKeyID()) + " as it does not the appropriate encryption key flags."); - return false; - } - - return true; - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/HasAllKeyFlagSelectionStrategy.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/HasAllKeyFlagSelectionStrategy.java deleted file mode 100644 index 791687ec..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/HasAllKeyFlagSelectionStrategy.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2021 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key.impl; - -import java.util.Iterator; - -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.bouncycastle.openpgp.PGPSignature; -import org.pgpainless.algorithm.KeyFlag; -import org.pgpainless.util.selection.key.PublicKeySelectionStrategy; -import org.pgpainless.util.selection.key.SecretKeySelectionStrategy; - -/** - * Selection Strategy that accepts a key if it carries all of the specified key flags. - */ -public class HasAllKeyFlagSelectionStrategy { - - public static class PublicKey extends PublicKeySelectionStrategy { - - private final int keyFlagMask; - - public PublicKey(KeyFlag... flags) { - this(KeyFlag.toBitmask(flags)); - } - - public PublicKey(int mask) { - this.keyFlagMask = mask; - } - - @Override - public boolean accept(PGPPublicKey key) { - Iterator signatures = key.getSignatures(); - int flags = signatures.next().getHashedSubPackets().getKeyFlags(); - return (keyFlagMask & flags) == keyFlagMask; - } - } - - public static class SecretKey extends SecretKeySelectionStrategy { - - private final int keyFlagMask; - - public SecretKey(KeyFlag... flags) { - this(KeyFlag.toBitmask(flags)); - } - - public SecretKey(int mask) { - this.keyFlagMask = mask; - } - - @Override - public boolean accept(PGPSecretKey key) { - Iterator signatures = key.getPublicKey().getSignatures(); - int flags = signatures.next().getHashedSubPackets().getKeyFlags(); - return (keyFlagMask & flags) == keyFlagMask; - } - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/HasAnyKeyFlagSelectionStrategy.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/HasAnyKeyFlagSelectionStrategy.java deleted file mode 100644 index 70b7267c..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/HasAnyKeyFlagSelectionStrategy.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2021 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key.impl; - -import java.util.Iterator; - -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.bouncycastle.openpgp.PGPSignature; -import org.pgpainless.algorithm.KeyFlag; -import org.pgpainless.util.selection.key.PublicKeySelectionStrategy; -import org.pgpainless.util.selection.key.SecretKeySelectionStrategy; - -/** - * Selection Strategies that accept a key if it carries at least one of the given key flags. - */ -public class HasAnyKeyFlagSelectionStrategy { - - public static class PublicKey extends PublicKeySelectionStrategy { - - private final int keyFlagMask; - - public PublicKey(KeyFlag... flags) { - this(KeyFlag.toBitmask(flags)); - } - - public PublicKey(int mask) { - this.keyFlagMask = mask; - } - - @Override - public boolean accept(PGPPublicKey key) { - Iterator signatures = key.getSignatures(); - int flags = 0; - while (signatures.hasNext()) { - flags = signatures.next().getHashedSubPackets().getKeyFlags(); - } - return (keyFlagMask & flags) != 0; - } - } - - public static class SecretKey extends SecretKeySelectionStrategy { - - private final int keyFlagMask; - - public SecretKey(KeyFlag... flags) { - this(KeyFlag.toBitmask(flags)); - } - - public SecretKey(int mask) { - this.keyFlagMask = mask; - } - - @Override - public boolean accept(PGPSecretKey key) { - Iterator signatures = key.getPublicKey().getSignatures(); - int flags = signatures.next().getHashedSubPackets().getKeyFlags(); - return (keyFlagMask & flags) != 0; - } - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/KeyBelongsToKeyRing.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/KeyBelongsToKeyRing.java deleted file mode 100644 index 5e2b4af2..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/KeyBelongsToKeyRing.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key.impl; - -import javax.annotation.Nonnull; -import java.util.Arrays; -import java.util.Iterator; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSignature; -import org.pgpainless.implementation.ImplementationFactory; -import org.pgpainless.util.selection.key.PublicKeySelectionStrategy; - -public class KeyBelongsToKeyRing { - - private static final Logger LOGGER = Logger.getLogger(KeyBelongsToKeyRing.class.getName()); - - public static class PubkeySelectionStrategy extends PublicKeySelectionStrategy { - - private final PGPPublicKey masterKey; - - public PubkeySelectionStrategy(PGPPublicKey masterKey) { - this.masterKey = masterKey; - } - - @Override - public boolean accept(@Nonnull PGPPublicKey key) { - // Same key -> accept - if (Arrays.equals(masterKey.getFingerprint(), key.getFingerprint())) { - return true; - } - - Iterator signatures = key.getSignaturesForKeyID(masterKey.getKeyID()); - while (signatures.hasNext()) { - PGPSignature signature = signatures.next(); - if (signature.getSignatureType() == PGPSignature.SUBKEY_BINDING) { - try { - signature.init(ImplementationFactory.getInstance().getPGPContentVerifierBuilderProvider(), masterKey); - return signature.verifyCertification(masterKey, key); - } catch (PGPException e) { - LOGGER.log(Level.WARNING, "Could not verify subkey signature of key " + - Long.toHexString(masterKey.getKeyID()) + " on key " + Long.toHexString(key.getKeyID())); - - return false; - } - } - } - return false; - } - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/NoRevocation.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/NoRevocation.java deleted file mode 100644 index c5c7899f..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/NoRevocation.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key.impl; - -import javax.annotation.Nonnull; - -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.pgpainless.util.selection.key.PublicKeySelectionStrategy; -import org.pgpainless.util.selection.key.SecretKeySelectionStrategy; - -/** - * Key Selection Strategies that do accept only keys, which have no revocation. - */ -public class NoRevocation { - - /** - * Key Selection Strategy which only accepts {@link PGPPublicKey}s which have no revocation. - */ - public static class PubKeySelectionStrategy extends PublicKeySelectionStrategy { - - @Override - public boolean accept(@Nonnull PGPPublicKey key) { - return !key.hasRevocation(); - } - } - - /** - * Key Selection Strategy which only accepts {@link PGPSecretKey}s which have no revocation. - */ - public static class SecKeySelectionStrategy extends SecretKeySelectionStrategy { - - @Override - public boolean accept(@Nonnull PGPSecretKey key) { - return !key.getPublicKey().hasRevocation(); - } - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/Or.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/Or.java deleted file mode 100644 index 880df4f1..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/Or.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key.impl; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import javax.annotation.Nonnull; - -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.pgpainless.util.selection.key.PublicKeySelectionStrategy; -import org.pgpainless.util.selection.key.SecretKeySelectionStrategy; - -public class Or { - - public static class PubKeySelectionStrategy extends PublicKeySelectionStrategy { - - private final Set strategies = new HashSet<>(); - - public PubKeySelectionStrategy(@Nonnull PublicKeySelectionStrategy... strategies) { - this.strategies.addAll(Arrays.asList(strategies)); - } - - @Override - public boolean accept(PGPPublicKey key) { - boolean accept = false; - for (PublicKeySelectionStrategy strategy : strategies) { - accept |= strategy.accept(key); - } - return accept; - } - } - - public static class SecKeySelectionStrategy extends SecretKeySelectionStrategy { - - private final Set strategies = new HashSet<>(); - - public SecKeySelectionStrategy(@Nonnull SecretKeySelectionStrategy... strategies) { - this.strategies.addAll(Arrays.asList(strategies)); - } - - @Override - public boolean accept(PGPSecretKey key) { - boolean accept = false; - for (SecretKeySelectionStrategy strategy : strategies) { - accept |= strategy.accept(key); - } - return accept; - } - } - -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/SignatureKeySelectionStrategy.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/SignatureKeySelectionStrategy.java deleted file mode 100644 index 9b5e310b..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/SignatureKeySelectionStrategy.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key.impl; - -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.annotation.Nonnull; - -import org.bouncycastle.openpgp.PGPSecretKey; -import org.pgpainless.algorithm.KeyFlag; -import org.pgpainless.algorithm.PublicKeyAlgorithm; -import org.pgpainless.util.selection.key.SecretKeySelectionStrategy; - -/** - * Key Selection Strategy that only accepts {@link PGPSecretKey}s which are capable of signing. - */ -public class SignatureKeySelectionStrategy extends SecretKeySelectionStrategy { - - private static final Logger LOGGER = Logger.getLogger(SignatureKeySelectionStrategy.class.getName()); - - HasAnyKeyFlagSelectionStrategy.SecretKey flagSelector = - new HasAnyKeyFlagSelectionStrategy.SecretKey(KeyFlag.SIGN_DATA); - - @Override - public boolean accept(@Nonnull PGPSecretKey key) { - boolean hasSignDataKeyFlag = flagSelector.accept(key); - - if (!key.isSigningKey()) { - LOGGER.log(Level.FINE, "Rejecting key " + Long.toHexString(key.getKeyID()) + " as its algorithm (" + - PublicKeyAlgorithm.fromId(key.getPublicKey().getAlgorithm()) + ") is not capable of signing."); - return false; - } - - if (!hasSignDataKeyFlag) { - LOGGER.log(Level.FINE, "Rejecting key " + Long.toHexString(key.getKeyID()) + - " as it does not carry the key flag SIGN_DATA."); - return false; - } - return true; - } - -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/package-info.java b/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/package-info.java deleted file mode 100644 index 6729a311..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/selection/key/impl/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Implementations of Key Selection Strategies. - */ -package org.pgpainless.util.selection.key.impl; diff --git a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/SigningTest.java b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/SigningTest.java index f04b2c11..ab03f45a 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/SigningTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/SigningTest.java @@ -45,10 +45,10 @@ import org.pgpainless.decryption_verification.OpenPgpMetadata; import org.pgpainless.exception.KeyValidationException; import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.TestKeys; +import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.util.KeyRingUtils; import org.pgpainless.util.Passphrase; -import org.pgpainless.util.selection.key.impl.SignatureKeySelectionStrategy; public class SigningTest { @@ -61,9 +61,8 @@ public class SigningTest { PGPPublicKeyRing romeoKeys = TestKeys.getRomeoPublicKeyRing(); PGPSecretKeyRing cryptieKeys = TestKeys.getCryptieSecretKeyRing(); - PGPSecretKey cryptieSigningKey = new SignatureKeySelectionStrategy() - .selectKeysFromKeyRing(cryptieKeys) - .iterator().next(); + KeyRingInfo cryptieInfo = new KeyRingInfo(cryptieKeys); + PGPSecretKey cryptieSigningKey = cryptieKeys.getSecretKey(cryptieInfo.getSigningSubkeys().get(0).getKeyID()); PGPPublicKeyRingCollection keys = new PGPPublicKeyRingCollection(Arrays.asList(julietKeys, romeoKeys)); diff --git a/pgpainless-core/src/test/java/org/pgpainless/util/BCUtilTest.java b/pgpainless-core/src/test/java/org/pgpainless/util/BCUtilTest.java index 69887b8d..857e6574 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/util/BCUtilTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/util/BCUtilTest.java @@ -16,8 +16,6 @@ package org.pgpainless.util; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; @@ -30,7 +28,6 @@ import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; -import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.junit.jupiter.api.Test; @@ -105,32 +102,4 @@ public class BCUtilTest { LOGGER.log(Level.FINER, "PubCol: " + pubColSize); } - - @Test - public void removeUnsignedKeysTest() - throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { - @SuppressWarnings("deprecation") - PGPSecretKeyRing alice = PGPainless.generateKeyRing().simpleRsaKeyRing("alice@wonderland.lit", RsaLength._1024); - PGPSecretKeyRing mallory = PGPainless.generateKeyRing().simpleEcKeyRing("mallory@mall.ory"); - - PGPSecretKey subKey = null; - Iterator sit = mallory.getSecretKeys(); - while (sit.hasNext()) { - PGPSecretKey s = sit.next(); - if (!s.isMasterKey()) { - subKey = s; - break; - } - } - - assertNotNull(subKey); - - PGPSecretKeyRing alice_mallory = PGPSecretKeyRing.insertSecretKey(alice, subKey); - - // Check, if alice_mallory contains mallory's key - assertNotNull(alice_mallory.getSecretKey(subKey.getKeyID())); - - PGPSecretKeyRing cleaned = KeyRingUtils.removeUnassociatedKeysFromKeyRing(alice_mallory, alice.getPublicKey()); - assertNull(cleaned.getSecretKey(subKey.getKeyID())); - } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/AndOrSelectionStrategyTest.java b/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/AndOrSelectionStrategyTest.java deleted file mode 100644 index 32e85006..00000000 --- a/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/AndOrSelectionStrategyTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2021 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.util.Iterator; - -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.bouncycastle.openpgp.PGPSecretKeyRing; -import org.junit.jupiter.api.Test; -import org.pgpainless.algorithm.KeyFlag; -import org.pgpainless.key.TestKeys; -import org.pgpainless.util.selection.key.impl.EncryptionKeySelectionStrategy; -import org.pgpainless.util.selection.key.impl.HasAnyKeyFlagSelectionStrategy; -import org.pgpainless.util.selection.key.impl.Or; - -public class AndOrSelectionStrategyTest { - - @Test - public void testOr() throws IOException, PGPException { - PGPSecretKeyRing ring = TestKeys.getEmilSecretKeyRing(); - Iterator secretKeys = ring.getSecretKeys(); - Or.SecKeySelectionStrategy secStrategy = new Or.SecKeySelectionStrategy( - new HasAnyKeyFlagSelectionStrategy.SecretKey(KeyFlag.ENCRYPT_COMMS), - new HasAnyKeyFlagSelectionStrategy.SecretKey(KeyFlag.ENCRYPT_STORAGE) - ); - PGPSecretKey certSecKey = secretKeys.next(); - PGPSecretKey cryptSecKey = secretKeys.next(); - - assertFalse(secStrategy.accept(certSecKey)); - assertTrue(secStrategy.accept(cryptSecKey)); - - Iterator publicKeys = ring.getPublicKeys(); - Or.PubKeySelectionStrategy pubStrategy = new Or.PubKeySelectionStrategy( - new EncryptionKeySelectionStrategy(KeyFlag.ENCRYPT_COMMS), - new EncryptionKeySelectionStrategy(KeyFlag.ENCRYPT_STORAGE) - ); - PGPPublicKey certPubKey = publicKeys.next(); - PGPPublicKey cryptPubKey = publicKeys.next(); - - assertFalse(pubStrategy.accept(certPubKey)); - assertTrue(pubStrategy.accept(cryptPubKey)); - } -} diff --git a/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyBelongsToKeyRingTest.java b/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyBelongsToKeyRingTest.java deleted file mode 100644 index 1fd17535..00000000 --- a/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyBelongsToKeyRingTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2021 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.util.Iterator; - -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSecretKeyRing; -import org.junit.jupiter.api.Test; -import org.pgpainless.PGPainless; -import org.pgpainless.key.TestKeys; -import org.pgpainless.util.selection.key.impl.KeyBelongsToKeyRing; - -public class KeyBelongsToKeyRingTest { - - @Test - public void testStrategyOnlyAcceptsKeysThatBelongToKeyRing() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing("test@test.test"); - Iterator iterator = secretKeys.getPublicKeys(); - PGPPublicKey primaryKey = iterator.next(); - PGPPublicKey subKey = iterator.next(); - - KeyBelongsToKeyRing.PubkeySelectionStrategy strategy = new KeyBelongsToKeyRing.PubkeySelectionStrategy(primaryKey); - assertTrue(strategy.accept(primaryKey)); - assertTrue(strategy.accept(subKey)); - - PGPSecretKeyRing unrelatedKeys = TestKeys.getEmilSecretKeyRing(); - Iterator unrelated = unrelatedKeys.getPublicKeys(); - while (unrelated.hasNext()) { - PGPPublicKey unrelatedKey = unrelated.next(); - assertFalse(strategy.accept(unrelatedKey)); - } - } -} diff --git a/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyFlagBasedSelectionStrategyTest.java b/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyFlagBasedSelectionStrategyTest.java deleted file mode 100644 index 27422354..00000000 --- a/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyFlagBasedSelectionStrategyTest.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2021 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.util.selection.key; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPPublicKeyRing; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.bouncycastle.openpgp.PGPSecretKeyRing; -import org.junit.jupiter.api.Test; -import org.pgpainless.PGPainless; -import org.pgpainless.algorithm.KeyFlag; -import org.pgpainless.key.generation.KeySpec; -import org.pgpainless.key.generation.type.KeyType; -import org.pgpainless.key.generation.type.ecc.EllipticCurve; -import org.pgpainless.key.generation.type.eddsa.EdDSACurve; -import org.pgpainless.key.generation.type.xdh.XDHSpec; -import org.pgpainless.util.selection.key.impl.HasAllKeyFlagSelectionStrategy; -import org.pgpainless.util.selection.key.impl.HasAnyKeyFlagSelectionStrategy; -import org.pgpainless.key.util.KeyRingUtils; - -public class KeyFlagBasedSelectionStrategyTest { - - @Test - public void testKeyFlagSelectors() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() - .withSubKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._P256)) - .withKeyFlags(KeyFlag.SIGN_DATA) - .withDefaultAlgorithms()) - .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) - .withKeyFlags(KeyFlag.ENCRYPT_COMMS) - .withDefaultAlgorithms()) - .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) - .withKeyFlags(KeyFlag.CERTIFY_OTHER, KeyFlag.AUTHENTICATION) - .withDefaultAlgorithms()) - .withPrimaryUserId("test@test.test") - .withoutPassphrase().build(); - - Iterator iterator = secretKeys.iterator(); - // CERTIFY_OTHER and AUTHENTICATION - PGPSecretKey s_primaryKey = iterator.next(); - // SIGN_DATA - PGPSecretKey s_signingKey = iterator.next(); - // ENCRYPT_COMMS - PGPSecretKey s_encryptionKey = iterator.next(); - - HasAllKeyFlagSelectionStrategy.SecretKey s_certifyOther = - new HasAllKeyFlagSelectionStrategy.SecretKey(KeyFlag.CERTIFY_OTHER); - HasAllKeyFlagSelectionStrategy.SecretKey s_encryptComms = - new HasAllKeyFlagSelectionStrategy.SecretKey(KeyFlag.ENCRYPT_COMMS); - HasAllKeyFlagSelectionStrategy.SecretKey s_encryptCommsEncryptStorage = - new HasAllKeyFlagSelectionStrategy.SecretKey(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE); - HasAnyKeyFlagSelectionStrategy.SecretKey s_anyEncryptCommsEncryptStorage = - new HasAnyKeyFlagSelectionStrategy.SecretKey(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE); - - assertTrue(s_certifyOther.accept(s_primaryKey)); - assertFalse(s_certifyOther.accept(s_encryptionKey)); - assertFalse(s_certifyOther.accept(s_signingKey)); - - assertTrue(s_encryptComms.accept(s_encryptionKey)); - assertFalse(s_encryptComms.accept(s_primaryKey)); - assertFalse(s_encryptComms.accept(s_signingKey)); - - assertFalse(s_encryptCommsEncryptStorage.accept(s_encryptionKey), - "Must not accept the key, as it only carries ENCRYPT_COMMS, but not ENCRYPT_STORAGE"); - assertFalse(s_encryptCommsEncryptStorage.accept(s_primaryKey)); - assertFalse(s_encryptCommsEncryptStorage.accept(s_signingKey)); - - assertTrue(s_anyEncryptCommsEncryptStorage.accept(s_encryptionKey)); - assertFalse(s_anyEncryptCommsEncryptStorage.accept(s_primaryKey)); - assertFalse(s_anyEncryptCommsEncryptStorage.accept(s_signingKey)); - - PGPPublicKey p_primaryKey = s_primaryKey.getPublicKey(); - PGPPublicKey p_encryptionKey = s_encryptionKey.getPublicKey(); - PGPPublicKey p_signingKey = s_signingKey.getPublicKey(); - - HasAllKeyFlagSelectionStrategy.PublicKey p_certifyOther = - new HasAllKeyFlagSelectionStrategy.PublicKey(KeyFlag.CERTIFY_OTHER); - HasAllKeyFlagSelectionStrategy.PublicKey p_encryptComms = - new HasAllKeyFlagSelectionStrategy.PublicKey(KeyFlag.ENCRYPT_COMMS); - HasAllKeyFlagSelectionStrategy.PublicKey p_encryptCommsEncryptStorage = - new HasAllKeyFlagSelectionStrategy.PublicKey(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE); - HasAnyKeyFlagSelectionStrategy.PublicKey p_anyEncryptCommsEncryptStorage = - new HasAnyKeyFlagSelectionStrategy.PublicKey(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE); - - assertTrue(p_certifyOther.accept(p_primaryKey)); - assertFalse(p_certifyOther.accept(p_encryptionKey)); - assertFalse(p_certifyOther.accept(p_signingKey)); - - assertTrue(p_encryptComms.accept(p_encryptionKey)); - assertFalse(p_encryptComms.accept(p_primaryKey)); - assertFalse(p_encryptComms.accept(p_signingKey)); - - assertFalse(p_encryptCommsEncryptStorage.accept(p_encryptionKey), - "Must not accept the key, as it only carries ENCRYPT_COMMS, but not ENCRYPT_STORAGE"); - assertFalse(p_encryptCommsEncryptStorage.accept(p_primaryKey)); - assertFalse(p_encryptCommsEncryptStorage.accept(p_signingKey)); - - assertTrue(p_anyEncryptCommsEncryptStorage.accept(p_encryptionKey)); - assertFalse(p_anyEncryptCommsEncryptStorage.accept(p_primaryKey)); - assertFalse(p_anyEncryptCommsEncryptStorage.accept(p_signingKey)); - } - - @Test - public void testSelectKeysFromKeyRing() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() - .withSubKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._P256)) - .withKeyFlags(KeyFlag.SIGN_DATA) - .withDefaultAlgorithms()) - .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) - .withKeyFlags(KeyFlag.ENCRYPT_COMMS) - .withDefaultAlgorithms()) - .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) - .withKeyFlags(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA, KeyFlag.AUTHENTICATION) - .withDefaultAlgorithms()) - .withPrimaryUserId("test@test.test") - .withoutPassphrase().build(); - - HasAnyKeyFlagSelectionStrategy.SecretKey secSelection = - new HasAnyKeyFlagSelectionStrategy.SecretKey(KeyFlag.SIGN_DATA); - - Set secSigningKeys = secSelection.selectKeysFromKeyRing(secretKeys); - assertEquals(2, secSigningKeys.size()); - - PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys); - - HasAnyKeyFlagSelectionStrategy.PublicKey pubSelection = - new HasAnyKeyFlagSelectionStrategy.PublicKey(KeyFlag.SIGN_DATA); - - Set pubSigningKeys = pubSelection.selectKeysFromKeyRing(publicKeys); - assertEquals(2, pubSigningKeys.size()); - - List ids = new ArrayList<>(); - for (PGPSecretKey secretKey : secSigningKeys) { - ids.add(secretKey.getKeyID()); - } - - for (PGPPublicKey publicKey : pubSigningKeys) { - assertTrue(ids.contains(publicKey.getKeyID())); - } - - secSelection = new HasAnyKeyFlagSelectionStrategy.SecretKey(KeyFlag.ENCRYPT_STORAGE); - assertTrue(secSelection.selectKeysFromKeyRing(secretKeys).isEmpty()); - } -}