1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-09 10:19:39 +02:00

Port Exception classes to Kotlin

This commit is contained in:
Paul Schaub 2025-05-08 16:16:08 +02:00
parent 65f341f687
commit a76128cf79
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
24 changed files with 377 additions and 430 deletions

View file

@ -1,190 +0,0 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import org.bouncycastle.bcpg.KeyIdentifier;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
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 OpenPGPCertificate cert, @Nonnull Date expirationDate) {
this(OpenPgpFingerprint.of(cert), expirationDate);
}
public ExpiredKeyException(@Nonnull OpenPgpFingerprint fingerprint, @Nonnull Date expirationDate) {
super("Key " + fingerprint + " is expired. Expiration date: " + DateUtil.formatUTCDate(expirationDate), fingerprint);
}
}
public static class RevokedKeyException extends KeyException {
public RevokedKeyException(@Nonnull OpenPgpFingerprint fingerprint) {
super("Key " + fingerprint + " appears to be revoked.", fingerprint);
}
public RevokedKeyException(@Nonnull OpenPGPCertificate.OpenPGPComponentKey key) {
super("Subkey " + key.getKeyIdentifier() + " appears to be revoked.",
OpenPgpFingerprint.of(key));
}
public RevokedKeyException(@Nonnull OpenPGPCertificate cert) {
super("Key or certificate " + cert.getKeyIdentifier() + " appears to be revoked.",
OpenPgpFingerprint.of(cert));
}
}
public static class UnacceptableEncryptionKeyException extends KeyException {
public UnacceptableEncryptionKeyException(@Nonnull OpenPGPCertificate cert) {
this(OpenPgpFingerprint.of(cert));
}
public UnacceptableEncryptionKeyException(@Nonnull OpenPGPCertificate.OpenPGPComponentKey subkey) {
super("Subkey " + subkey.getKeyIdentifier() + " is not an acceptable encryption key.",
OpenPgpFingerprint.of(subkey));
}
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(OpenPGPCertificate certificate) {
this(OpenPgpFingerprint.of(certificate));
}
public UnacceptableSigningKeyException(OpenPGPCertificate.OpenPGPComponentKey subkey) {
this(OpenPgpFingerprint.of(subkey));
}
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 UnacceptableThirdPartyCertificationKeyException extends KeyException {
public UnacceptableThirdPartyCertificationKeyException(@Nonnull OpenPgpFingerprint fingerprint) {
super("Key " + fingerprint + " has no acceptable certification key.", fingerprint);
}
}
public static class UnacceptableSelfSignatureException extends KeyException {
public UnacceptableSelfSignatureException(@Nonnull OpenPGPCertificate cert) {
this(OpenPgpFingerprint.of(cert));
}
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 KeyIdentifier missingSecretKeyIdentifier;
public MissingSecretKeyException(@Nonnull OpenPGPCertificate.OpenPGPComponentKey publicKey) {
this(OpenPgpFingerprint.of(publicKey.getCertificate()), publicKey.getKeyIdentifier());
}
public MissingSecretKeyException(@Nonnull OpenPgpFingerprint fingerprint, KeyIdentifier keyIdentifier) {
super("Key " + fingerprint + " does not contain a secret key for public key " + keyIdentifier, fingerprint);
this.missingSecretKeyIdentifier = keyIdentifier;
}
@Deprecated
public MissingSecretKeyException(@Nonnull OpenPgpFingerprint fingerprint, long keyId) {
this(fingerprint, new KeyIdentifier(keyId));
}
public KeyIdentifier getMissingSecretKeyIdentifier() {
return missingSecretKeyIdentifier;
}
}
public static class PublicKeyAlgorithmPolicyException extends KeyException {
private final KeyIdentifier violatingSubkeyId;
public PublicKeyAlgorithmPolicyException(@Nonnull OpenPGPCertificate.OpenPGPComponentKey subkey,
@Nonnull PublicKeyAlgorithm algorithm,
int bitSize) {
super("Subkey " + subkey.getKeyIdentifier() + " of key " + subkey.getCertificate().getKeyIdentifier() +
" is violating the Public Key Algorithm Policy:\n" +
algorithm + " of size " + bitSize + " is not acceptable.", OpenPgpFingerprint.of(subkey));
this.violatingSubkeyId = subkey.getKeyIdentifier();
}
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 = new KeyIdentifier(keyId);
}
public KeyIdentifier 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.";
}
}
}

