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:
parent
3b8a1b47d7
commit
953206b4ed
12 changed files with 263 additions and 137 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<>();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue