diff options
7 files changed, 91 insertions, 88 deletions
| diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index d201a1426..09c0b2d8f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -460,12 +460,16 @@ public class PgpKeyHelper {      public static String convertFingerprintToHex(byte[] fingerprint, boolean split) {          String hexString = Hex.toHexString(fingerprint);          if (split) { -            hexString = hexString.replaceAll("(.{4})(?!$)", "$1 "); +            hexString = splitFingerprintHex(hexString);          }          return hexString;      } +    public static String splitFingerprintHex(String hexString) { +        return hexString.replaceAll("(.{4})(?!$)", "$1 "); +    } +      /**       * Convert key id from long to 64 bit hex string       * <p/> @@ -498,19 +502,6 @@ public class PgpKeyHelper {      }      /** -     * Used in HkpKeyServer to convert hex encoded key ids back to long. -     * -     * @param hexString -     * @return -     */ -    public static long convertHexToKeyId(String hexString) { -        int len = hexString.length(); -        String s2 = hexString.substring(len - 8); -        String s1 = hexString.substring(0, len - 8); -        return ((!s1.isEmpty() ? Long.parseLong(s1, 16) << 32 : 0) | Long.parseLong(s2, 16)); -    } - -    /**       * Splits userId string into naming part, email part, and comment part       *       * @param userId diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 6ec6dcf8a..5af81d39d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -749,7 +749,7 @@ public class KeychainIntentService extends IntentService                  HkpKeyServer server = new HkpKeyServer(keyServer);                  for (ImportKeysListEntry entry : entries) { -                    byte[] downloadedKey = server.get(entry.getKeyId()).getBytes(); +                    byte[] downloadedKey = server.get(entry.getKeyIdHex()).getBytes();                      /**                       * TODO: copied from ImportKeysListLoader diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 0f05af447..37a8dd416 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -134,10 +134,10 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {              holder.mMainUserIdRest.setVisibility(View.GONE);          } -        holder.mKeyId.setText(entry.hexKeyId); +        holder.mKeyId.setText(entry.keyIdHex); -        if (entry.fingerPrint != null) { -            holder.mFingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint); +        if (entry.fingerPrintHex != null) { +            holder.mFingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrintHex);              holder.mFingerprint.setVisibility(View.VISIBLE);          } else {              holder.mFingerprint.setVisibility(View.GONE); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 05521b0c9..d7c38213d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui.adapter;  import android.os.Parcel;  import android.os.Parcelable;  import android.util.SparseArray; +  import org.spongycastle.openpgp.PGPKeyRing;  import org.spongycastle.openpgp.PGPPublicKey;  import org.spongycastle.openpgp.PGPSecretKeyRing; @@ -38,10 +39,11 @@ public class ImportKeysListEntry implements Serializable, Parcelable {      public ArrayList<String> userIds;      public long keyId; +    public String keyIdHex; +      public boolean revoked;      public Date date; // TODO: not displayed -    public String fingerPrint; -    public String hexKeyId; +    public String fingerPrintHex;      public int bitStrength;      public String algorithm;      public boolean secretKey; @@ -55,8 +57,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {          this.keyId = b.keyId;          this.revoked = b.revoked;          this.date = b.date; -        this.fingerPrint = b.fingerPrint; -        this.hexKeyId = b.hexKeyId; +        this.fingerPrintHex = b.fingerPrintHex; +        this.keyIdHex = b.keyIdHex;          this.bitStrength = b.bitStrength;          this.algorithm = b.algorithm;          this.secretKey = b.secretKey; @@ -74,8 +76,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {          dest.writeLong(keyId);          dest.writeByte((byte) (revoked ? 1 : 0));          dest.writeSerializable(date); -        dest.writeString(fingerPrint); -        dest.writeString(hexKeyId); +        dest.writeString(fingerPrintHex); +        dest.writeString(keyIdHex);          dest.writeInt(bitStrength);          dest.writeString(algorithm);          dest.writeByte((byte) (secretKey ? 1 : 0)); @@ -92,8 +94,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {              vr.keyId = source.readLong();              vr.revoked = source.readByte() == 1;              vr.date = (Date) source.readSerializable(); -            vr.fingerPrint = source.readString(); -            vr.hexKeyId = source.readString(); +            vr.fingerPrintHex = source.readString(); +            vr.keyIdHex = source.readString();              vr.bitStrength = source.readInt();              vr.algorithm = source.readString();              vr.secretKey = source.readByte() == 1; @@ -109,8 +111,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {          }      }; -    public long getKeyId() { -        return keyId; +    public String getKeyIdHex() { +        return keyIdHex;      }      public byte[] getBytes() { @@ -121,6 +123,14 @@ public class ImportKeysListEntry implements Serializable, Parcelable {          this.mBytes = bytes;      } +    public boolean isSelected() { +        return mSelected; +    } + +    public void setSelected(boolean selected) { +        this.mSelected = selected; +    } +      /**       * Constructor for later querying from keyserver       */ @@ -132,14 +142,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable {          userIds = new ArrayList<String>();      } -    public boolean isSelected() { -        return mSelected; -    } - -    public void setSelected(boolean selected) { -        this.mSelected = selected; -    } -      /**       * Constructor based on key object, used for import from NFC, QR Codes, files       */ @@ -165,12 +167,13 @@ public class ImportKeysListEntry implements Serializable, Parcelable {          for (String userId : new IterableIterator<String>(pgpKeyRing.getPublicKey().getUserIDs())) {              userIds.add(userId);          } +          this.keyId = pgpKeyRing.getPublicKey().getKeyID(); +        this.keyIdHex = PgpKeyHelper.convertKeyIdToHex(keyId);          this.revoked = pgpKeyRing.getPublicKey().isRevoked(); -        this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey() +        this.fingerPrintHex = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()                  .getFingerprint(), true); -        this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);          this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();          final int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();          this.algorithm = getAlgorithmFromId(algorithm); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 43b40a4db..3658ef6c6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -18,7 +18,6 @@  package org.sufficientlysecure.keychain.util; -import android.text.Html;  import org.apache.http.HttpEntity;  import org.apache.http.HttpResponse;  import org.apache.http.HttpStatus; @@ -34,7 +33,6 @@ import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.pgp.PgpHelper;  import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;  import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; -import org.sufficientlysecure.keychain.util.Log;  import java.io.ByteArrayOutputStream;  import java.io.IOException; @@ -74,26 +72,26 @@ public class HkpKeyServer extends KeyServer {      /**       * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags%       * <ul> -     *     <li>%<b>keyid</b>% = this is either the fingerprint or the key ID of the key. Either the 16-digit or 8-digit -     *          key IDs are acceptable, but obviously the fingerprint is best.</li> -     *     <li>%<b>algo</b>% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). -     *          See <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a></li> -     *     <li>%<b>keylen</b>% = the key length (i.e. 1024, 2048, 4096, etc.)</li> -     *     <li>%<b>creationdate</b>% = creation date of the key in standard -     *          <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since -     *          1/1/1970 UTC time)</li> -     *     <li>%<b>expirationdate</b>% = expiration date of the key in standard -     *          <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since -     *          1/1/1970 UTC time)</li> -     *     <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any order. The -     *          meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so -     *          the absence of a given flag does not necessarily mean the absence of the detail. -     *          <ul> -     *              <li>r == revoked</li> -     *              <li>d == disabled</li> -     *              <li>e == expired</li> -     *          </ul> -     *     </li> +     * <li>%<b>keyid</b>% = this is either the fingerprint or the key ID of the key. Either the 16-digit or 8-digit +     * key IDs are acceptable, but obviously the fingerprint is best.</li> +     * <li>%<b>algo</b>% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). +     * See <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a></li> +     * <li>%<b>keylen</b>% = the key length (i.e. 1024, 2048, 4096, etc.)</li> +     * <li>%<b>creationdate</b>% = creation date of the key in standard +     * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since +     * 1/1/1970 UTC time)</li> +     * <li>%<b>expirationdate</b>% = expiration date of the key in standard +     * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since +     * 1/1/1970 UTC time)</li> +     * <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any order. The +     * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so +     * the absence of a given flag does not necessarily mean the absence of the detail. +     * <ul> +     * <li>r == revoked</li> +     * <li>d == disabled</li> +     * <li>e == expired</li> +     * </ul> +     * </li>       * </ul>       *       * @see <a href="http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-5.2">5.2. Machine Readable Indexes</a> @@ -107,23 +105,23 @@ public class HkpKeyServer extends KeyServer {      /**       * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags%       * <ul> -     *      <li>%<b>escaped uid string</b>% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit -     *          safe as well as for the ":" character.  Any other characters may be escaped, as desired.</li> -     *      <li>%<b>creationdate</b>% = creation date of the key in standard -     *          <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since -     *          1/1/1970 UTC time)</li> -     *      <li>%<b>expirationdate</b>% = expiration date of the key in standard -     *          <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since -     *          1/1/1970 UTC time)</li> -     *      <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any order. The -     *          meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so -     *          the absence of a given flag does not necessarily mean the absence of the detail. -     *          <ul> -     *              <li>r == revoked</li> -     *              <li>d == disabled</li> -     *              <li>e == expired</li> -     *          </ul> -     *      </li> +     * <li>%<b>escaped uid string</b>% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit +     * safe as well as for the ":" character.  Any other characters may be escaped, as desired.</li> +     * <li>%<b>creationdate</b>% = creation date of the key in standard +     * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since +     * 1/1/1970 UTC time)</li> +     * <li>%<b>expirationdate</b>% = expiration date of the key in standard +     * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of seconds since +     * 1/1/1970 UTC time)</li> +     * <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any order. The +     * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so +     * the absence of a given flag does not necessarily mean the absence of the detail. +     * <ul> +     * <li>r == revoked</li> +     * <li>d == disabled</li> +     * <li>e == expired</li> +     * </ul> +     * </li>       * </ul>       */      public static final Pattern UID_LINE = Pattern @@ -246,8 +244,18 @@ public class HkpKeyServer extends KeyServer {              final int algorithmId = Integer.decode(matcher.group(2));              info.algorithm = getAlgorithmFromId(algorithmId); -            info.hexKeyId = "0x" + matcher.group(1); -            info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(1)); +            // group 1 contains the full fingerprint (v4) or the long key id if available +            // see https://bitbucket.org/skskeyserver/sks-keyserver/pull-request/12/fixes-for-machine-readable-indexes/diff +            // and https://github.com/openpgp-keychain/openpgp-keychain/issues/259#issuecomment-38168176 +            String fingerprintOrKeyId = matcher.group(1); +            if (fingerprintOrKeyId.length() > 16) { +                info.fingerPrintHex = "0x" + PgpKeyHelper.splitFingerprintHex(fingerprintOrKeyId); +                info.keyIdHex = "0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length() +                        - 16, fingerprintOrKeyId.length()); +            } else { +                // set key id only +                info.keyIdHex = "0x" + fingerprintOrKeyId; +            }              final long creationDate = Long.parseLong(matcher.group(4));              final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); @@ -277,11 +285,11 @@ public class HkpKeyServer extends KeyServer {      }      @Override -    public String get(long keyId) throws QueryException { +    public String get(String keyIdHex) throws QueryException {          HttpClient client = new DefaultHttpClient();          try {              String query = "http://" + mHost + ":" + mPort + -                "/pks/lookup?op=get&options=mr&search=" + PgpKeyHelper.convertKeyIdToHex(keyId); +                    "/pks/lookup?op=get&options=mr&search=" + keyIdHex;              Log.d(Constants.TAG, "hkp keyserver get: " + query);              HttpGet get = new HttpGet(query);              HttpResponse response = client.execute(get); @@ -306,14 +314,14 @@ public class HkpKeyServer extends KeyServer {      }      @Override -    public void add(String armoredText) throws AddKeyException { +    public void add(String armoredKey) throws AddKeyException {          HttpClient client = new DefaultHttpClient();          try {              String query = "http://" + mHost + ":" + mPort + "/pks/add";              HttpPost post = new HttpPost(query);              Log.d(Constants.TAG, "hkp keyserver add: " + query);              List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); -            nameValuePairs.add(new BasicNameValuePair("keytext", armoredText)); +            nameValuePairs.add(new BasicNameValuePair("keytext", armoredKey));              post.setEntity(new UrlEncodedFormEntity(nameValuePairs));              HttpResponse response = client.execute(post); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java index a31fdc5ae..7f70867a5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java @@ -46,7 +46,7 @@ public abstract class KeyServer {      abstract List<ImportKeysListEntry> search(String query) throws QueryException, TooManyResponses,              InsufficientQuery; -    abstract String get(long keyId) throws QueryException; +    abstract String get(String keyIdHex) throws QueryException; -    abstract void add(String armoredText) throws AddKeyException; +    abstract void add(String armoredKey) throws AddKeyException;  } diff --git a/OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml b/OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml index 3cc0bc6dc..fb092793b 100644 --- a/OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml +++ b/OpenPGP-Keychain/src/main/res/layout/import_keys_list_entry.xml @@ -77,10 +77,11 @@              <TextView                  android:id="@+id/keyId"                  android:layout_width="wrap_content" -                android:layout_height="fill_parent" -                android:text="BBBBBBBB" +                android:layout_height="wrap_content" +                android:text="0xBBBBBBBBBBBBBBBB"                  android:textAppearance="?android:attr/textAppearanceSmall" -                android:typeface="monospace" /> +                android:typeface="monospace" +                android:layout_weight="1" />              <TextView                  android:id="@+id/algorithm" | 