View file

@ -1,16 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
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() {
super("Key Integrity Exception");
}
}

View file

@ -1,30 +0,0 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import org.pgpainless.decryption_verification.syntax_check.InputSymbol;
import org.pgpainless.decryption_verification.syntax_check.StackSymbol;
import org.pgpainless.decryption_verification.syntax_check.State;
/**
* Exception that gets thrown if the OpenPGP message is malformed.
* Malformed messages are messages which do not follow the grammar specified in the RFC.
*
* @see <a href="https://www.rfc-editor.org/rfc/rfc4880#section-11.3">RFC4880 §11.3. OpenPGP Messages</a>
*/
public class MalformedOpenPgpMessageException extends RuntimeException {
public MalformedOpenPgpMessageException(String message) {
super(message);
}
public MalformedOpenPgpMessageException(State state, InputSymbol input, StackSymbol stackItem) {
this("There is no legal transition from state '" + state + "' for input '" + input + "' when '" + stackItem + "' is on top of the stack.");
}
public MalformedOpenPgpMessageException(String s, MalformedOpenPgpMessageException e) {
super(s, e);
}
}

View file

@ -1,15 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import org.bouncycastle.openpgp.PGPException;
public class MessageNotIntegrityProtectedException extends PGPException {
public MessageNotIntegrityProtectedException() {
super("Message is encrypted using a 'Symmetrically Encrypted Data' (SED) packet, which enables certain types of attacks. " +
"A 'Symmetrically Encrypted Integrity Protected' (SEIP) packet should be used instead.");
}
}

View file

@ -1,19 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import org.bouncycastle.openpgp.PGPException;
/**
* Exception that is thrown when decryption fails due to a missing decryption key or decryption passphrase.
* This can happen when the user does not provide the right set of keys / the right password when decrypting
* a message.
*/
public class MissingDecryptionMethodException extends PGPException {
public MissingDecryptionMethodException(String message) {
super(message);
}
}

View file

@ -1,26 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import org.bouncycastle.openpgp.PGPException;
import org.pgpainless.key.SubkeyIdentifier;
public class MissingPassphraseException extends PGPException {
private final Set<SubkeyIdentifier> keyIds;
public MissingPassphraseException(Set<SubkeyIdentifier> keyIds) {
super("Missing passphrase encountered for keys " + Arrays.toString(keyIds.toArray()));
this.keyIds = Collections.unmodifiableSet(keyIds);
}
public Set<SubkeyIdentifier> getKeyIds() {
return keyIds;
}
}

View file

@ -1,14 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import java.io.IOException;
/**
* Exception that gets thrown when the verification of a modification detection code failed.
*/
public class ModificationDetectionException extends IOException {
}

View file

@ -1,44 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import java.util.Map;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.algorithm.SignatureType;
public class SignatureValidationException extends PGPException {
public SignatureValidationException(String message) {
super(message);
}
public SignatureValidationException(String message, Exception underlying) {
super(message, underlying);
}
public SignatureValidationException(String message, Map<PGPSignature, Exception> rejections) {
super(message + ": " + exceptionMapToString(rejections));
}
private static String exceptionMapToString(Map<PGPSignature, Exception> rejections) {
StringBuilder sb = new StringBuilder();
sb.append(rejections.size()).append(" rejected signatures:\n");
for (PGPSignature signature : rejections.keySet()) {
String typeString;
SignatureType type = SignatureType.fromCode(signature.getSignatureType());
if (type == null) {
typeString = "0x" + Long.toHexString(signature.getSignatureType());
} else {
typeString = type.toString();
}
sb.append(typeString).append(' ')
.append(signature.getCreationTime()).append(": ")
.append(rejections.get(signature).getMessage()).append('\n');
}
return sb.toString();
}
}

