mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-27 06:42:05 +01:00
Make KeyRingInfo NPE-safe
This commit is contained in:
parent
e3749f5734
commit
3edaa60b52
1 changed files with 207 additions and 32 deletions
|
@ -29,6 +29,9 @@ import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.sig.PrimaryUserID;
|
import org.bouncycastle.bcpg.sig.PrimaryUserID;
|
||||||
import org.bouncycastle.openpgp.PGPKeyRing;
|
import org.bouncycastle.openpgp.PGPKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
|
@ -37,9 +40,11 @@ import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSignature;
|
import org.bouncycastle.openpgp.PGPSignature;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
import org.pgpainless.algorithm.HashAlgorithm;
|
import org.pgpainless.algorithm.HashAlgorithm;
|
||||||
import org.pgpainless.algorithm.KeyFlag;
|
import org.pgpainless.algorithm.KeyFlag;
|
||||||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.encryption_signing.EncryptionStream;
|
import org.pgpainless.encryption_signing.EncryptionStream;
|
||||||
import org.pgpainless.exception.KeyValidationException;
|
import org.pgpainless.exception.KeyValidationException;
|
||||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
@ -105,7 +110,7 @@ public class KeyRingInfo {
|
||||||
* @param fingerprint fingerprint
|
* @param fingerprint fingerprint
|
||||||
* @return public key or null
|
* @return public key or null
|
||||||
*/
|
*/
|
||||||
public PGPPublicKey getPublicKey(OpenPgpV4Fingerprint fingerprint) {
|
public @Nullable PGPPublicKey getPublicKey(OpenPgpV4Fingerprint fingerprint) {
|
||||||
return getPublicKey(fingerprint.getKeyId());
|
return getPublicKey(fingerprint.getKeyId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +120,7 @@ public class KeyRingInfo {
|
||||||
* @param keyId key id
|
* @param keyId key id
|
||||||
* @return public key or null
|
* @return public key or null
|
||||||
*/
|
*/
|
||||||
public PGPPublicKey getPublicKey(long keyId) {
|
public @Nullable PGPPublicKey getPublicKey(long keyId) {
|
||||||
return getPublicKey(keys, keyId);
|
return getPublicKey(keys, keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +131,7 @@ public class KeyRingInfo {
|
||||||
* @param keyId key id
|
* @param keyId key id
|
||||||
* @return public key or null
|
* @return public key or null
|
||||||
*/
|
*/
|
||||||
public static PGPPublicKey getPublicKey(PGPKeyRing keyRing, long keyId) {
|
public @Nullable static PGPPublicKey getPublicKey(PGPKeyRing keyRing, long keyId) {
|
||||||
return keyRing.getPublicKey(keyId);
|
return keyRing.getPublicKey(keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +170,8 @@ public class KeyRingInfo {
|
||||||
// Subkey is hard revoked
|
// Subkey is hard revoked
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (!SignatureUtils.isSignatureExpired(revocation) && revocation.getCreationTime().after(binding.getCreationTime())) {
|
if (!SignatureUtils.isSignatureExpired(revocation)
|
||||||
|
&& revocation.getCreationTime().after(binding.getCreationTime())) {
|
||||||
// Key is soft-revoked, not yet re-bound
|
// Key is soft-revoked, not yet re-bound
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +199,7 @@ public class KeyRingInfo {
|
||||||
*
|
*
|
||||||
* @return primary secret key or null if the key ring is public
|
* @return primary secret key or null if the key ring is public
|
||||||
*/
|
*/
|
||||||
public PGPSecretKey getSecretKey() {
|
public @Nullable PGPSecretKey getSecretKey() {
|
||||||
if (keys instanceof PGPSecretKeyRing) {
|
if (keys instanceof PGPSecretKeyRing) {
|
||||||
PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) keys;
|
PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) keys;
|
||||||
return secretKeys.getSecretKey();
|
return secretKeys.getSecretKey();
|
||||||
|
@ -207,7 +213,7 @@ public class KeyRingInfo {
|
||||||
* @param fingerprint fingerprint
|
* @param fingerprint fingerprint
|
||||||
* @return secret key or null
|
* @return secret key or null
|
||||||
*/
|
*/
|
||||||
public PGPSecretKey getSecretKey(OpenPgpV4Fingerprint fingerprint) {
|
public @Nullable PGPSecretKey getSecretKey(OpenPgpV4Fingerprint fingerprint) {
|
||||||
return getSecretKey(fingerprint.getKeyId());
|
return getSecretKey(fingerprint.getKeyId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +223,7 @@ public class KeyRingInfo {
|
||||||
* @param keyId key id
|
* @param keyId key id
|
||||||
* @return secret key or null
|
* @return secret key or null
|
||||||
*/
|
*/
|
||||||
public PGPSecretKey getSecretKey(long keyId) {
|
public @Nullable PGPSecretKey getSecretKey(long keyId) {
|
||||||
if (keys instanceof PGPSecretKeyRing) {
|
if (keys instanceof PGPSecretKeyRing) {
|
||||||
return ((PGPSecretKeyRing) keys).getSecretKey(keyId);
|
return ((PGPSecretKeyRing) keys).getSecretKey(keyId);
|
||||||
}
|
}
|
||||||
|
@ -266,15 +272,22 @@ public class KeyRingInfo {
|
||||||
*
|
*
|
||||||
* @return primary user-id or null
|
* @return primary user-id or null
|
||||||
*/
|
*/
|
||||||
public String getPrimaryUserId() {
|
public @Nullable String getPrimaryUserId() {
|
||||||
String primaryUserId = null;
|
String primaryUserId = null;
|
||||||
Date modificationDate = null;
|
Date modificationDate = null;
|
||||||
|
|
||||||
List<String> validUserIds = getValidUserIds();
|
List<String> validUserIds = getValidUserIds();
|
||||||
if (validUserIds.isEmpty()) {
|
if (validUserIds.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String userId : validUserIds) {
|
for (String userId : validUserIds) {
|
||||||
|
|
||||||
PGPSignature signature = signatures.userIdCertifications.get(userId);
|
PGPSignature signature = signatures.userIdCertifications.get(userId);
|
||||||
|
if (signature == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PrimaryUserID subpacket = SignatureSubpacketsUtil.getPrimaryUserId(signature);
|
PrimaryUserID subpacket = SignatureSubpacketsUtil.getPrimaryUserId(signature);
|
||||||
if (subpacket != null && subpacket.isPrimaryUserID()) {
|
if (subpacket != null && subpacket.isPrimaryUserID()) {
|
||||||
// if there are multiple primary userIDs, return most recently signed
|
// if there are multiple primary userIDs, return most recently signed
|
||||||
|
@ -294,6 +307,8 @@ public class KeyRingInfo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of all user-ids of the primary key.
|
* Return a list of all user-ids of the primary key.
|
||||||
|
* Note: This list might also contain expired / revoked user-ids.
|
||||||
|
* Consider using {@link #getValidUserIds()} instead.
|
||||||
*
|
*
|
||||||
* @return list of user-ids
|
* @return list of user-ids
|
||||||
*/
|
*/
|
||||||
|
@ -329,11 +344,25 @@ public class KeyRingInfo {
|
||||||
PGPSignature certification = signatures.userIdCertifications.get(userId);
|
PGPSignature certification = signatures.userIdCertifications.get(userId);
|
||||||
PGPSignature revocation = signatures.userIdRevocations.get(userId);
|
PGPSignature revocation = signatures.userIdRevocations.get(userId);
|
||||||
|
|
||||||
return certification != null && revocation == null;
|
// If user-id is expired, certification will be null.
|
||||||
|
if (certification == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Not revoked -> valid
|
||||||
|
if (revocation == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Hard revocation -> invalid
|
||||||
|
if (SignatureUtils.isHardRevocation(revocation)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Soft revocation -> valid if certification is newer than revocation (revalidation)
|
||||||
|
return certification.getCreationTime().after(revocation.getCreationTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of all user-ids of the primary key that appear to be email-addresses.
|
* Return a list of all user-ids of the primary key that appear to be email-addresses.
|
||||||
|
* Note: This list might contain expired / revoked user-ids.
|
||||||
*
|
*
|
||||||
* @return email addresses
|
* @return email addresses
|
||||||
*/
|
*/
|
||||||
|
@ -354,33 +383,68 @@ public class KeyRingInfo {
|
||||||
*
|
*
|
||||||
* Note: This signature might be expired (check with {@link SignatureUtils#isSignatureExpired(PGPSignature)}).
|
* Note: This signature might be expired (check with {@link SignatureUtils#isSignatureExpired(PGPSignature)}).
|
||||||
*
|
*
|
||||||
* @return latest direct key self-signature
|
* @return latest direct key self-signature or null
|
||||||
*/
|
*/
|
||||||
public PGPSignature getLatestDirectKeySelfSignature() {
|
public @Nullable PGPSignature getLatestDirectKeySelfSignature() {
|
||||||
return signatures.primaryKeySelfSignature;
|
return signatures.primaryKeySelfSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PGPSignature getRevocationSelfSignature() {
|
/**
|
||||||
|
* Return the latest revocation self-signature on the primary key.
|
||||||
|
*
|
||||||
|
* @return revocation or null
|
||||||
|
*/
|
||||||
|
public @Nullable PGPSignature getRevocationSelfSignature() {
|
||||||
return signatures.primaryKeyRevocation;
|
return signatures.primaryKeyRevocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PGPSignature getLatestUserIdCertification(String userId) {
|
/**
|
||||||
|
* Return the latest certification self-signature on the provided user-id.
|
||||||
|
*
|
||||||
|
* @param userId user-id
|
||||||
|
* @return certification signature or null
|
||||||
|
*/
|
||||||
|
public @Nullable PGPSignature getLatestUserIdCertification(String userId) {
|
||||||
return signatures.userIdCertifications.get(userId);
|
return signatures.userIdCertifications.get(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PGPSignature getUserIdRevocation(String userId) {
|
/**
|
||||||
|
* Return the latest user-id revocation signature for the provided user-id.
|
||||||
|
*
|
||||||
|
* @param userId user-id
|
||||||
|
* @return revocation or null
|
||||||
|
*/
|
||||||
|
public @Nullable PGPSignature getUserIdRevocation(String userId) {
|
||||||
return signatures.userIdRevocations.get(userId);
|
return signatures.userIdRevocations.get(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PGPSignature getCurrentSubkeyBindingSignature(long keyId) {
|
/**
|
||||||
|
* Return the currently active subkey binding signature for the subkey with the provided key-id.
|
||||||
|
*
|
||||||
|
* @param keyId subkey id
|
||||||
|
* @return subkey binding signature or null
|
||||||
|
*/
|
||||||
|
public @Nullable PGPSignature getCurrentSubkeyBindingSignature(long keyId) {
|
||||||
return signatures.subkeyBindings.get(keyId);
|
return signatures.subkeyBindings.get(keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PGPSignature getSubkeyRevocationSignature(long keyId) {
|
/**
|
||||||
|
* Return the latest subkey binding revocation signature for the subkey with the given key-id.
|
||||||
|
*
|
||||||
|
* @param keyId subkey id
|
||||||
|
* @return subkey binding revocation or null
|
||||||
|
*/
|
||||||
|
public @Nullable PGPSignature getSubkeyRevocationSignature(long keyId) {
|
||||||
return signatures.subkeyRevocations.get(keyId);
|
return signatures.subkeyRevocations.get(keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KeyFlag> getKeyFlagsOf(long keyId) {
|
/**
|
||||||
|
* Return the a list of {@link KeyFlag KeyFlags} that apply to the subkey with the provided key id.
|
||||||
|
* @param keyId key-id
|
||||||
|
* @return list of key flags
|
||||||
|
*/
|
||||||
|
public @Nonnull List<KeyFlag> getKeyFlagsOf(long keyId) {
|
||||||
|
// key is primary key
|
||||||
if (getPublicKey().getKeyID() == keyId) {
|
if (getPublicKey().getKeyID() == keyId) {
|
||||||
|
|
||||||
PGPSignature directKeySignature = getLatestDirectKeySelfSignature();
|
PGPSignature directKeySignature = getLatestDirectKeySelfSignature();
|
||||||
|
@ -399,7 +463,9 @@ public class KeyRingInfo {
|
||||||
return keyFlags;
|
return keyFlags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
// Key is subkey
|
||||||
|
else {
|
||||||
PGPSignature bindingSignature = getCurrentSubkeyBindingSignature(keyId);
|
PGPSignature bindingSignature = getCurrentSubkeyBindingSignature(keyId);
|
||||||
if (bindingSignature != null) {
|
if (bindingSignature != null) {
|
||||||
List<KeyFlag> keyFlags = SignatureSubpacketsUtil.parseKeyFlags(bindingSignature);
|
List<KeyFlag> keyFlags = SignatureSubpacketsUtil.parseKeyFlags(bindingSignature);
|
||||||
|
@ -411,7 +477,13 @@ public class KeyRingInfo {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KeyFlag> getKeyFlagsOf(String userId) {
|
/**
|
||||||
|
* Return a list of {@link KeyFlag KeyFlags} that apply to the given user-id.
|
||||||
|
*
|
||||||
|
* @param userId user-id
|
||||||
|
* @return key flags
|
||||||
|
*/
|
||||||
|
public @Nonnull List<KeyFlag> getKeyFlagsOf(String userId) {
|
||||||
if (!isUserIdValid(userId)) {
|
if (!isUserIdValid(userId)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
@ -452,12 +524,35 @@ public class KeyRingInfo {
|
||||||
*
|
*
|
||||||
* @return last modification date.
|
* @return last modification date.
|
||||||
*/
|
*/
|
||||||
public Date getLastModified() {
|
public @Nullable Date getLastModified() {
|
||||||
PGPSignature mostRecent = getMostRecentSignature();
|
PGPSignature mostRecent = getMostRecentSignature();
|
||||||
|
if (mostRecent == null) {
|
||||||
|
// No sigs found. Return public key creation date instead.
|
||||||
|
return getLatestKeyCreationDate();
|
||||||
|
}
|
||||||
return mostRecent.getCreationTime();
|
return mostRecent.getCreationTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PGPSignature getMostRecentSignature() {
|
/**
|
||||||
|
* Return the creation time of the latest added subkey.
|
||||||
|
*
|
||||||
|
* @return latest key creation time
|
||||||
|
*/
|
||||||
|
public @Nonnull Date getLatestKeyCreationDate() {
|
||||||
|
Date latestCreation = null;
|
||||||
|
for (PGPPublicKey key : getPublicKeys()) {
|
||||||
|
Date keyCreation = key.getCreationTime();
|
||||||
|
if (latestCreation == null || latestCreation.before(keyCreation)) {
|
||||||
|
latestCreation = keyCreation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (latestCreation == null) {
|
||||||
|
throw new AssertionError("Apparently there is no key in this key ring.");
|
||||||
|
}
|
||||||
|
return latestCreation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable PGPSignature getMostRecentSignature() {
|
||||||
Set<PGPSignature> allSignatures = new HashSet<>();
|
Set<PGPSignature> allSignatures = new HashSet<>();
|
||||||
PGPSignature mostRecentSelfSignature = getLatestDirectKeySelfSignature();
|
PGPSignature mostRecentSelfSignature = getLatestDirectKeySelfSignature();
|
||||||
PGPSignature revocationSelfSignature = getRevocationSelfSignature();
|
PGPSignature revocationSelfSignature = getRevocationSelfSignature();
|
||||||
|
@ -482,7 +577,7 @@ public class KeyRingInfo {
|
||||||
*
|
*
|
||||||
* @return revocation date or null
|
* @return revocation date or null
|
||||||
*/
|
*/
|
||||||
public Date getRevocationDate() {
|
public @Nullable Date getRevocationDate() {
|
||||||
return getRevocationSelfSignature() == null ? null : getRevocationSelfSignature().getCreationTime();
|
return getRevocationSelfSignature() == null ? null : getRevocationSelfSignature().getCreationTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,14 +586,19 @@ public class KeyRingInfo {
|
||||||
*
|
*
|
||||||
* @return expiration date
|
* @return expiration date
|
||||||
*/
|
*/
|
||||||
public Date getPrimaryKeyExpirationDate() {
|
public @Nullable Date getPrimaryKeyExpirationDate() {
|
||||||
Date lastExpiration = null;
|
Date lastExpiration = null;
|
||||||
if (getLatestDirectKeySelfSignature() != null) {
|
if (getLatestDirectKeySelfSignature() != null) {
|
||||||
lastExpiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), getLatestDirectKeySelfSignature());
|
lastExpiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), getLatestDirectKeySelfSignature());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String userId : getValidUserIds()) {
|
for (String userId : getValidUserIds()) {
|
||||||
|
|
||||||
PGPSignature signature = getLatestUserIdCertification(userId);
|
PGPSignature signature = getLatestUserIdCertification(userId);
|
||||||
|
if (signature == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Date expiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), signature);
|
Date expiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), signature);
|
||||||
if (expiration != null && (lastExpiration == null || expiration.after(lastExpiration))) {
|
if (expiration != null && (lastExpiration == null || expiration.after(lastExpiration))) {
|
||||||
lastExpiration = expiration;
|
lastExpiration = expiration;
|
||||||
|
@ -507,7 +607,13 @@ public class KeyRingInfo {
|
||||||
return lastExpiration;
|
return lastExpiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getSubkeyExpirationDate(OpenPgpV4Fingerprint fingerprint) {
|
/**
|
||||||
|
* Return the expiration date of the subkey with the provided fingerprint.
|
||||||
|
*
|
||||||
|
* @param fingerprint subkey fingerprint
|
||||||
|
* @return expiration date or null
|
||||||
|
*/
|
||||||
|
public @Nullable Date getSubkeyExpirationDate(OpenPgpV4Fingerprint fingerprint) {
|
||||||
if (getPublicKey().getKeyID() == fingerprint.getKeyId()) {
|
if (getPublicKey().getKeyID() == fingerprint.getKeyId()) {
|
||||||
return getPrimaryKeyExpirationDate();
|
return getPrimaryKeyExpirationDate();
|
||||||
}
|
}
|
||||||
|
@ -516,7 +622,11 @@ public class KeyRingInfo {
|
||||||
if (subkey == null) {
|
if (subkey == null) {
|
||||||
throw new IllegalArgumentException("No subkey with fingerprint " + fingerprint + " found.");
|
throw new IllegalArgumentException("No subkey with fingerprint " + fingerprint + " found.");
|
||||||
}
|
}
|
||||||
return SignatureUtils.getKeyExpirationDate(subkey.getCreationTime(), getCurrentSubkeyBindingSignature(fingerprint.getKeyId()));
|
PGPSignature bindingSig = getCurrentSubkeyBindingSignature(fingerprint.getKeyId());
|
||||||
|
if (bindingSig == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return SignatureUtils.getKeyExpirationDate(subkey.getCreationTime(), bindingSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -574,7 +684,14 @@ public class KeyRingInfo {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PGPPublicKey> getEncryptionSubkeys(EncryptionStream.Purpose purpose) {
|
/**
|
||||||
|
* Return a list of all subkeys which can be used for encryption of the given purpose.
|
||||||
|
* This list does not include expired or revoked keys.
|
||||||
|
*
|
||||||
|
* @param purpose purpose (encrypt data at rest / communications)
|
||||||
|
* @return encryption subkeys
|
||||||
|
*/
|
||||||
|
public @Nonnull List<PGPPublicKey> getEncryptionSubkeys(EncryptionStream.Purpose purpose) {
|
||||||
Iterator<PGPPublicKey> subkeys = keys.getPublicKeys();
|
Iterator<PGPPublicKey> subkeys = keys.getPublicKeys();
|
||||||
List<PGPPublicKey> encryptionKeys = new ArrayList<>();
|
List<PGPPublicKey> encryptionKeys = new ArrayList<>();
|
||||||
while (subkeys.hasNext()) {
|
while (subkeys.hasNext()) {
|
||||||
|
@ -610,7 +727,17 @@ public class KeyRingInfo {
|
||||||
return encryptionKeys;
|
return encryptionKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PGPPublicKey> getEncryptionSubkeys(String userId, EncryptionStream.Purpose purpose) {
|
/**
|
||||||
|
* Return a list of all subkeys that can be used for encryption with the given user-id.
|
||||||
|
* This list does not include expired or revoked keys.
|
||||||
|
* TODO: Does it make sense to pass in a user-id?
|
||||||
|
* Aren't the encryption subkeys the same, regardless of which user-id is used?
|
||||||
|
*
|
||||||
|
* @param userId user-id
|
||||||
|
* @param purpose encryption purpose
|
||||||
|
* @return encryption subkeys
|
||||||
|
*/
|
||||||
|
public @Nonnull List<PGPPublicKey> getEncryptionSubkeys(String userId, EncryptionStream.Purpose purpose) {
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
if (!isUserIdValid(userId)) {
|
if (!isUserIdValid(userId)) {
|
||||||
throw new KeyValidationException(userId, getLatestUserIdCertification(userId), getUserIdRevocation(userId));
|
throw new KeyValidationException(userId, getLatestUserIdCertification(userId), getUserIdRevocation(userId));
|
||||||
|
@ -620,7 +747,12 @@ public class KeyRingInfo {
|
||||||
return getEncryptionSubkeys(purpose);
|
return getEncryptionSubkeys(purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PGPPublicKey> getSigningSubkeys() {
|
/**
|
||||||
|
* Return a list of all subkeys which can be used to sign data.
|
||||||
|
*
|
||||||
|
* @return signing keys
|
||||||
|
*/
|
||||||
|
public @Nonnull List<PGPPublicKey> getSigningSubkeys() {
|
||||||
Iterator<PGPPublicKey> subkeys = keys.getPublicKeys();
|
Iterator<PGPPublicKey> subkeys = keys.getPublicKeys();
|
||||||
List<PGPPublicKey> signingKeys = new ArrayList<>();
|
List<PGPPublicKey> signingKeys = new ArrayList<>();
|
||||||
while (subkeys.hasNext()) {
|
while (subkeys.hasNext()) {
|
||||||
|
@ -638,12 +770,56 @@ public class KeyRingInfo {
|
||||||
return signingKeys;
|
return signingKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<HashAlgorithm> getPreferredHashAlgorithms(String userId, long keyID) {
|
/**
|
||||||
KeyAccessor keyAccessor = userId == null ? new KeyAccessor.ViaKeyId(this, new SubkeyIdentifier(keys, keyID))
|
* Return the (sorted) set of preferred hash algorithms of the given key.
|
||||||
: new KeyAccessor.ViaUserId(this, new SubkeyIdentifier(keys, keyID), userId);
|
*
|
||||||
|
* @param userId user-id. If this is non-null, the hash algorithms are being extracted from the user-id
|
||||||
|
* certification signature first.
|
||||||
|
* @param keyID if of the key in question
|
||||||
|
* @return hash algorithm preferences
|
||||||
|
*/
|
||||||
|
public Set<HashAlgorithm> getPreferredHashAlgorithms(@Nullable String userId, long keyID) {
|
||||||
|
KeyAccessor keyAccessor = getKeyAccessor(userId, keyID);
|
||||||
return keyAccessor.getPreferredHashAlgorithms();
|
return keyAccessor.getPreferredHashAlgorithms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the (sorted) set of preferred symmetric encryption algorithms of the given key.
|
||||||
|
*
|
||||||
|
* @param userId user-id. If this is non-null, the symmetric encryption algorithms are being
|
||||||
|
* extracted from the user-id certification signature first.
|
||||||
|
* @param keyId if of the key in question
|
||||||
|
* @return symmetric encryption algorithm preferences
|
||||||
|
*/
|
||||||
|
public Set<SymmetricKeyAlgorithm> getPreferredSymmetricKeyAlgorithms(@Nullable String userId, long keyId) {
|
||||||
|
KeyAccessor keyAccessor = getKeyAccessor(userId, keyId);
|
||||||
|
return keyAccessor.getPreferredSymmetricKeyAlgorithms();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the (sorted) set of preferred compression algorithms of the given key.
|
||||||
|
*
|
||||||
|
* @param userId user-id. If this is non-null, the compression algorithms are being extracted from the user-id
|
||||||
|
* certification signature first.
|
||||||
|
* @param keyId if of the key in question
|
||||||
|
* @return compression algorithm preferences
|
||||||
|
*/
|
||||||
|
public Set<CompressionAlgorithm> getPreferredCompressionAlgorithms(@Nullable String userId, long keyId) {
|
||||||
|
KeyAccessor keyAccessor = getKeyAccessor(userId, keyId);
|
||||||
|
return keyAccessor.getPreferredCompressionAlgorithms();
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyAccessor getKeyAccessor(@Nullable String userId, long keyID) {
|
||||||
|
if (getPublicKey(keyID) == null) {
|
||||||
|
throw new IllegalArgumentException("No subkey with key id " + Long.toHexString(keyID) + " found on this key.");
|
||||||
|
}
|
||||||
|
if (userId != null && !getUserIds().contains(userId)) {
|
||||||
|
throw new IllegalArgumentException("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);
|
||||||
|
}
|
||||||
|
|
||||||
public static class Signatures {
|
public static class Signatures {
|
||||||
|
|
||||||
private final PGPSignature primaryKeyRevocation;
|
private final PGPSignature primaryKeyRevocation;
|
||||||
|
@ -687,6 +863,5 @@ public class KeyRingInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue