diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2014-07-11 02:50:35 +0200 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2014-07-11 02:50:35 +0200 |
commit | e477577c55cf9c30b749b467ab01fa2ff2ce8254 (patch) | |
tree | fa0d133a25eabbd085a66b1ff05d78403840a83c /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java | |
parent | 38ee6203ad1dd784a37e705735398955cc7ec9f5 (diff) | |
download | open-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.java | 70 |
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>() { |