View file

@ -1,17 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import org.bouncycastle.openpgp.PGPException;
/**
* Exception that gets thrown if unacceptable algorithms are encountered.
*/
public class UnacceptableAlgorithmException extends PGPException {
public UnacceptableAlgorithmException(String message) {
super(message);
}
}

View file

@ -1,14 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import org.bouncycastle.openpgp.PGPException;
public class WrongConsumingMethodException extends PGPException {
public WrongConsumingMethodException(String message) {
super(message);
}
}

View file

@ -1,27 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception;
import org.bouncycastle.bcpg.KeyIdentifier;
import org.bouncycastle.openpgp.PGPException;
public class WrongPassphraseException extends PGPException {
public WrongPassphraseException(String message) {
super(message);
}
public WrongPassphraseException(long keyId, PGPException cause) {
this(new KeyIdentifier(keyId), cause);
}
public WrongPassphraseException(KeyIdentifier keyIdentifier, PGPException cause) {
this("Wrong passphrase provided for key " + keyIdentifier, cause);
}
public WrongPassphraseException(String message, PGPException cause) {
super(message, cause);
}
}

View file

@ -1,8 +0,0 @@
// SPDX-FileCopyrightText: 2018 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
/**
* Exceptions.
*/
package org.pgpainless.exception;

View file

@ -1,10 +0,0 @@
// SPDX-FileCopyrightText: 2018 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
/**
* PGPainless - Use OpenPGP Painlessly!
*
* @see <a href="http://pgpainless.org">org.pgpainless.core.org</a>
*/
package org.pgpainless;

View file

