From 0f06b8a1d6df7682d4216ec685c907bbf5774ff0 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 10 Apr 2014 20:33:54 +0200 Subject: display correct primary user id in import dialogue MOSTLY This is an incomplete fix; due to use of machine readable output, there is no way to know the primary user id for keys fetched from a key server. Pending https://bitbucket.org/skskeyserver/sks-keyserver/issue/28/primary-uid-in-machine-readable-index --- .../keychain/ui/adapter/ImportKeysListEntry.java | 61 ++++++++++++++-------- .../keychain/util/HkpKeyServer.java | 1 + 2 files changed, 41 insertions(+), 21 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 5631d40ea..44bde963e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -21,9 +21,12 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.SparseArray; +import org.spongycastle.bcpg.SignatureSubpacketTags; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.util.IterableIterator; @@ -46,31 +49,19 @@ public class ImportKeysListEntry implements Serializable, Parcelable { public int bitStrength; public String algorithm; public boolean secretKey; + public String mPrimaryUserId; private boolean mSelected; private byte[] mBytes = new byte[]{}; - public ImportKeysListEntry(ImportKeysListEntry b) { - this.userIds = b.userIds; - this.keyId = b.keyId; - this.revoked = b.revoked; - this.date = b.date; - this.fingerPrintHex = b.fingerPrintHex; - this.keyIdHex = b.keyIdHex; - this.bitStrength = b.bitStrength; - this.algorithm = b.algorithm; - this.secretKey = b.secretKey; - this.mSelected = b.mSelected; - this.mBytes = b.mBytes; - } - public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mPrimaryUserId); dest.writeStringList(userIds); dest.writeLong(keyId); dest.writeByte((byte) (revoked ? 1 : 0)); @@ -88,6 +79,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable { public static final Creator CREATOR = new Creator() { public ImportKeysListEntry createFromParcel(final Parcel source) { ImportKeysListEntry vr = new ImportKeysListEntry(); + vr.mPrimaryUserId = source.readString(); vr.userIds = new ArrayList(); source.readStringList(vr.userIds); vr.keyId = source.readLong(); @@ -198,6 +190,14 @@ public class ImportKeysListEntry implements Serializable, Parcelable { this.userIds = userIds; } + public String getPrimaryUserId() { + return mPrimaryUserId; + } + + public void setPrimaryUserId(String uid) { + mPrimaryUserId = uid; + } + /** * Constructor for later querying from keyserver */ @@ -229,20 +229,39 @@ public class ImportKeysListEntry implements Serializable, Parcelable { } else { secretKey = false; } + PGPPublicKey key = pgpKeyRing.getPublicKey(); userIds = new ArrayList(); - for (String userId : new IterableIterator(pgpKeyRing.getPublicKey().getUserIDs())) { + for (String userId : new IterableIterator(key.getUserIDs())) { userIds.add(userId); + for(PGPSignature sig : new IterableIterator(key.getSignaturesForID(userId))) { + if(sig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.PRIMARY_USER_ID)) { + try { + // make sure it's actually valid + sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME), key); + if (sig.verifyCertification(userId, key)) { + mPrimaryUserId = userId; + } + } catch(Exception e) { + // nothing bad happens, the key is just not considered the primary key id + } + } + + } + } + // if there was no user id flagged as primary, use the first one + if(mPrimaryUserId == null) { + mPrimaryUserId = userIds.get(0); } - this.keyId = pgpKeyRing.getPublicKey().getKeyID(); + this.keyId = key.getKeyID(); this.keyIdHex = PgpKeyHelper.convertKeyIdToHex(keyId); - this.revoked = pgpKeyRing.getPublicKey().isRevoked(); - this.fingerPrintHex = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey() - .getFingerprint()); - this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength(); - final int algorithm = pgpKeyRing.getPublicKey().getAlgorithm(); + this.revoked = key.isRevoked(); + this.fingerPrintHex = PgpKeyHelper.convertFingerprintToHex(key.getFingerprint()); + this.bitStrength = key.getBitStrength(); + final int algorithm = key.getAlgorithm(); this.algorithm = getAlgorithmFromId(algorithm); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index d1753de83..02149124c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -294,6 +294,7 @@ public class HkpKeyServer extends KeyServer { userIds.add(tmp); } entry.setUserIds(userIds); + entry.setPrimaryUserId(userIds.get(0)); results.add(entry); } -- cgit v1.2.3