diff --git a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java index af557703..ca7b8ddb 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java +++ b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java @@ -23,6 +23,7 @@ import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator; import org.pgpainless.algorithm.EncryptionPurpose; import org.pgpainless.algorithm.SymmetricKeyAlgorithm; +import org.pgpainless.exception.KeyException; import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.OpenPgpFingerprint; import org.pgpainless.key.SubkeyIdentifier; @@ -154,7 +155,7 @@ public class EncryptionOptions { List encryptionSubkeys = encryptionKeySelectionStrategy .selectEncryptionSubkeys(info.getEncryptionSubkeys(userId, purpose)); if (encryptionSubkeys.isEmpty()) { - throw new IllegalArgumentException("Key has no suitable encryption subkeys."); + throw new KeyException.UnacceptableEncryptionKeyException(OpenPgpFingerprint.of(key)); } for (PGPPublicKey encryptionSubkey : encryptionSubkeys) { @@ -193,16 +194,16 @@ public class EncryptionOptions { try { primaryKeyExpiration = info.getPrimaryKeyExpirationDate(); } catch (NoSuchElementException e) { - throw new IllegalArgumentException("Provided key " + OpenPgpFingerprint.of(key) + " does not have a valid/acceptable signature carrying a primary key expiration date."); + throw new KeyException.UnacceptableSelfSignatureException(OpenPgpFingerprint.of(key)); } if (primaryKeyExpiration != null && primaryKeyExpiration.before(evaluationDate)) { - throw new IllegalArgumentException("Provided key " + OpenPgpFingerprint.of(key) + " is expired: " + primaryKeyExpiration); + throw new KeyException.ExpiredKeyException(OpenPgpFingerprint.of(key), primaryKeyExpiration); } List encryptionSubkeys = encryptionKeySelectionStrategy .selectEncryptionSubkeys(info.getEncryptionSubkeys(purpose)); if (encryptionSubkeys.isEmpty()) { - throw new IllegalArgumentException("Key " + OpenPgpFingerprint.of(key) + " has no suitable encryption subkeys."); + throw new KeyException.UnacceptableEncryptionKeyException(OpenPgpFingerprint.of(key)); } for (PGPPublicKey encryptionSubkey : encryptionSubkeys) { diff --git a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java index 52d21641..f81bf5aa 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java +++ b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java @@ -24,8 +24,7 @@ import org.pgpainless.algorithm.DocumentSignatureType; import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.PublicKeyAlgorithm; import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator; -import org.pgpainless.exception.KeyCannotSignException; -import org.pgpainless.exception.KeyValidationError; +import org.pgpainless.exception.KeyException; import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.OpenPgpFingerprint; import org.pgpainless.key.SubkeyIdentifier; @@ -120,13 +119,13 @@ public final class SigningOptions { * @param signingKeys collection of signing keys * @param signatureType type of signature (binary, canonical text) * @return this - * @throws KeyValidationError if something is wrong with any of the keys + * @throws KeyException if something is wrong with any of the keys * @throws PGPException if any of the keys cannot be unlocked or a signing method cannot be created */ public SigningOptions addInlineSignatures(SecretKeyRingProtector secrectKeyDecryptor, Iterable signingKeys, DocumentSignatureType signatureType) - throws KeyValidationError, PGPException { + throws KeyException, PGPException { for (PGPSecretKeyRing signingKey : signingKeys) { addInlineSignature(secrectKeyDecryptor, signingKey, signatureType); } @@ -141,14 +140,14 @@ public final class SigningOptions { * @param secretKeyDecryptor decryptor to unlock the signing secret key * @param secretKey signing key * @param signatureType type of signature (binary, canonical text) - * @throws KeyValidationError if something is wrong with the key + * @throws KeyException if something is wrong with the key * @throws PGPException if the key cannot be unlocked or the signing method cannot be created * @return this */ public SigningOptions addInlineSignature(SecretKeyRingProtector secretKeyDecryptor, PGPSecretKeyRing secretKey, DocumentSignatureType signatureType) - throws KeyValidationError, PGPException { + throws KeyException, PGPException { return addInlineSignature(secretKeyDecryptor, secretKey, null, signatureType); } @@ -164,14 +163,14 @@ public final class SigningOptions { * @param userId user-id of the signer * @param signatureType signature type (binary, canonical text) * @return this - * @throws KeyValidationError if the key is invalid + * @throws KeyException if the key is invalid * @throws PGPException if the key cannot be unlocked or the signing method cannot be created */ public SigningOptions addInlineSignature(SecretKeyRingProtector secretKeyDecryptor, PGPSecretKeyRing secretKey, String userId, DocumentSignatureType signatureType) - throws KeyValidationError, PGPException { + throws KeyException, PGPException { return addInlineSignature(secretKeyDecryptor, secretKey, userId, signatureType, null); } @@ -188,7 +187,8 @@ public final class SigningOptions { * @param signatureType signature type (binary, canonical text) * @param subpacketsCallback callback to modify the hashed and unhashed subpackets of the signature * @return this - * @throws KeyValidationError if the key is invalid + * @throws KeyException + * if the key is invalid * @throws PGPException if the key cannot be unlocked or the signing method cannot be created */ public SigningOptions addInlineSignature(SecretKeyRingProtector secretKeyDecryptor, @@ -196,19 +196,27 @@ public final class SigningOptions { String userId, DocumentSignatureType signatureType, @Nullable BaseSignatureSubpackets.Callback subpacketsCallback) - throws KeyValidationError, PGPException { + throws KeyException, PGPException { KeyRingInfo keyRingInfo = new KeyRingInfo(secretKey, new Date()); if (userId != null && !keyRingInfo.isUserIdValid(userId)) { - throw new KeyValidationError(userId, keyRingInfo.getLatestUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId)); + throw new KeyException.UnboundUserIdException( + OpenPgpFingerprint.of(secretKey), + userId, + keyRingInfo.getLatestUserIdCertification(userId), + keyRingInfo.getUserIdRevocation(userId) + ); } List signingPubKeys = keyRingInfo.getSigningSubkeys(); if (signingPubKeys.isEmpty()) { - throw new KeyCannotSignException("Key " + OpenPgpFingerprint.of(secretKey) + " has no valid signing key."); + throw new KeyException.UnacceptableSigningKeyException(OpenPgpFingerprint.of(secretKey)); } for (PGPPublicKey signingPubKey : signingPubKeys) { PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID()); + if (signingSecKey == null) { + throw new KeyException.MissingSecretKeyException(OpenPgpFingerprint.of(secretKey), signingPubKey.getKeyID()); + } PGPPrivateKey signingSubkey = UnlockSecretKey.unlockSecretKey(signingSecKey, secretKeyDecryptor); Set hashAlgorithms = userId != null ? keyRingInfo.getPreferredHashAlgorithms(userId) : keyRingInfo.getPreferredHashAlgorithms(signingPubKey.getKeyID()); @@ -304,18 +312,23 @@ public final class SigningOptions { throws PGPException { KeyRingInfo keyRingInfo = new KeyRingInfo(secretKey, new Date()); if (userId != null && !keyRingInfo.isUserIdValid(userId)) { - throw new KeyValidationError(userId, keyRingInfo.getLatestUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId)); + throw new KeyException.UnboundUserIdException( + OpenPgpFingerprint.of(secretKey), + userId, + keyRingInfo.getLatestUserIdCertification(userId), + keyRingInfo.getUserIdRevocation(userId) + ); } List signingPubKeys = keyRingInfo.getSigningSubkeys(); if (signingPubKeys.isEmpty()) { - throw new KeyCannotSignException("Key has no valid signing key."); + throw new KeyException.UnacceptableSigningKeyException(OpenPgpFingerprint.of(secretKey)); } for (PGPPublicKey signingPubKey : signingPubKeys) { PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID()); if (signingSecKey == null) { - throw new PGPException("Missing secret key for signing key " + Long.toHexString(signingPubKey.getKeyID())); + throw new KeyException.MissingSecretKeyException(OpenPgpFingerprint.of(secretKey), signingPubKey.getKeyID()); } PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey( secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID())); @@ -340,8 +353,9 @@ public final class SigningOptions { PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.requireFromId(signingSecretKey.getPublicKey().getAlgorithm()); int bitStrength = secretKey.getPublicKey().getBitStrength(); if (!PGPainless.getPolicy().getPublicKeyAlgorithmPolicy().isAcceptable(publicKeyAlgorithm, bitStrength)) { - throw new IllegalArgumentException("Public key algorithm policy violation: " + - publicKeyAlgorithm + " with bit strength " + bitStrength + " is not acceptable."); + throw new KeyException.UnacceptableSigningKeyException( + new KeyException.PublicKeyAlgorithmPolicyException( + OpenPgpFingerprint.of(secretKey), signingSecretKey.getKeyID(), publicKeyAlgorithm, bitStrength)); } PGPSignatureGenerator generator = createSignatureGenerator(signingSubkey, hashAlgorithm, signatureType); diff --git a/pgpainless-core/src/main/java/org/pgpainless/exception/KeyCannotSignException.java b/pgpainless-core/src/main/java/org/pgpainless/exception/KeyCannotSignException.java deleted file mode 100644 index ee869fa9..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/exception/KeyCannotSignException.java +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.exception; - -import org.bouncycastle.openpgp.PGPException; - -public class KeyCannotSignException extends PGPException { - public KeyCannotSignException(String message) { - super(message); - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/exception/KeyException.java b/pgpainless-core/src/main/java/org/pgpainless/exception/KeyException.java new file mode 100644 index 00000000..7ffc66ee --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/exception/KeyException.java @@ -0,0 +1,118 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.exception; + +import org.bouncycastle.openpgp.PGPSignature; +import org.pgpainless.algorithm.PublicKeyAlgorithm; +import org.pgpainless.key.OpenPgpFingerprint; +import org.pgpainless.util.DateUtil; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Date; + +public abstract class KeyException extends RuntimeException { + + private final OpenPgpFingerprint fingerprint; + + protected KeyException(@Nonnull String message, @Nonnull OpenPgpFingerprint fingerprint) { + super(message); + this.fingerprint = fingerprint; + } + + protected KeyException(@Nonnull String message, @Nonnull OpenPgpFingerprint fingerprint, @Nonnull Throwable underlying) { + super(message, underlying); + this.fingerprint = fingerprint; + } + + public OpenPgpFingerprint getFingerprint() { + return fingerprint; + } + + public static class ExpiredKeyException extends KeyException { + + public ExpiredKeyException(@Nonnull OpenPgpFingerprint fingerprint, @Nonnull Date expirationDate) { + super("Key " + fingerprint + " is expired. Expiration date: " + DateUtil.formatUTCDate(expirationDate), fingerprint); + } + } + + public static class UnacceptableEncryptionKeyException extends KeyException { + + public UnacceptableEncryptionKeyException(@Nonnull OpenPgpFingerprint fingerprint) { + super("Key " + fingerprint + " has no acceptable encryption key.", fingerprint); + } + + public UnacceptableEncryptionKeyException(@Nonnull PublicKeyAlgorithmPolicyException reason) { + super("Key " + reason.getFingerprint() + " has no acceptable encryption key.", reason.getFingerprint(), reason); + } + } + + public static class UnacceptableSigningKeyException extends KeyException { + + public UnacceptableSigningKeyException(@Nonnull OpenPgpFingerprint fingerprint) { + super("Key " + fingerprint + " has no acceptable signing key.", fingerprint); + } + + public UnacceptableSigningKeyException(@Nonnull PublicKeyAlgorithmPolicyException reason) { + super("Key " + reason.getFingerprint() + " has no acceptable signing key.", reason.getFingerprint(), reason); + } + } + + public static class UnacceptableSelfSignatureException extends KeyException { + + public UnacceptableSelfSignatureException(@Nonnull OpenPgpFingerprint fingerprint) { + super("Key " + fingerprint + " does not have a valid/acceptable signature to derive an expiration date from.", fingerprint); + } + } + + public static class MissingSecretKeyException extends KeyException { + + private final long missingSecretKeyId; + + public MissingSecretKeyException(@Nonnull OpenPgpFingerprint fingerprint, long keyId) { + super("Key " + fingerprint + " does not contain a secret key for public key " + Long.toHexString(keyId), fingerprint); + this.missingSecretKeyId = keyId; + } + + public long getMissingSecretKeyId() { + return missingSecretKeyId; + } + } + + public static class PublicKeyAlgorithmPolicyException extends KeyException { + + private final long violatingSubkeyId; + + public PublicKeyAlgorithmPolicyException(@Nonnull OpenPgpFingerprint fingerprint, long keyId, @Nonnull PublicKeyAlgorithm algorithm, int bitSize) { + super("Subkey " + Long.toHexString(keyId) + " of key " + fingerprint + " is violating the Public Key Algorithm Policy:\n" + + algorithm + " of size " + bitSize + " is not acceptable.", fingerprint); + this.violatingSubkeyId = keyId; + } + + public long getViolatingSubkeyId() { + return violatingSubkeyId; + } + } + + public static class UnboundUserIdException extends KeyException { + + public UnboundUserIdException(@Nonnull OpenPgpFingerprint fingerprint, @Nonnull String userId, + @Nullable PGPSignature userIdSignature, @Nullable PGPSignature userIdRevocation) { + super(errorMessage(fingerprint, userId, userIdSignature, userIdRevocation), fingerprint); + } + + private static String errorMessage(@Nonnull OpenPgpFingerprint fingerprint, @Nonnull String userId, + @Nullable PGPSignature userIdSignature, @Nullable PGPSignature userIdRevocation) { + String errorMessage = "UserID '" + userId + "' is not valid for key " + fingerprint + ": "; + if (userIdSignature == null) { + return errorMessage + "Missing binding signature."; + } + if (userIdRevocation != null) { + return errorMessage + "UserID is revoked."; + } + return errorMessage + "Unacceptable binding signature."; + } + } +} diff --git a/pgpainless-core/src/main/java/org/pgpainless/exception/KeyIntegrityException.java b/pgpainless-core/src/main/java/org/pgpainless/exception/KeyIntegrityException.java index 65ed3dea..b7a87ab7 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/exception/KeyIntegrityException.java +++ b/pgpainless-core/src/main/java/org/pgpainless/exception/KeyIntegrityException.java @@ -4,6 +4,10 @@ package org.pgpainless.exception; +/** + * This exception gets thrown, when the integrity of an OpenPGP key is broken. + * That could happen on accident, or during an active attack, so take this exception seriously. + */ public class KeyIntegrityException extends AssertionError { public KeyIntegrityException() { diff --git a/pgpainless-core/src/main/java/org/pgpainless/exception/KeyValidationError.java b/pgpainless-core/src/main/java/org/pgpainless/exception/KeyValidationError.java deleted file mode 100644 index 8296d6c9..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/exception/KeyValidationError.java +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.exception; - -import org.bouncycastle.openpgp.PGPSignature; - -public class KeyValidationError extends AssertionError { - - public KeyValidationError(String userId, PGPSignature userIdSig, PGPSignature userIdRevocation) { - super("User-ID '" + userId + "' is not valid: Sig: " + userIdSig + " Rev: " + userIdRevocation); - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java index f1611aff..3ea2f424 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java @@ -36,7 +36,7 @@ import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.KeyFlag; import org.pgpainless.algorithm.PublicKeyAlgorithm; import org.pgpainless.algorithm.SymmetricKeyAlgorithm; -import org.pgpainless.exception.KeyValidationError; +import org.pgpainless.exception.KeyException; import org.pgpainless.key.OpenPgpFingerprint; import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.util.RevocationAttributes; @@ -949,7 +949,12 @@ public class KeyRingInfo { */ public @Nonnull List getEncryptionSubkeys(String userId, EncryptionPurpose purpose) { if (userId != null && !isUserIdValid(userId)) { - throw new KeyValidationError(userId, getLatestUserIdCertification(userId), getUserIdRevocation(userId)); + throw new KeyException.UnboundUserIdException( + OpenPgpFingerprint.of(keys), + userId, + getLatestUserIdCertification(userId), + getUserIdRevocation(userId) + ); } return getEncryptionSubkeys(purpose); diff --git a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptDecryptTest.java b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptDecryptTest.java index 966e273f..88a2c38b 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptDecryptTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptDecryptTest.java @@ -34,6 +34,7 @@ import org.pgpainless.algorithm.SymmetricKeyAlgorithm; import org.pgpainless.decryption_verification.ConsumerOptions; import org.pgpainless.decryption_verification.DecryptionStream; import org.pgpainless.decryption_verification.OpenPgpMetadata; +import org.pgpainless.exception.KeyException; import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.TestKeys; import org.pgpainless.key.generation.KeySpec; @@ -326,7 +327,7 @@ public class EncryptDecryptTest { PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key); - assertThrows(IllegalArgumentException.class, () -> + assertThrows(KeyException.UnacceptableEncryptionKeyException.class, () -> EncryptionOptions.encryptCommunications() .addRecipient(publicKeys)); } diff --git a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptionOptionsTest.java b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptionOptionsTest.java index 0c5f6489..488e5918 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptionOptionsTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptionOptionsTest.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; import org.pgpainless.algorithm.KeyFlag; import org.pgpainless.algorithm.SymmetricKeyAlgorithm; -import org.pgpainless.exception.KeyValidationError; +import org.pgpainless.exception.KeyException; import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.generation.KeySpec; import org.pgpainless.key.generation.type.KeyType; @@ -132,14 +132,14 @@ public class EncryptionOptionsTest { .build(); PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys); - assertThrows(IllegalArgumentException.class, () -> options.addRecipient(publicKeys)); + assertThrows(KeyException.UnacceptableEncryptionKeyException.class, () -> options.addRecipient(publicKeys)); } @Test public void testEncryptionKeySelectionStrategyEmpty_ThrowsAssertionError() { EncryptionOptions options = new EncryptionOptions(); - assertThrows(IllegalArgumentException.class, + assertThrows(KeyException.UnacceptableEncryptionKeyException.class, () -> options.addRecipient(publicKeys, new EncryptionOptions.EncryptionKeySelector() { @Override public List selectEncryptionSubkeys(List encryptionCapableKeys) { @@ -147,7 +147,7 @@ public class EncryptionOptionsTest { } })); - assertThrows(IllegalArgumentException.class, + assertThrows(KeyException.UnacceptableEncryptionKeyException.class, () -> options.addRecipient(publicKeys, "test@pgpainless.org", new EncryptionOptions.EncryptionKeySelector() { @Override public List selectEncryptionSubkeys(List encryptionCapableKeys) { @@ -180,6 +180,6 @@ public class EncryptionOptionsTest { @Test public void testAddRecipient_withInvalidUserId() { EncryptionOptions options = new EncryptionOptions(); - assertThrows(KeyValidationError.class, () -> options.addRecipient(publicKeys, "invalid@user.id")); + assertThrows(KeyException.UnboundUserIdException.class, () -> options.addRecipient(publicKeys, "invalid@user.id")); } } 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 593938ad..156e6b57 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 @@ -35,8 +35,7 @@ import org.pgpainless.algorithm.KeyFlag; import org.pgpainless.decryption_verification.ConsumerOptions; import org.pgpainless.decryption_verification.DecryptionStream; import org.pgpainless.decryption_verification.OpenPgpMetadata; -import org.pgpainless.exception.KeyCannotSignException; -import org.pgpainless.exception.KeyValidationError; +import org.pgpainless.exception.KeyException; import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.TestKeys; import org.pgpainless.key.generation.KeySpec; @@ -45,9 +44,9 @@ import org.pgpainless.key.generation.type.eddsa.EdDSACurve; import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.util.KeyRingUtils; -import org.pgpainless.util.TestAllImplementations; import org.pgpainless.util.MultiMap; import org.pgpainless.util.Passphrase; +import org.pgpainless.util.TestAllImplementations; public class SigningTest { @@ -125,7 +124,7 @@ public class SigningTest { SigningOptions opts = new SigningOptions(); // "bob" is not a valid user-id - assertThrows(KeyValidationError.class, + assertThrows(KeyException.UnboundUserIdException.class, () -> opts.addInlineSignature(protector, secretKeys, "bob", DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)); } @@ -146,7 +145,7 @@ public class SigningTest { SigningOptions opts = new SigningOptions(); // "alice" has been revoked - assertThrows(KeyValidationError.class, + assertThrows(KeyException.UnboundUserIdException.class, () -> opts.addInlineSignature(protector, fSecretKeys, "alice", DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)); } @@ -253,9 +252,9 @@ public class SigningTest { .build(); SigningOptions options = new SigningOptions(); - assertThrows(KeyCannotSignException.class, () -> options.addDetachedSignature( + assertThrows(KeyException.UnacceptableSigningKeyException.class, () -> options.addDetachedSignature( SecretKeyRingProtector.unprotectedKeys(), secretKeys, DocumentSignatureType.BINARY_DOCUMENT)); - assertThrows(KeyCannotSignException.class, () -> options.addInlineSignature( + assertThrows(KeyException.UnacceptableSigningKeyException.class, () -> options.addInlineSignature( SecretKeyRingProtector.unprotectedKeys(), secretKeys, DocumentSignatureType.BINARY_DOCUMENT)); } @@ -270,10 +269,10 @@ public class SigningTest { .build(); SigningOptions options = new SigningOptions(); - assertThrows(KeyValidationError.class, () -> + assertThrows(KeyException.UnboundUserIdException.class, () -> options.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, "Bob", DocumentSignatureType.BINARY_DOCUMENT)); - assertThrows(KeyValidationError.class, () -> + assertThrows(KeyException.UnboundUserIdException.class, () -> options.addInlineSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, "Bob", DocumentSignatureType.BINARY_DOCUMENT)); } diff --git a/pgpainless-core/src/test/java/org/pgpainless/signature/CertificateExpirationTest.java b/pgpainless-core/src/test/java/org/pgpainless/signature/CertificateExpirationTest.java index c87bd2aa..f8c6471e 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/signature/CertificateExpirationTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/signature/CertificateExpirationTest.java @@ -21,6 +21,7 @@ import org.pgpainless.encryption_signing.EncryptionOptions; import org.pgpainless.encryption_signing.EncryptionResult; import org.pgpainless.encryption_signing.EncryptionStream; import org.pgpainless.encryption_signing.ProducerOptions; +import org.pgpainless.exception.KeyException; import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.SubkeyIdentifier; @@ -124,7 +125,7 @@ public class CertificateExpirationTest { "-----END PGP PUBLIC KEY BLOCK-----\n"; PGPPublicKeyRing cert = PGPainless.readKeyRing().publicKeyRing(CERT); - assertThrows(IllegalArgumentException.class, () -> encrypt(cert)); + assertThrows(KeyException.ExpiredKeyException.class, () -> encrypt(cert)); } private EncryptionResult encrypt(PGPPublicKeyRing certificate) throws PGPException, IOException { diff --git a/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestEncryptCommsStorageFlagsDifferentiated.java b/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestEncryptCommsStorageFlagsDifferentiated.java index 079f1062..b96d95e5 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestEncryptCommsStorageFlagsDifferentiated.java +++ b/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestEncryptCommsStorageFlagsDifferentiated.java @@ -16,6 +16,7 @@ import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; import org.pgpainless.algorithm.KeyFlag; import org.pgpainless.encryption_signing.EncryptionOptions; +import org.pgpainless.exception.KeyException; import org.pgpainless.key.generation.KeySpec; import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.rsa.RsaLength; @@ -38,7 +39,7 @@ public class TestEncryptCommsStorageFlagsDifferentiated { PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys); - assertThrows(IllegalArgumentException.class, () -> EncryptionOptions.encryptCommunications() + assertThrows(KeyException.UnacceptableEncryptionKeyException.class, () -> EncryptionOptions.encryptCommunications() .addRecipient(publicKeys)); } } diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/SignImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/SignImpl.java index b3d18043..286c5262 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/SignImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/SignImpl.java @@ -22,6 +22,7 @@ import org.pgpainless.encryption_signing.EncryptionResult; import org.pgpainless.encryption_signing.EncryptionStream; import org.pgpainless.encryption_signing.ProducerOptions; import org.pgpainless.encryption_signing.SigningOptions; +import org.pgpainless.exception.KeyException; import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.protection.SecretKeyRingProtector; @@ -63,7 +64,7 @@ public class SignImpl implements Sign { } signingOptions.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), key, modeToSigType(mode)); } - } catch (PGPException e) { + } catch (PGPException | KeyException e) { throw new SOPGPException.BadData(e); } return this;