@ -0,0 +1,203 @@
package org.pgpainless.exception
import java.util.*
import javax.annotation.Nonnull
import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
import org.pgpainless.algorithm.PublicKeyAlgorithm
import org.pgpainless.key.OpenPgpFingerprint
import org.pgpainless.key.OpenPgpFingerprint.Companion.of
import org.pgpainless.util.DateUtil.Companion.formatUTCDate
abstract class KeyException : RuntimeException {
val fingerprint: OpenPgpFingerprint
protected constructor(message: String, fingerprint: OpenPgpFingerprint) : super(message) {
this.fingerprint = fingerprint
}
protected constructor(
message: String,
fingerprint: OpenPgpFingerprint,
underlying: Throwable
) : super(message, underlying) {
this.fingerprint = fingerprint
}
class ExpiredKeyException(fingerprint: OpenPgpFingerprint, expirationDate: Date) :
KeyException(
"Key $fingerprint is expired. Expiration date: ${formatUTCDate(expirationDate)}",
fingerprint,
) {
constructor(cert: OpenPGPCertificate, expirationDate: Date) : this(of(cert), expirationDate)
}
class RevokedKeyException : KeyException {
constructor(
fingerprint: OpenPgpFingerprint
) : super(
"Key $fingerprint appears to be revoked.",
fingerprint,
)
constructor(
componentKey: OpenPGPComponentKey
) : super(
"Subkey ${componentKey.keyIdentifier} appears to be revoked.",
of(componentKey),
)
constructor(
cert: OpenPGPCertificate
) : super(
"Key or certificate ${cert.keyIdentifier} appears to be revoked.",
of(cert),
)
}
class UnacceptableEncryptionKeyException : KeyException {
constructor(cert: OpenPGPCertificate) : this(of(cert))
constructor(
subkey: OpenPGPComponentKey
) : super(
"Subkey ${subkey.keyIdentifier} is not an acceptable encryption key.",
of(subkey),
)
constructor(
fingerprint: OpenPgpFingerprint
) : super("Key $fingerprint has no acceptable encryption key.", fingerprint)
constructor(
reason: PublicKeyAlgorithmPolicyException
) : super(
"Key ${reason.fingerprint} has no acceptable encryption key.",
reason.fingerprint,
reason)
}
class UnacceptableSigningKeyException : KeyException {
constructor(cert: OpenPGPCertificate) : this(of(cert))
constructor(subkey: OpenPGPComponentKey) : this(of(subkey))
constructor(
fingerprint: OpenPgpFingerprint
) : super("Key $fingerprint has no acceptable signing key.", fingerprint)
constructor(
reason: KeyException.PublicKeyAlgorithmPolicyException
) : super(
"Key ${reason.fingerprint} has no acceptable signing key.", reason.fingerprint, reason)
}
class UnacceptableThirdPartyCertificationKeyException(fingerprint: OpenPgpFingerprint) :
KeyException("Key $fingerprint has no acceptable certification key.", fingerprint) {}
class UnacceptableSelfSignatureException : KeyException {
constructor(cert: OpenPGPCertificate) : this(of(cert))
constructor(
fingerprint: OpenPgpFingerprint
) : super(
"Key $fingerprint does not have a valid/acceptable signature to derive an expiration date from.",
fingerprint,
)
}
class MissingSecretKeyException : KeyException {
val missingSecretKeyIdentifier: KeyIdentifier
constructor(
publicKey: OpenPGPComponentKey
) : this(
of(publicKey.certificate),
publicKey.keyIdentifier,
)
constructor(
fingerprint: OpenPgpFingerprint,
keyIdentifier: KeyIdentifier
) : super(
"Key $fingerprint does not contain a secret key for public key $keyIdentifier",
fingerprint,
) {
missingSecretKeyIdentifier = keyIdentifier
}
@Deprecated("Pass in a KeyIdentifier instead.")
constructor(
fingerprint: OpenPgpFingerprint,
keyId: Long
) : this(fingerprint, KeyIdentifier(keyId))
}
class PublicKeyAlgorithmPolicyException : KeyException {
val violatingSubkeyId: KeyIdentifier
constructor(
subkey: OpenPGPComponentKey,
algorithm: PublicKeyAlgorithm,
bitSize: Int
) : super(
"""Subkey ${subkey.keyIdentifier} of key ${subkey.certificate.keyIdentifier} is violating the Public Key Algorithm Policy:
$algorithm of size $bitSize is not acceptable.""",
of(subkey),
) {
this.violatingSubkeyId = subkey.keyIdentifier
}
constructor(
fingerprint: OpenPgpFingerprint,
keyId: Long,
algorithm: PublicKeyAlgorithm,
bitSize: Int
) : super(
"""Subkey ${java.lang.Long.toHexString(keyId)} of key $fingerprint is violating the Public Key Algorithm Policy:
$algorithm of size $bitSize is not acceptable.""",
fingerprint,
) {
this.violatingSubkeyId = KeyIdentifier(keyId)
}
}
class UnboundUserIdException(
fingerprint: OpenPgpFingerprint,
userId: String,
userIdSignature: PGPSignature?,
userIdRevocation: PGPSignature?
) :
KeyException(
errorMessage(
fingerprint,
userId,
userIdSignature,
userIdRevocation,
),
fingerprint,
) {
companion object {
private fun errorMessage(
@Nonnull fingerprint: OpenPgpFingerprint,
@Nonnull userId: String,
userIdSignature: PGPSignature?,
userIdRevocation: PGPSignature?
): String {
val 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."
}
}
}
}

View file

@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import java.lang.AssertionError
/**
* 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.
*/
class KeyIntegrityException : AssertionError("Key Integrity Exception")

View file

@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import org.pgpainless.decryption_verification.syntax_check.InputSymbol
import org.pgpainless.decryption_verification.syntax_check.StackSymbol
import org.pgpainless.decryption_verification.syntax_check.State
/**
* Exception that gets thrown if the OpenPGP message is malformed. Malformed messages are messages
* which do not follow the grammar specified in the RFC.
*
* @see [RFC4880 §11.3. OpenPGP Messages](https://www.rfc-editor.org/rfc/rfc4880#section-11.3)
*/
class MalformedOpenPgpMessageException : RuntimeException {
constructor(message: String) : super(message)
constructor(message: String, e: MalformedOpenPgpMessageException) : super(message, e)
constructor(
state: State,
input: InputSymbol,
stackItem: StackSymbol?
) : this(
"There is no legal transition from state '$state' for input '$input' when '${stackItem ?: "null"}' is on top of the stack.",
)
}

View file

@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import org.bouncycastle.openpgp.PGPException
class MessageNotIntegrityProtectedException :
PGPException(
"Message is encrypted using a 'Symmetrically Encrypted Data' (SED) packet, which enables certain types of attacks. " +
"A 'Symmetrically Encrypted Integrity Protected' (SEIP) packet should be used instead.",
)

View file

@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import org.bouncycastle.openpgp.PGPException
/**
* Exception that is thrown when decryption fails due to a missing decryption key or decryption
* passphrase. This can happen when the user does not provide the right set of keys / the right
* password when decrypting a message.
*/
class MissingDecryptionMethodException(message: String) : PGPException(message)

View file

@ -0,0 +1,11 @@
package org.pgpainless.exception
import java.util.*
import org.bouncycastle.openpgp.PGPException
import org.pgpainless.key.SubkeyIdentifier
class MissingPassphraseException(keyIds: Set<SubkeyIdentifier>) :
PGPException(
"Missing passphrase encountered for keys ${keyIds.toTypedArray().contentToString()}") {
val keyIds: Set<SubkeyIdentifier> = Collections.unmodifiableSet(keyIds)
}

View file

@ -0,0 +1,10 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import java.io.IOException
/** Exception that gets thrown when the verification of a modification detection code failed. */
class ModificationDetectionException : IOException()

View file

@ -0,0 +1,42 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSignature
import org.pgpainless.algorithm.SignatureType
class SignatureValidationException : PGPException {
constructor(message: String?) : super(message)
constructor(message: String?, underlying: Exception) : super(message, underlying)
constructor(
message: String,
rejections: Map<PGPSignature, Exception>
) : super("$message: ${exceptionMapToString(rejections)}")
companion object {
@JvmStatic
private fun exceptionMapToString(rejections: Map<PGPSignature, Exception>): String =
buildString {
append(rejections.size).append(" rejected signatures:\n")
for (signature in rejections.keys) {
append(sigTypeToString(signature.signatureType))
.append(' ')
.append(signature.creationTime)
.append(": ")
.append(rejections[signature]!!.message)
.append('\n')
}
}
@JvmStatic
private fun sigTypeToString(type: Int): String =
SignatureType.fromCode(type)?.toString()
?: "0x${java.lang.Long.toHexString(type.toLong())}"
}
}

View file

@ -0,0 +1,10 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import org.bouncycastle.openpgp.PGPException
/** Exception that gets thrown if unacceptable algorithms are encountered. */
class UnacceptableAlgorithmException(message: String) : PGPException(message)

View file

@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import org.bouncycastle.openpgp.PGPException
class WrongConsumingMethodException(message: String) : PGPException(message)

View file

@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.exception
import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.PGPException
class WrongPassphraseException : PGPException {
constructor(message: String) : super(message)
constructor(message: String, cause: PGPException) : super(message, cause)
@Deprecated("Pass in a KeyIdentifier instead.")
constructor(keyId: Long, cause: PGPException) : this(KeyIdentifier(keyId), cause)
constructor(
keyIdentifier: KeyIdentifier,
cause: PGPException
) : this("Wrong passphrase provided for key $keyIdentifier", cause)
}