1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-12-22 10:57:58 +01:00

Make more of the API null-safe by using @Nonnull/@Nullable

This commit is contained in:
Paul Schaub 2023-05-03 16:03:50 +02:00
parent 3b8a1b47d7
commit 953206b4ed
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
12 changed files with 263 additions and 137 deletions

View file

@ -40,6 +40,7 @@ public final class PGPainless {
* Generate a fresh OpenPGP key ring from predefined templates.
* @return templates
*/
@Nonnull
public static KeyRingTemplates generateKeyRing() {
return new KeyRingTemplates();
}
@ -49,6 +50,7 @@ public final class PGPainless {
*
* @return builder
*/
@Nonnull
public static KeyRingBuilder buildKeyRing() {
return new KeyRingBuilder();
}
@ -57,6 +59,7 @@ public final class PGPainless {
* Read an existing OpenPGP key ring.
* @return builder
*/
@Nonnull
public static KeyRingReader readKeyRing() {
return new KeyRingReader();
}
@ -67,6 +70,7 @@ public final class PGPainless {
* @param secretKey secret key
* @return public key certificate
*/
@Nonnull
public static PGPPublicKeyRing extractCertificate(@Nonnull PGPSecretKeyRing secretKey) {
return KeyRingUtils.publicKeyRingFrom(secretKey);
}
@ -79,6 +83,7 @@ public final class PGPainless {
* @return merged certificate
* @throws PGPException in case of an error
*/
@Nonnull
public static PGPPublicKeyRing mergeCertificate(
@Nonnull PGPPublicKeyRing originalCopy,
@Nonnull PGPPublicKeyRing updatedCopy)
@ -94,6 +99,7 @@ public final class PGPainless {
*
* @throws IOException in case of an error in the {@link ArmoredOutputStream}
*/
@Nonnull
public static String asciiArmor(@Nonnull PGPKeyRing key)
throws IOException {
if (key instanceof PGPSecretKeyRing) {
@ -111,6 +117,7 @@ public final class PGPainless {
*
* @throws IOException in case of an error in the {@link ArmoredOutputStream}
*/
@Nonnull
public static String asciiArmor(@Nonnull PGPSignature signature)
throws IOException {
return ArmorUtils.toAsciiArmoredString(signature);
@ -136,6 +143,7 @@ public final class PGPainless {
*
* @return builder
*/
@Nonnull
public static EncryptionBuilder encryptAndOrSign() {
return new EncryptionBuilder();
}
@ -145,6 +153,7 @@ public final class PGPainless {
*
* @return builder
*/
@Nonnull
public static DecryptionBuilder decryptAndOrVerify() {
return new DecryptionBuilder();
}
@ -158,8 +167,9 @@ public final class PGPainless {
* @param secretKeys secret key ring
* @return builder
*/
public static SecretKeyRingEditorInterface modifyKeyRing(PGPSecretKeyRing secretKeys) {
return modifyKeyRing(secretKeys, null);
@Nonnull
public static SecretKeyRingEditorInterface modifyKeyRing(@Nonnull PGPSecretKeyRing secretKeys) {
return modifyKeyRing(secretKeys, new Date());
}
/**
@ -172,7 +182,9 @@ public final class PGPainless {
* @param referenceTime reference time used as signature creation date
* @return builder
*/
public static SecretKeyRingEditorInterface modifyKeyRing(PGPSecretKeyRing secretKeys, Date referenceTime) {
@Nonnull
public static SecretKeyRingEditorInterface modifyKeyRing(@Nonnull PGPSecretKeyRing secretKeys,
@Nonnull Date referenceTime) {
return new SecretKeyRingEditor(secretKeys, referenceTime);
}
@ -186,7 +198,8 @@ public final class PGPainless {
* @param keyRing key ring
* @return access object
*/
public static KeyRingInfo inspectKeyRing(PGPKeyRing keyRing) {
@Nonnull
public static KeyRingInfo inspectKeyRing(@Nonnull PGPKeyRing keyRing) {
return new KeyRingInfo(keyRing);
}
@ -198,7 +211,8 @@ public final class PGPainless {
* @param referenceTime date of inspection
* @return access object
*/
public static KeyRingInfo inspectKeyRing(PGPKeyRing keyRing, Date referenceTime) {
@Nonnull
public static KeyRingInfo inspectKeyRing(@Nonnull PGPKeyRing keyRing, @Nonnull Date referenceTime) {
return new KeyRingInfo(keyRing, referenceTime);
}
@ -207,6 +221,7 @@ public final class PGPainless {
*
* @return policy
*/
@Nonnull
public static Policy getPolicy() {
return Policy.getInstance();
}
@ -216,6 +231,7 @@ public final class PGPainless {
*
* @return builder
*/
@Nonnull
public static CertifyCertificate certify() {
return new CertifyCertificate();
}

View file

@ -359,7 +359,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
PGPCompressedData compressedData = packetInputStream.readCompressedData();
// Extract Metadata
MessageMetadata.CompressedData compressionLayer = new MessageMetadata.CompressedData(
CompressionAlgorithm.fromId(compressedData.getAlgorithm()),
CompressionAlgorithm.requireFromId(compressedData.getAlgorithm()),
metadata.depth + 1);
LOGGER.debug("Compressed Data Packet (" + compressionLayer.algorithm + ") at depth " + metadata.depth + " encountered");

View file

@ -44,10 +44,15 @@ class BcPGPHashContextContentSignerBuilder extends PGPHashContextContentSignerBu
BcPGPHashContextContentSignerBuilder(MessageDigest messageDigest) {
this.messageDigest = messageDigest;
this.hashAlgorithm = HashAlgorithm.fromName(messageDigest.getAlgorithm());
this.hashAlgorithm = requireFromName(messageDigest.getAlgorithm());
}
private static HashAlgorithm requireFromName(String digestName) {
HashAlgorithm hashAlgorithm = HashAlgorithm.fromName(digestName);
if (hashAlgorithm == null) {
throw new IllegalArgumentException("Cannot recognize OpenPGP Hash Algorithm: " + messageDigest.getAlgorithm());
throw new IllegalArgumentException("Cannot recognize OpenPGP Hash Algorithm: " + digestName);
}
return hashAlgorithm;
}
@Override

View file

@ -10,6 +10,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.PGPException;
@ -46,7 +47,9 @@ public final class SigningOptions {
private final boolean detached;
private final HashAlgorithm hashAlgorithm;
private SigningMethod(PGPSignatureGenerator signatureGenerator, boolean detached, HashAlgorithm hashAlgorithm) {
private SigningMethod(@Nonnull PGPSignatureGenerator signatureGenerator,
boolean detached,
@Nonnull HashAlgorithm hashAlgorithm) {
this.signatureGenerator = signatureGenerator;
this.detached = detached;
this.hashAlgorithm = hashAlgorithm;
@ -60,7 +63,8 @@ public final class SigningOptions {
* @param hashAlgorithm hash algorithm used to generate the signature
* @return inline signing method
*/
public static SigningMethod inlineSignature(PGPSignatureGenerator signatureGenerator, HashAlgorithm hashAlgorithm) {
public static SigningMethod inlineSignature(@Nonnull PGPSignatureGenerator signatureGenerator,
@Nonnull HashAlgorithm hashAlgorithm) {
return new SigningMethod(signatureGenerator, false, hashAlgorithm);
}
@ -73,7 +77,8 @@ public final class SigningOptions {
* @param hashAlgorithm hash algorithm used to generate the signature
* @return detached signing method
*/
public static SigningMethod detachedSignature(PGPSignatureGenerator signatureGenerator, HashAlgorithm hashAlgorithm) {
public static SigningMethod detachedSignature(@Nonnull PGPSignatureGenerator signatureGenerator,
@Nonnull HashAlgorithm hashAlgorithm) {
return new SigningMethod(signatureGenerator, true, hashAlgorithm);
}
@ -93,6 +98,7 @@ public final class SigningOptions {
private final Map<SubkeyIdentifier, SigningMethod> signingMethods = new HashMap<>();
private HashAlgorithm hashAlgorithmOverride;
@Nonnull
public static SigningOptions get() {
return new SigningOptions();
}
@ -107,8 +113,9 @@ public final class SigningOptions {
* @throws KeyException if something is wrong with the key
* @throws PGPException if the key cannot be unlocked or a signing method cannot be created
*/
public SigningOptions addSignature(SecretKeyRingProtector signingKeyProtector,
PGPSecretKeyRing signingKey)
@Nonnull
public SigningOptions addSignature(@Nonnull SecretKeyRingProtector signingKeyProtector,
@Nonnull PGPSecretKeyRing signingKey)
throws PGPException {
return addInlineSignature(signingKeyProtector, signingKey, DocumentSignatureType.BINARY_DOCUMENT);
}
@ -124,9 +131,10 @@ public final class SigningOptions {
* @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<PGPSecretKeyRing> signingKeys,
DocumentSignatureType signatureType)
@Nonnull
public SigningOptions addInlineSignatures(@Nonnull SecretKeyRingProtector secrectKeyDecryptor,
@Nonnull Iterable<PGPSecretKeyRing> signingKeys,
@Nonnull DocumentSignatureType signatureType)
throws KeyException, PGPException {
for (PGPSecretKeyRing signingKey : signingKeys) {
addInlineSignature(secrectKeyDecryptor, signingKey, signatureType);
@ -147,9 +155,10 @@ public final class SigningOptions {
* @throws KeyException if something is wrong with the key
* @throws PGPException if the key cannot be unlocked or the signing method cannot be created
*/
public SigningOptions addInlineSignature(SecretKeyRingProtector secretKeyDecryptor,
PGPSecretKeyRing secretKey,
DocumentSignatureType signatureType)
@Nonnull
public SigningOptions addInlineSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
@Nonnull DocumentSignatureType signatureType)
throws KeyException, PGPException {
return addInlineSignature(secretKeyDecryptor, secretKey, null, signatureType);
}
@ -170,10 +179,11 @@ public final class SigningOptions {
* @throws KeyException if something is wrong with the key
* @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)
@Nonnull
public SigningOptions addInlineSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
@Nullable CharSequence userId,
@Nonnull DocumentSignatureType signatureType)
throws KeyException, PGPException {
return addInlineSignature(secretKeyDecryptor, secretKey, userId, signatureType, null);
}
@ -195,17 +205,18 @@ public final class SigningOptions {
* @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,
@Nonnull
public SigningOptions addInlineSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
@Nullable CharSequence userId,
@Nonnull DocumentSignatureType signatureType,
@Nullable BaseSignatureSubpackets.Callback subpacketsCallback)
throws KeyException, PGPException {
KeyRingInfo keyRingInfo = new KeyRingInfo(secretKey, new Date());
if (userId != null && !keyRingInfo.isUserIdValid(userId)) {
throw new KeyException.UnboundUserIdException(
OpenPgpFingerprint.of(secretKey),
userId,
userId.toString(),
keyRingInfo.getLatestUserIdCertification(userId),
keyRingInfo.getUserIdRevocation(userId)
);
@ -242,9 +253,10 @@ public final class SigningOptions {
* @throws KeyException if something is wrong with any of the keys
* @throws PGPException if any of the keys cannot be validated or unlocked, or if any signing method cannot be created
*/
public SigningOptions addDetachedSignatures(SecretKeyRingProtector secretKeyDecryptor,
Iterable<PGPSecretKeyRing> signingKeys,
DocumentSignatureType signatureType)
@Nonnull
public SigningOptions addDetachedSignatures(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull Iterable<PGPSecretKeyRing> signingKeys,
@Nonnull DocumentSignatureType signatureType)
throws PGPException {
for (PGPSecretKeyRing signingKey : signingKeys) {
addDetachedSignature(secretKeyDecryptor, signingKey, signatureType);
@ -263,8 +275,9 @@ public final class SigningOptions {
* @throws KeyException if something is wrong with the key
* @throws PGPException if the key cannot be validated or unlocked, or if no signature method can be created
*/
public SigningOptions addDetachedSignature(SecretKeyRingProtector secretKeyDecryptor,
PGPSecretKeyRing signingKey)
@Nonnull
public SigningOptions addDetachedSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing signingKey)
throws PGPException {
return addDetachedSignature(secretKeyDecryptor, signingKey, DocumentSignatureType.BINARY_DOCUMENT);
}
@ -283,9 +296,10 @@ public final class SigningOptions {
* @throws KeyException if something is wrong with the key
* @throws PGPException if the key cannot be validated or unlocked, or if no signature method can be created
*/
public SigningOptions addDetachedSignature(SecretKeyRingProtector secretKeyDecryptor,
PGPSecretKeyRing secretKey,
DocumentSignatureType signatureType)
@Nonnull
public SigningOptions addDetachedSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
@Nonnull DocumentSignatureType signatureType)
throws PGPException {
return addDetachedSignature(secretKeyDecryptor, secretKey, null, signatureType);
}
@ -307,10 +321,11 @@ public final class SigningOptions {
* @throws KeyException if something is wrong with the key
* @throws PGPException if the key cannot be validated or unlocked, or if no signature method can be created
*/
public SigningOptions addDetachedSignature(SecretKeyRingProtector secretKeyDecryptor,
PGPSecretKeyRing secretKey,
String userId,
DocumentSignatureType signatureType)
@Nonnull
public SigningOptions addDetachedSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
@Nullable CharSequence userId,
@Nonnull DocumentSignatureType signatureType)
throws PGPException {
return addDetachedSignature(secretKeyDecryptor, secretKey, userId, signatureType, null);
}
@ -333,17 +348,18 @@ public final class SigningOptions {
* @throws KeyException if something is wrong with the key
* @throws PGPException if the key cannot be validated or unlocked, or if no signature method can be created
*/
public SigningOptions addDetachedSignature(SecretKeyRingProtector secretKeyDecryptor,
PGPSecretKeyRing secretKey,
String userId,
DocumentSignatureType signatureType,
@Nonnull
public SigningOptions addDetachedSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
@Nullable CharSequence userId,
@Nonnull DocumentSignatureType signatureType,
@Nullable BaseSignatureSubpackets.Callback subpacketCallback)
throws PGPException {
KeyRingInfo keyRingInfo = new KeyRingInfo(secretKey, new Date());
if (userId != null && !keyRingInfo.isUserIdValid(userId)) {
throw new KeyException.UnboundUserIdException(
OpenPgpFingerprint.of(secretKey),
userId,
userId.toString(),
keyRingInfo.getLatestUserIdCertification(userId),
keyRingInfo.getUserIdRevocation(userId)
);
@ -369,11 +385,11 @@ public final class SigningOptions {
return this;
}
private void addSigningMethod(PGPSecretKeyRing secretKey,
PGPPrivateKey signingSubkey,
private void addSigningMethod(@Nonnull PGPSecretKeyRing secretKey,
@Nonnull PGPPrivateKey signingSubkey,
@Nullable BaseSignatureSubpackets.Callback subpacketCallback,
HashAlgorithm hashAlgorithm,
DocumentSignatureType signatureType,
@Nonnull HashAlgorithm hashAlgorithm,
@Nonnull DocumentSignatureType signatureType,
boolean detached)
throws PGPException {
SubkeyIdentifier signingKeyIdentifier = new SubkeyIdentifier(secretKey, signingSubkey.getKeyID());
@ -416,7 +432,9 @@ public final class SigningOptions {
* @param policy policy
* @return selected hash algorithm
*/
private HashAlgorithm negotiateHashAlgorithm(Set<HashAlgorithm> preferences, Policy policy) {
@Nonnull
private HashAlgorithm negotiateHashAlgorithm(@Nonnull Set<HashAlgorithm> preferences,
@Nonnull Policy policy) {
if (hashAlgorithmOverride != null) {
return hashAlgorithmOverride;
}
@ -425,9 +443,10 @@ public final class SigningOptions {
.negotiateHashAlgorithm(preferences);
}
private PGPSignatureGenerator createSignatureGenerator(PGPPrivateKey privateKey,
HashAlgorithm hashAlgorithm,
DocumentSignatureType signatureType)
@Nonnull
private PGPSignatureGenerator createSignatureGenerator(@Nonnull PGPPrivateKey privateKey,
@Nonnull HashAlgorithm hashAlgorithm,
@Nonnull DocumentSignatureType signatureType)
throws PGPException {
int publicKeyAlgorithm = privateKey.getPublicKeyPacket().getAlgorithm();
PGPContentSignerBuilder signerBuilder = ImplementationFactory.getInstance()
@ -444,6 +463,7 @@ public final class SigningOptions {
*
* @return signing methods
*/
@Nonnull
Map<SubkeyIdentifier, SigningMethod> getSigningMethods() {
return Collections.unmodifiableMap(signingMethods);
}
@ -459,7 +479,8 @@ public final class SigningOptions {
* @param hashAlgorithmOverride override hash algorithm
* @return this
*/
public SigningOptions overrideHashAlgorithm(HashAlgorithm hashAlgorithmOverride) {
@Nonnull
public SigningOptions overrideHashAlgorithm(@Nonnull HashAlgorithm hashAlgorithmOverride) {
this.hashAlgorithmOverride = hashAlgorithmOverride;
return this;
}
@ -469,6 +490,7 @@ public final class SigningOptions {
*
* @return hash algorithm override
*/
@Nullable
public HashAlgorithm getHashAlgorithmOverride() {
return hashAlgorithmOverride;
}

View file

@ -20,7 +20,7 @@ public abstract class KeyAccessor {
protected final KeyRingInfo info;
protected final SubkeyIdentifier key;
KeyAccessor(KeyRingInfo info, SubkeyIdentifier key) {
KeyAccessor(@Nonnull KeyRingInfo info, @Nonnull SubkeyIdentifier key) {
this.info = info;
this.key = key;
}
@ -34,13 +34,15 @@ public abstract class KeyAccessor {
*
* @return signature
*/
public abstract @Nonnull PGPSignature getSignatureWithPreferences();
@Nonnull
public abstract PGPSignature getSignatureWithPreferences();
/**
* Return preferred symmetric key encryption algorithms.
*
* @return preferred symmetric algorithms
*/
@Nonnull
public Set<SymmetricKeyAlgorithm> getPreferredSymmetricKeyAlgorithms() {
return SignatureSubpacketsUtil.parsePreferredSymmetricKeyAlgorithms(getSignatureWithPreferences());
}
@ -50,6 +52,7 @@ public abstract class KeyAccessor {
*
* @return preferred hash algorithms
*/
@Nonnull
public Set<HashAlgorithm> getPreferredHashAlgorithms() {
return SignatureSubpacketsUtil.parsePreferredHashAlgorithms(getSignatureWithPreferences());
}
@ -59,6 +62,7 @@ public abstract class KeyAccessor {
*
* @return preferred compression algorithms
*/
@Nonnull
public Set<CompressionAlgorithm> getPreferredCompressionAlgorithms() {
return SignatureSubpacketsUtil.parsePreferredCompressionAlgorithms(getSignatureWithPreferences());
}
@ -78,13 +82,16 @@ public abstract class KeyAccessor {
* @param key id of the subkey
* @param userId user-id
*/
public ViaUserId(KeyRingInfo info, SubkeyIdentifier key, String userId) {
public ViaUserId(@Nonnull KeyRingInfo info,
@Nonnull SubkeyIdentifier key,
@Nonnull String userId) {
super(info, key);
this.userId = userId;
}
@Override
public @Nonnull PGPSignature getSignatureWithPreferences() {
@Nonnull
public PGPSignature getSignatureWithPreferences() {
PGPSignature signature = info.getLatestUserIdCertification(userId);
if (signature != null) {
return signature;
@ -104,19 +111,26 @@ public abstract class KeyAccessor {
* @param info info about the key at a given date
* @param key key-id
*/
public ViaKeyId(KeyRingInfo info, SubkeyIdentifier key) {
public ViaKeyId(@Nonnull KeyRingInfo info,
@Nonnull SubkeyIdentifier key) {
super(info, key);
}
@Override
public @Nonnull PGPSignature getSignatureWithPreferences() {
@Nonnull
public PGPSignature getSignatureWithPreferences() {
String primaryUserId = info.getPrimaryUserId();
// If the key is located by Key ID, the algorithm of the primary User ID of the key provides the
// preferred symmetric algorithm.
PGPSignature signature = info.getLatestUserIdCertification(primaryUserId);
PGPSignature signature = null;
if (primaryUserId != null) {
signature = info.getLatestUserIdCertification(primaryUserId);
}
if (signature == null) {
signature = info.getLatestDirectKeySelfSignature();
}
if (signature == null) {
throw new IllegalStateException("No valid signature found.");
}
@ -126,22 +140,27 @@ public abstract class KeyAccessor {
public static class SubKey extends KeyAccessor {
public SubKey(KeyRingInfo info, SubkeyIdentifier key) {
public SubKey(@Nonnull KeyRingInfo info,
@Nonnull SubkeyIdentifier key) {
super(info, key);
}
@Override
public @Nonnull PGPSignature getSignatureWithPreferences() {
@Nonnull
public PGPSignature getSignatureWithPreferences() {
PGPSignature signature;
if (key.getPrimaryKeyId() == key.getSubkeyId()) {
signature = info.getLatestDirectKeySelfSignature();
if (signature == null) {
if (signature == null && info.getPrimaryUserId() != null) {
signature = info.getLatestUserIdCertification(info.getPrimaryUserId());
}
} else {
signature = info.getCurrentSubkeyBindingSignature(key.getSubkeyId());
}
if (signature == null) {
throw new IllegalStateException("No valid signature found.");
}
return signature;
}
}

View file

@ -74,7 +74,9 @@ public class KeyRingInfo {
* @param signature signature
* @return info of key ring at signature creation time
*/
public static KeyRingInfo evaluateForSignature(PGPKeyRing keyRing, PGPSignature signature) {
@Nonnull
public static KeyRingInfo evaluateForSignature(@Nonnull PGPKeyRing keyRing,
@Nonnull PGPSignature signature) {
return new KeyRingInfo(keyRing, signature.getCreationTime());
}
@ -83,7 +85,7 @@ public class KeyRingInfo {
*
* @param keys key ring
*/
public KeyRingInfo(PGPKeyRing keys) {
public KeyRingInfo(@Nonnull PGPKeyRing keys) {
this(keys, new Date());
}
@ -93,7 +95,8 @@ public class KeyRingInfo {
* @param keys key ring
* @param referenceDate date of validation
*/
public KeyRingInfo(PGPKeyRing keys, Date referenceDate) {
public KeyRingInfo(@Nonnull PGPKeyRing keys,
@Nonnull Date referenceDate) {
this(keys, PGPainless.getPolicy(), referenceDate);
}
@ -104,14 +107,17 @@ public class KeyRingInfo {
* @param policy policy
* @param referenceDate validation date
*/
public KeyRingInfo(PGPKeyRing keys, Policy policy, Date referenceDate) {
this.referenceDate = referenceDate != null ? referenceDate : new Date();
public KeyRingInfo(@Nonnull PGPKeyRing keys,
@Nonnull Policy policy,
@Nonnull Date referenceDate) {
this.referenceDate = referenceDate;
this.keys = keys;
this.signatures = new Signatures(keys, this.referenceDate, policy);
this.primaryUserId = findPrimaryUserId();
this.revocationState = findRevocationState();
}
@Nonnull
private RevocationState findRevocationState() {
PGPSignature revocation = signatures.primaryKeyRevocation;
if (revocation != null) {
@ -126,6 +132,7 @@ public class KeyRingInfo {
*
* @return public key
*/
@Nonnull
public PGPPublicKey getPublicKey() {
return keys.getPublicKey();
}
@ -136,7 +143,8 @@ public class KeyRingInfo {
* @param fingerprint fingerprint
* @return public key or null
*/
public @Nullable PGPPublicKey getPublicKey(OpenPgpFingerprint fingerprint) {
@Nullable
public PGPPublicKey getPublicKey(@Nonnull OpenPgpFingerprint fingerprint) {
return getPublicKey(fingerprint.getKeyId());
}
@ -146,7 +154,8 @@ public class KeyRingInfo {
* @param keyId key id
* @return public key or null
*/
public @Nullable PGPPublicKey getPublicKey(long keyId) {
@Nullable
public PGPPublicKey getPublicKey(long keyId) {
return getPublicKey(keys, keyId);
}
@ -157,7 +166,8 @@ public class KeyRingInfo {
* @param keyId key id
* @return public key or null
*/
public static @Nullable PGPPublicKey getPublicKey(PGPKeyRing keyRing, long keyId) {
@Nullable
public static PGPPublicKey getPublicKey(@Nonnull PGPKeyRing keyRing, long keyId) {
return keyRing.getPublicKey(keyId);
}
@ -210,6 +220,7 @@ public class KeyRingInfo {
*
* @return list of public keys
*/
@Nonnull
public List<PGPPublicKey> getPublicKeys() {
Iterator<PGPPublicKey> iterator = keys.getPublicKeys();
List<PGPPublicKey> list = iteratorToList(iterator);
@ -221,7 +232,8 @@ public class KeyRingInfo {
*
* @return primary secret key or null if the key ring is public
*/
public @Nullable PGPSecretKey getSecretKey() {
@Nullable
public PGPSecretKey getSecretKey() {
if (keys instanceof PGPSecretKeyRing) {
PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) keys;
return secretKeys.getSecretKey();
@ -235,7 +247,8 @@ public class KeyRingInfo {
* @param fingerprint fingerprint
* @return secret key or null
*/
public @Nullable PGPSecretKey getSecretKey(OpenPgpFingerprint fingerprint) {
@Nullable
public PGPSecretKey getSecretKey(@Nonnull OpenPgpFingerprint fingerprint) {
return getSecretKey(fingerprint.getKeyId());
}
@ -245,7 +258,8 @@ public class KeyRingInfo {
* @param keyId key id
* @return secret key or null
*/
public @Nullable PGPSecretKey getSecretKey(long keyId) {
@Nullable
public PGPSecretKey getSecretKey(long keyId) {
if (keys instanceof PGPSecretKeyRing) {
return ((PGPSecretKeyRing) keys).getSecretKey(keyId);
}
@ -259,6 +273,7 @@ public class KeyRingInfo {
*
* @return list of secret keys
*/
@Nonnull
public List<PGPSecretKey> getSecretKeys() {
if (keys instanceof PGPSecretKeyRing) {
PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) keys;
@ -282,11 +297,13 @@ public class KeyRingInfo {
*
* @return fingerprint
*/
@Nonnull
public OpenPgpFingerprint getFingerprint() {
return OpenPgpFingerprint.of(getPublicKey());
}
public @Nullable String getPrimaryUserId() {
@Nullable
public String getPrimaryUserId() {
return primaryUserId;
}
@ -298,6 +315,7 @@ public class KeyRingInfo {
*
* @return primary user-id or null
*/
@Nullable
private String findPrimaryUserId() {
String primaryUserId = null;
Date currentModificationDate = null;
@ -342,10 +360,10 @@ public class KeyRingInfo {
*
* @return list of user-ids
*/
@Nonnull
public List<String> getUserIds() {
Iterator<String> iterator = getPublicKey().getUserIDs();
List<String> userIds = iteratorToList(iterator);
return userIds;
return iteratorToList(iterator);
}
/**
@ -353,6 +371,7 @@ public class KeyRingInfo {
*
* @return valid user-ids
*/
@Nonnull
public List<String> getValidUserIds() {
List<String> valid = new ArrayList<>();
List<String> userIds = getUserIds();
@ -369,6 +388,7 @@ public class KeyRingInfo {
*
* @return bound user-ids
*/
@Nonnull
public List<String> getValidAndExpiredUserIds() {
List<String> probablyExpired = new ArrayList<>();
List<String> userIds = getUserIds();
@ -407,21 +427,25 @@ public class KeyRingInfo {
* @param userId user-id
* @return true if user-id is valid
*/
public boolean isUserIdValid(String userId) {
public boolean isUserIdValid(@Nonnull CharSequence userId) {
if (primaryUserId == null) {
// No primary userID? No userID at all!
return false;
}
if (!userId.equals(primaryUserId)) {
if (!isUserIdBound(primaryUserId)) {
// primary user-id not valid
// primary user-id not valid? UserID not valid!
return false;
}
}
return isUserIdBound(userId);
}
private boolean isUserIdBound(String userId) {
PGPSignature certification = signatures.userIdCertifications.get(userId);
PGPSignature revocation = signatures.userIdRevocations.get(userId);
private boolean isUserIdBound(@Nonnull CharSequence userId) {
String userIdString = userId.toString();
PGPSignature certification = signatures.userIdCertifications.get(userIdString);
PGPSignature revocation = signatures.userIdRevocations.get(userIdString);
if (certification == null) {
return false;
@ -453,6 +477,7 @@ public class KeyRingInfo {
*
* @return email addresses
*/
@Nonnull
public List<String> getEmailAddresses() {
List<String> userIds = getUserIds();
List<String> emails = new ArrayList<>();
@ -477,7 +502,8 @@ public class KeyRingInfo {
*
* @return latest direct key self-signature or null
*/
public @Nullable PGPSignature getLatestDirectKeySelfSignature() {
@Nullable
public PGPSignature getLatestDirectKeySelfSignature() {
return signatures.primaryKeySelfSignature;
}
@ -486,7 +512,8 @@ public class KeyRingInfo {
*
* @return revocation or null
*/
public @Nullable PGPSignature getRevocationSelfSignature() {
@Nullable
public PGPSignature getRevocationSelfSignature() {
return signatures.primaryKeyRevocation;
}
@ -496,8 +523,9 @@ public class KeyRingInfo {
* @param userId user-id
* @return certification signature or null
*/
public @Nullable PGPSignature getLatestUserIdCertification(String userId) {
return signatures.userIdCertifications.get(userId);
@Nullable
public PGPSignature getLatestUserIdCertification(@Nonnull CharSequence userId) {
return signatures.userIdCertifications.get(userId.toString());
}
/**
@ -506,8 +534,9 @@ public class KeyRingInfo {
* @param userId user-id
* @return revocation or null
*/
public @Nullable PGPSignature getUserIdRevocation(String userId) {
return signatures.userIdRevocations.get(userId);
@Nullable
public PGPSignature getUserIdRevocation(@Nonnull CharSequence userId) {
return signatures.userIdRevocations.get(userId.toString());
}
/**
@ -516,7 +545,8 @@ public class KeyRingInfo {
* @param keyId subkey id
* @return subkey binding signature or null
*/
public @Nullable PGPSignature getCurrentSubkeyBindingSignature(long keyId) {
@Nullable
public PGPSignature getCurrentSubkeyBindingSignature(long keyId) {
return signatures.subkeyBindings.get(keyId);
}
@ -526,7 +556,8 @@ public class KeyRingInfo {
* @param keyId subkey id
* @return subkey binding revocation or null
*/
public @Nullable PGPSignature getSubkeyRevocationSignature(long keyId) {
@Nullable
public PGPSignature getSubkeyRevocationSignature(long keyId) {
return signatures.subkeyRevocations.get(keyId);
}
@ -535,7 +566,8 @@ public class KeyRingInfo {
* @param keyId key-id
* @return list of key flags
*/
public @Nonnull List<KeyFlag> getKeyFlagsOf(long keyId) {
@Nonnull
public List<KeyFlag> getKeyFlagsOf(long keyId) {
// key is primary key
if (getPublicKey().getKeyID() == keyId) {
@ -575,7 +607,8 @@ public class KeyRingInfo {
* @param userId user-id
* @return key flags
*/
public @Nonnull List<KeyFlag> getKeyFlagsOf(String userId) {
@Nonnull
public List<KeyFlag> getKeyFlagsOf(String userId) {
if (!isUserIdValid(userId)) {
return Collections.emptyList();
}
@ -607,6 +640,7 @@ public class KeyRingInfo {
*
* @return creation date
*/
@Nonnull
public Date getCreationDate() {
return getPublicKey().getCreationTime();
}
@ -617,7 +651,8 @@ public class KeyRingInfo {
*
* @return last modification date.
*/
public @Nonnull Date getLastModified() {
@Nonnull
public Date getLastModified() {
PGPSignature mostRecent = getMostRecentSignature();
if (mostRecent == null) {
// No sigs found. Return public key creation date instead.
@ -631,7 +666,8 @@ public class KeyRingInfo {
*
* @return latest key creation time
*/
public @Nonnull Date getLatestKeyCreationDate() {
@Nonnull
public Date getLatestKeyCreationDate() {
Date latestCreation = null;
for (PGPPublicKey key : getPublicKeys()) {
if (!isKeyValidlyBound(key.getKeyID())) {
@ -648,7 +684,8 @@ public class KeyRingInfo {
return latestCreation;
}
private @Nullable PGPSignature getMostRecentSignature() {
@Nullable
private PGPSignature getMostRecentSignature() {
Set<PGPSignature> allSignatures = new HashSet<>();
PGPSignature mostRecentSelfSignature = getLatestDirectKeySelfSignature();
PGPSignature revocationSelfSignature = getRevocationSelfSignature();
@ -668,6 +705,7 @@ public class KeyRingInfo {
return mostRecent;
}
@Nonnull
public RevocationState getRevocationState() {
return revocationState;
}
@ -677,7 +715,8 @@ public class KeyRingInfo {
*
* @return revocation date or null
*/
public @Nullable Date getRevocationDate() {
@Nullable
public Date getRevocationDate() {
return getRevocationState().isSoftRevocation() ? getRevocationState().getDate() : null;
}
@ -686,7 +725,8 @@ public class KeyRingInfo {
*
* @return expiration date
*/
public @Nullable Date getPrimaryKeyExpirationDate() {
@Nullable
public Date getPrimaryKeyExpirationDate() {
PGPSignature directKeySig = getLatestDirectKeySelfSignature();
Date directKeyExpirationDate = null;
if (directKeySig != null) {
@ -722,6 +762,7 @@ public class KeyRingInfo {
return userIdExpirationDate;
}
@Nullable
public String getPossiblyExpiredPrimaryUserId() {
String validPrimaryUserId = getPrimaryUserId();
if (validPrimaryUserId != null) {
@ -760,7 +801,8 @@ public class KeyRingInfo {
* @param fingerprint subkey fingerprint
* @return expiration date or null
*/
public @Nullable Date getSubkeyExpirationDate(OpenPgpFingerprint fingerprint) {
@Nullable
public Date getSubkeyExpirationDate(OpenPgpFingerprint fingerprint) {
if (getPublicKey().getKeyID() == fingerprint.getKeyId()) {
return getPrimaryKeyExpirationDate();
}
@ -788,6 +830,7 @@ public class KeyRingInfo {
* {@link KeyFlag#ENCRYPT_COMMS}/{@link KeyFlag#ENCRYPT_STORAGE}.
* @return latest date on which the key ring can be used for the given use case, or null if it can be used indefinitely.
*/
@Nullable
public Date getExpirationDateForUse(KeyFlag use) {
if (use == KeyFlag.SPLIT || use == KeyFlag.SHARED) {
throw new IllegalArgumentException("SPLIT and SHARED are not uses, but properties.");
@ -814,20 +857,18 @@ public class KeyRingInfo {
}
if (nonExpiringSubkeys.isEmpty()) {
if (latestSubkeyExpirationDate != null) {
if (primaryExpiration == null) {
return latestSubkeyExpirationDate;
}
if (latestSubkeyExpirationDate.before(primaryExpiration)) {
return latestSubkeyExpirationDate;
}
if (primaryExpiration == null) {
return latestSubkeyExpirationDate;
}
if (latestSubkeyExpirationDate.before(primaryExpiration)) {
return latestSubkeyExpirationDate;
}
}
return primaryExpiration;
}
public boolean isHardRevoked(String userId) {
PGPSignature revocation = signatures.userIdRevocations.get(userId);
public boolean isHardRevoked(@Nonnull CharSequence userId) {
PGPSignature revocation = signatures.userIdRevocations.get(userId.toString());
if (revocation == null) {
return false;
}
@ -907,7 +948,8 @@ public class KeyRingInfo {
* @param purpose purpose (encrypt data at rest / communications)
* @return encryption subkeys
*/
public @Nonnull List<PGPPublicKey> getEncryptionSubkeys(EncryptionPurpose purpose) {
@Nonnull
public List<PGPPublicKey> getEncryptionSubkeys(@Nonnull EncryptionPurpose purpose) {
Date primaryExpiration = getPrimaryKeyExpirationDate();
if (primaryExpiration != null && primaryExpiration.before(referenceDate)) {
LOGGER.debug("Certificate is expired: Primary key is expired on " + DateUtil.formatUTCDate(primaryExpiration));
@ -966,7 +1008,8 @@ public class KeyRingInfo {
*
* @return decryption keys
*/
public @Nonnull List<PGPPublicKey> getDecryptionSubkeys() {
@Nonnull
public List<PGPPublicKey> getDecryptionSubkeys() {
Iterator<PGPPublicKey> subkeys = keys.getPublicKeys();
List<PGPPublicKey> decryptionKeys = new ArrayList<>();
@ -999,7 +1042,8 @@ public class KeyRingInfo {
* @param flag flag
* @return keys with flag
*/
public List<PGPPublicKey> getKeysWithKeyFlag(KeyFlag flag) {
@Nonnull
public List<PGPPublicKey> getKeysWithKeyFlag(@Nonnull KeyFlag flag) {
List<PGPPublicKey> keysWithFlag = new ArrayList<>();
for (PGPPublicKey key : getPublicKeys()) {
List<KeyFlag> keyFlags = getKeyFlagsOf(key.getKeyID());
@ -1021,11 +1065,13 @@ public class KeyRingInfo {
* @param purpose encryption purpose
* @return encryption subkeys
*/
public @Nonnull List<PGPPublicKey> getEncryptionSubkeys(String userId, EncryptionPurpose purpose) {
@Nonnull
public List<PGPPublicKey> getEncryptionSubkeys(@Nullable CharSequence userId,
@Nonnull EncryptionPurpose purpose) {
if (userId != null && !isUserIdValid(userId)) {
throw new KeyException.UnboundUserIdException(
OpenPgpFingerprint.of(keys),
userId,
userId.toString(),
getLatestUserIdCertification(userId),
getUserIdRevocation(userId)
);
@ -1039,7 +1085,8 @@ public class KeyRingInfo {
*
* @return signing keys
*/
public @Nonnull List<PGPPublicKey> getSigningSubkeys() {
@Nonnull
public List<PGPPublicKey> getSigningSubkeys() {
Iterator<PGPPublicKey> subkeys = keys.getPublicKeys();
List<PGPPublicKey> signingKeys = new ArrayList<>();
while (subkeys.hasNext()) {
@ -1057,39 +1104,48 @@ public class KeyRingInfo {
return signingKeys;
}
@Nonnull
public Set<HashAlgorithm> getPreferredHashAlgorithms() {
return getPreferredHashAlgorithms(getPrimaryUserId());
}
public Set<HashAlgorithm> getPreferredHashAlgorithms(String userId) {
@Nonnull
public Set<HashAlgorithm> getPreferredHashAlgorithms(@Nullable CharSequence userId) {
return getKeyAccessor(userId, getKeyId()).getPreferredHashAlgorithms();
}
@Nonnull
public Set<HashAlgorithm> getPreferredHashAlgorithms(long keyId) {
return new KeyAccessor.SubKey(this, new SubkeyIdentifier(keys, keyId))
.getPreferredHashAlgorithms();
}
@Nonnull
public Set<SymmetricKeyAlgorithm> getPreferredSymmetricKeyAlgorithms() {
return getPreferredSymmetricKeyAlgorithms(getPrimaryUserId());
}
public Set<SymmetricKeyAlgorithm> getPreferredSymmetricKeyAlgorithms(String userId) {
@Nonnull
public Set<SymmetricKeyAlgorithm> getPreferredSymmetricKeyAlgorithms(@Nullable CharSequence userId) {
return getKeyAccessor(userId, getKeyId()).getPreferredSymmetricKeyAlgorithms();
}
@Nonnull
public Set<SymmetricKeyAlgorithm> getPreferredSymmetricKeyAlgorithms(long keyId) {
return new KeyAccessor.SubKey(this, new SubkeyIdentifier(keys, keyId)).getPreferredSymmetricKeyAlgorithms();
}
@Nonnull
public Set<CompressionAlgorithm> getPreferredCompressionAlgorithms() {
return getPreferredCompressionAlgorithms(getPrimaryUserId());
}
public Set<CompressionAlgorithm> getPreferredCompressionAlgorithms(String userId) {
@Nonnull
public Set<CompressionAlgorithm> getPreferredCompressionAlgorithms(@Nullable CharSequence userId) {
return getKeyAccessor(userId, getKeyId()).getPreferredCompressionAlgorithms();
}
@Nonnull
public Set<CompressionAlgorithm> getPreferredCompressionAlgorithms(long keyId) {
return new KeyAccessor.SubKey(this, new SubkeyIdentifier(keys, keyId)).getPreferredCompressionAlgorithms();
}
@ -1173,15 +1229,20 @@ public class KeyRingInfo {
return true;
}
private KeyAccessor getKeyAccessor(@Nullable String userId, long keyID) {
private KeyAccessor getKeyAccessor(@Nullable CharSequence userId, long keyID) {
if (getPublicKey(keyID) == null) {
throw new NoSuchElementException("No subkey with key id " + Long.toHexString(keyID) + " found on this key.");
}
if (userId != null && !getUserIds().contains(userId)) {
if (userId != null && !getUserIds().contains(userId.toString())) {
throw new NoSuchElementException("No user-id '" + userId + "' found on this key.");
}
return userId == null ? new KeyAccessor.ViaKeyId(this, new SubkeyIdentifier(keys, keyID))
: new KeyAccessor.ViaUserId(this, new SubkeyIdentifier(keys, keyID), userId);
if (userId != null) {
return new KeyAccessor.ViaUserId(this, new SubkeyIdentifier(keys, keyID), userId.toString());
} else {
return new KeyAccessor.ViaKeyId(this, new SubkeyIdentifier(keys, keyID));
}
}
public static class Signatures {
@ -1193,7 +1254,9 @@ public class KeyRingInfo {
private final Map<Long, PGPSignature> subkeyRevocations;
private final Map<Long, PGPSignature> subkeyBindings;
public Signatures(PGPKeyRing keyRing, Date referenceDate, Policy policy) {
public Signatures(@Nonnull PGPKeyRing keyRing,
@Nonnull Date referenceDate,
@Nonnull Policy policy) {
primaryKeyRevocation = SignaturePicker.pickCurrentRevocationSelfSignature(keyRing, policy, referenceDate);
primaryKeySelfSignature = SignaturePicker.pickLatestDirectKeySignature(keyRing, policy, referenceDate);
userIdRevocations = new HashMap<>();

View file

@ -72,14 +72,12 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
private PGPSecretKeyRing secretKeyRing;
private final Date referenceTime;
public SecretKeyRingEditor(PGPSecretKeyRing secretKeyRing) {
this(secretKeyRing, null);
public SecretKeyRingEditor(@Nonnull PGPSecretKeyRing secretKeyRing) {
this(secretKeyRing, new Date());
}
public SecretKeyRingEditor(PGPSecretKeyRing secretKeyRing, Date referenceTime) {
if (secretKeyRing == null) {
throw new NullPointerException("SecretKeyRing MUST NOT be null.");
}
public SecretKeyRingEditor(@Nonnull PGPSecretKeyRing secretKeyRing,
@Nonnull Date referenceTime) {
this.secretKeyRing = secretKeyRing;
this.referenceTime = referenceTime;
}

View file

@ -60,11 +60,6 @@ public class RevocationStateTest {
assertEquals("softRevoked (2022-08-03 18:26:35 UTC)", state.toString());
}
@Test
public void testSoftRevokedNullDateThrows() {
assertThrows(NullPointerException.class, () -> RevocationState.softRevoked(null));
}
@Test
public void orderTest() {
assertEquals(RevocationState.notRevoked(), RevocationState.notRevoked());

View file

@ -95,6 +95,7 @@ public class UserIdRevocationTest {
KeyRingInfo info = new KeyRingInfo(secretKeys);
PGPSignature signature = info.getUserIdRevocation("secondary@key.id");
assertNotNull(signature);
RevocationReason reason = (RevocationReason) signature.getHashedSubPackets()
.getSubpacket(SignatureSubpacketTags.REVOCATION_REASON);
assertNotNull(reason);

View file

@ -145,6 +145,7 @@ public class SignatureSubpacketsUtilTest {
PGPSignature signature = generator.generateCertification(secretKeys.getPublicKey());
Set<Feature> featureSet = SignatureSubpacketsUtil.parseFeatures(signature);
assertNotNull(featureSet);
assertEquals(2, featureSet.size());
assertTrue(featureSet.contains(Feature.MODIFICATION_DETECTION));
assertTrue(featureSet.contains(Feature.AEAD_ENCRYPTED_DATA));
@ -216,6 +217,7 @@ public class SignatureSubpacketsUtilTest {
PGPSignature signature = generator.generateCertification(secretKeys.getPublicKey());
RevocationKey revocationKey = SignatureSubpacketsUtil.getRevocationKey(signature);
assertNotNull(revocationKey);
assertArrayEquals(secretKeys.getPublicKey().getFingerprint(), revocationKey.getFingerprint());
assertEquals(secretKeys.getPublicKey().getAlgorithm(), revocationKey.getAlgorithm());
}
@ -277,6 +279,7 @@ public class SignatureSubpacketsUtilTest {
PGPSignature signature = generator.generateCertification(secretKeys.getPublicKey());
TrustSignature trustSignature = SignatureSubpacketsUtil.getTrustSignature(signature);
assertNotNull(trustSignature);
assertEquals(10, trustSignature.getDepth());
assertEquals(3, trustSignature.getTrustAmount());
}

View file

@ -4,6 +4,7 @@
package org.pgpainless.signature.builder;
import org.bouncycastle.bcpg.sig.Exportable;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
@ -22,6 +23,7 @@ import java.security.NoSuchAlgorithmException;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -61,7 +63,9 @@ public class ThirdPartyCertificationSignatureBuilderTest {
assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.valueOf(certification.getSignatureType()));
assertEquals(secretKeys.getPublicKey().getKeyID(), certification.getKeyID());
assertArrayEquals(secretKeys.getPublicKey().getFingerprint(), certification.getHashedSubPackets().getIssuerFingerprint().getFingerprint());
assertFalse(SignatureSubpacketsUtil.getExportableCertification(certification).isExportable());
Exportable exportable = SignatureSubpacketsUtil.getExportableCertification(certification);
assertNotNull(exportable);
assertFalse(exportable.isExportable());
// test sig correctness
certification.init(ImplementationFactory.getInstance().getPGPContentVerifierBuilderProvider(), secretKeys.getPublicKey());

View file

@ -376,7 +376,7 @@ public class SignatureSubpacketsTest {
public void testSetSignatureTarget() {
byte[] hash = new byte[20];
new Random().nextBytes(hash);
wrapper.setSignatureTarget(PublicKeyAlgorithm.fromId(key.getAlgorithm()), HashAlgorithm.SHA512, hash);
wrapper.setSignatureTarget(PublicKeyAlgorithm.requireFromId(key.getAlgorithm()), HashAlgorithm.SHA512, hash);
PGPSignatureSubpacketVector vector = SignatureSubpacketsHelper.toVector(wrapper);
SignatureTarget target = vector.getSignatureTarget();