aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2014-07-11 02:50:35 +0200
committerVincent Breitmoser <valodim@mugenguild.com>2014-07-11 02:50:35 +0200
commite477577c55cf9c30b749b467ab01fa2ff2ce8254 (patch)
treefa0d133a25eabbd085a66b1ff05d78403840a83c /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
parent38ee6203ad1dd784a37e705735398955cc7ec9f5 (diff)
downloadopen-keychain-e477577c55cf9c30b749b467ab01fa2ff2ce8254.tar.gz
open-keychain-e477577c55cf9c30b749b467ab01fa2ff2ce8254.tar.bz2
open-keychain-e477577c55cf9c30b749b467ab01fa2ff2ce8254.zip
some UncachedKeyRing fixes, primary user id mostly
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java70
1 files changed, 62 insertions, 8 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
index 33db7771b..3171d0565 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
@@ -77,26 +77,65 @@ public class UncachedPublicKey {
return mPublicKey.getBitStrength();
}
+ /** Returns the primary user id, as indicated by the public key's self certificates.
+ *
+ * This is an expensive operation, since potentially a lot of certificates (and revocations)
+ * have to be checked, and even then the result is NOT guaranteed to be constant through a
+ * canonicalization operation.
+ *
+ * Returns null if there is no primary user id (as indicated by certificates)
+ *
+ */
public String getPrimaryUserId() {
+ String found = null;
+ PGPSignature foundSig = null;
for (String userId : new IterableIterator<String>(mPublicKey.getUserIDs())) {
+ PGPSignature revocation = null;
+
for (PGPSignature sig : new IterableIterator<PGPSignature>(mPublicKey.getSignaturesForID(userId))) {
- if (sig.getHashedSubPackets() != null
- && sig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.PRIMARY_USER_ID)) {
- try {
+ try {
+
+ // if this is a revocation, this is not the user id
+ if (sig.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION) {
+ // make sure it's actually valid
+ sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider(
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME), mPublicKey);
+ if (!sig.verifyCertification(userId, mPublicKey)) {
+ continue;
+ }
+ if (found != null && found.equals(userId)) {
+ found = null;
+ }
+ revocation = sig;
+ // this revocation may still be overridden by a newer cert
+ continue;
+ }
+
+ if (sig.getHashedSubPackets() != null && sig.getHashedSubPackets().isPrimaryUserID()) {
+ if (foundSig != null && sig.getCreationTime().before(foundSig.getCreationTime())) {
+ continue;
+ }
+ // ignore if there is a newer revocation for this user id
+ if (revocation != null && sig.getCreationTime().before(revocation.getCreationTime())) {
+ continue;
+ }
// make sure it's actually valid
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider(
Constants.BOUNCY_CASTLE_PROVIDER_NAME), mPublicKey);
if (sig.verifyCertification(userId, mPublicKey)) {
- return userId;
+ found = userId;
+ foundSig = sig;
+ // this one can't be relevant anymore at this point
+ revocation = null;
}
- } catch (Exception e) {
- // nothing bad happens, the key is just not considered the primary key id
}
- }
+ } catch (Exception e) {
+ // nothing bad happens, the key is just not considered the primary key id
+ }
}
}
- return null;
+ return found;
}
public ArrayList<String> getUnorderedUserIds() {
@@ -186,6 +225,21 @@ public class UncachedPublicKey {
return mPublicKey;
}
+ public Iterator<WrappedSignature> getSignatures() {
+ final Iterator<PGPSignature> it = mPublicKey.getSignatures();
+ return new Iterator<WrappedSignature>() {
+ public void remove() {
+ it.remove();
+ }
+ public WrappedSignature next() {
+ return new WrappedSignature(it.next());
+ }
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+ };
+ }
+
public Iterator<WrappedSignature> getSignaturesForId(String userId) {
final Iterator<PGPSignature> it = mPublicKey.getSignaturesForID(userId);
return new Iterator<WrappedSignature>() {