diff options
Diffstat (limited to 'OpenKeychain/src/main/java')
22 files changed, 456 insertions, 246 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java index 8f967499e..49e4d9793 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java @@ -114,6 +114,15 @@ public class WrappedUserAttribute implements Serializable {      } +    public byte[][] getSubpackets() { +        UserAttributeSubpacket[] subpackets = mVector.toSubpacketArray(); +        byte[][] ret = new byte[subpackets.length][]; +        for (int i = 0; i < subpackets.length; i++) { +            ret[i] = subpackets[i].getData(); +        } +        return ret; +    } +      private void readObjectNoData() throws ObjectStreamException {      } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java index 6228b29ec..fb3f2433a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java @@ -19,27 +19,10 @@ import java.util.Set;  import java.util.regex.Matcher;  import java.util.regex.Pattern; -public abstract class LinkedCookieResource { - -    protected final URI mSubUri; -    protected final Set<String> mFlags; -    protected final HashMap<String,String> mParams; - -    static Pattern magicPattern = -            Pattern.compile("\\[Verifying my PGP key: openpgp4fpr:([a-zA-Z0-9]+)#([a-zA-Z0-9]+)\\]"); +public abstract class LinkedCookieResource extends LinkedResource {      protected LinkedCookieResource(Set<String> flags, HashMap<String, String> params, URI uri) { -        mFlags = flags; -        mParams = params; -        mSubUri = uri; -    } - -    public Set<String> getFlags () { -        return new HashSet<String>(mFlags); -    } - -    public HashMap<String,String> getParams () { -        return new HashMap<String,String>(mParams); +        super(flags, params, uri);      }      public URI toUri () { @@ -82,10 +65,10 @@ public abstract class LinkedCookieResource {          return mSubUri;      } -    public static String generate (Context context, byte[] fingerprint, String nonce) { +    public static String generate (Context context, byte[] fingerprint, int nonce) {          return "[Verifying my PGP key: openpgp4fpr:" -                + KeyFormattingUtils.convertFingerprintToHex(fingerprint) + "#" + nonce + "]"; +                + KeyFormattingUtils.convertFingerprintToHex(fingerprint) + "#" + Integer.toHexString(nonce) + "]";      } @@ -129,7 +112,17 @@ public abstract class LinkedCookieResource {          }          String candidateFp = match.group(1).toLowerCase(); -        int nonceCandidate = Integer.parseInt(match.group(2).toLowerCase(), 16); +        try { +            int nonceCandidate = Integer.parseInt(match.group(2).toLowerCase(), 16); + +            if (nonce != nonceCandidate) { +                log.add(LogType.MSG_LV_NONCE_ERROR, indent); +                return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); +            } +        } catch (NumberFormatException e) { +            log.add(LogType.MSG_LV_NONCE_ERROR, indent); +            return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); +        }          String fp = KeyFormattingUtils.convertFingerprintToHex(fingerprint); @@ -139,72 +132,9 @@ public abstract class LinkedCookieResource {          }          log.add(LogType.MSG_LV_FP_OK, indent); -        if (nonce != nonceCandidate) { -            log.add(LogType.MSG_LV_NONCE_ERROR, indent); -            return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); -        } -          log.add(LogType.MSG_LV_NONCE_OK, indent);          return new LinkedVerifyResult(LinkedVerifyResult.RESULT_OK, log);      } -    protected static LinkedCookieResource fromRawLinkedId (RawLinkedIdentity id) { -        return fromUri(id.mNonce, id.mUri); -    } - -    protected static LinkedCookieResource fromUri (int nonce, URI uri) { - -        if ("pgpid".equals(uri.getScheme())) { -            Log.e(Constants.TAG, "unknown uri scheme in (suspected) linked id packet"); -            return null; -        } - -        if (!uri.isOpaque()) { -            Log.e(Constants.TAG, "non-opaque uri in (suspected) linked id packet"); -            return null; -        } - -        String specific = uri.getSchemeSpecificPart(); -        if (!specific.contains("@")) { -            Log.e(Constants.TAG, "unknown uri scheme in linked id packet"); -            return null; -        } - -        String[] pieces = specific.split("@", 2); -        URI subUri = URI.create(pieces[1]); - -        Set<String> flags = new HashSet<String>(); -        HashMap<String,String> params = new HashMap<String,String>(); -        { -            String[] rawParams = pieces[0].split(";"); -            for (String param : rawParams) { -                String[] p = param.split("=", 2); -                if (p.length == 1) { -                    flags.add(param); -                } else { -                    params.put(p[0], p[1]); -                } -            } -        } - -        return findResourceType(nonce, flags, params, subUri); - -    } - -    protected static LinkedCookieResource findResourceType (int nonce, Set<String> flags, -                                                            HashMap<String,String> params, -                                                            URI  subUri) { - -        LinkedCookieResource res; - -        res = GenericHttpsResource.create(flags, params, subUri); -        if (res != null) { -            return res; -        } - -        return new UnknownResource(flags, params, subUri); - -    } -  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java new file mode 100644 index 000000000..f06a23681 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java @@ -0,0 +1,75 @@ +package org.sufficientlysecure.keychain.pgp.linked; + +import org.spongycastle.bcpg.UserAttributeSubpacket; +import org.spongycastle.util.Strings; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.IOException; +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.Arrays; + +public class LinkedIdentity extends RawLinkedIdentity { + +    public final LinkedResource mResource; + +    protected LinkedIdentity(int nonce, URI uri, LinkedResource resource) { +        super(nonce, uri); +        if (resource == null) { +            throw new AssertionError("resource must not be null in a LinkedIdentity!"); +        } +        mResource = resource; +    } + +    public static RawLinkedIdentity fromAttributeData(byte[] data) throws IOException { +        WrappedUserAttribute att = WrappedUserAttribute.fromData(data); + +        byte[][] subpackets = att.getSubpackets(); +        if (subpackets.length >= 1) { +            return fromSubpacketData(subpackets[0]); +        } + +        throw new IOException("no subpacket data"); +    } + +    /** This method parses a linked id from a UserAttributeSubpacket, or returns null if the +     * subpacket can not be parsed as a valid linked id. +     */ +    static RawLinkedIdentity fromAttributeSubpacket(UserAttributeSubpacket subpacket) { +        if (subpacket.getType() != 100) { +            return null; +        } + +        byte[] data = subpacket.getData(); + +        return fromSubpacketData(data); + +    } + +    static RawLinkedIdentity fromSubpacketData(byte[] data) { + +        try { +            int nonce = ByteBuffer.wrap(data).getInt(); +            String uriStr = Strings.fromUTF8ByteArray(Arrays.copyOfRange(data, 4, data.length)); +            URI uri = URI.create(uriStr); + +            LinkedResource res = LinkedResource.fromUri(uri); +            if (res == null) { +                return new RawLinkedIdentity(nonce, uri); +            } + +            return new LinkedIdentity(nonce, uri, res); + +        } catch (IllegalArgumentException e) { +            Log.e(Constants.TAG, "error parsing uri in (suspected) linked id packet"); +            return null; +        } +    } + +    public static RawLinkedIdentity fromResource (LinkedCookieResource res, int nonce) { +        return new RawLinkedIdentity(nonce, res.toUri()); +    } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java new file mode 100644 index 000000000..6077db606 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java @@ -0,0 +1,101 @@ +package org.sufficientlysecure.keychain.pgp.linked; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource; +import org.sufficientlysecure.keychain.pgp.linked.resources.GenericHttpsResource; +import org.sufficientlysecure.keychain.pgp.linked.resources.UnknownResource; +import org.sufficientlysecure.keychain.util.Log; + +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; + +public abstract class LinkedResource { + +    protected final URI mSubUri; +    protected final Set<String> mFlags; +    protected final HashMap<String,String> mParams; + +    static Pattern magicPattern = +            Pattern.compile("\\[Verifying my PGP key: openpgp4fpr:([a-zA-Z0-9]+)#([a-zA-Z0-9]+)\\]"); + +    protected LinkedResource(Set<String> flags, HashMap<String, String> params, URI uri) { +        mFlags = flags; +        mParams = params; +        mSubUri = uri; +    } + +    public abstract URI toUri(); + +    public Set<String> getFlags () { +        return new HashSet<>(mFlags); +    } + +    public HashMap<String,String> getParams () { +        return new HashMap<>(mParams); +    } + +    protected static LinkedCookieResource fromUri (URI uri) { + +        if ("pgpid+cookie".equals(uri.getScheme())) { +            Log.e(Constants.TAG, "unknown uri scheme in (suspected) linked id packet"); +            return null; +        } + +        if (!uri.isOpaque()) { +            Log.e(Constants.TAG, "non-opaque uri in (suspected) linked id packet"); +            return null; +        } + +        String specific = uri.getSchemeSpecificPart(); +        if (!specific.contains("@")) { +            Log.e(Constants.TAG, "unknown uri scheme in linked id packet"); +            return null; +        } + +        String[] pieces = specific.split("@", 2); +        URI subUri = URI.create(pieces[1]); + +        Set<String> flags = new HashSet<String>(); +        HashMap<String,String> params = new HashMap<String,String>(); +        { +            String[] rawParams = pieces[0].split(";"); +            for (String param : rawParams) { +                String[] p = param.split("=", 2); +                if ("".equals(p[0])) { +                    continue; +                } +                if (p.length == 1) { +                    flags.add(param); +                } else { +                    params.put(p[0], p[1]); +                } +            } +        } + +        return findResourceType(flags, params, subUri); + +    } + +    protected static LinkedCookieResource findResourceType (Set<String> flags, +                                                            HashMap<String,String> params, +                                                            URI  subUri) { + +        LinkedCookieResource res; + +        res = GenericHttpsResource.create(flags, params, subUri); +        if (res != null) { +            return res; +        } +        res = DnsResource.create(flags, params, subUri); +        if (res != null) { +            return res; +        } + +        return null; + +    } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java index 931f2ec6b..bfde3c3b9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java @@ -1,18 +1,10 @@  package org.sufficientlysecure.keychain.pgp.linked; -import org.spongycastle.bcpg.UserAttributeSubpacket;  import org.spongycastle.util.Strings; -import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; -import org.sufficientlysecure.keychain.util.Log;  import java.net.URI;  import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map.Entry; -import java.util.Set;  /** The RawLinkedIdentity contains raw parsed data from a Linked Identity subpacket. */  public class RawLinkedIdentity { @@ -36,50 +28,18 @@ public class RawLinkedIdentity {          return buf.array();      } -    /** This method parses a linked id from a UserAttributeSubpacket, or returns null if the -     * subpacket can not be parsed as a valid linked id. -     */ -    static RawLinkedIdentity fromAttributeSubpacket(UserAttributeSubpacket subpacket) { -        if (subpacket.getType() != 100) { -            return null; -        } - -        byte[] data = subpacket.getData(); - -        return fromSubpacketData(data); - -    } - -    public static RawLinkedIdentity fromSubpacketData(byte[] data) { - -        try { -            int nonce = ByteBuffer.wrap(data).getInt(); -            String uri = Strings.fromUTF8ByteArray(Arrays.copyOfRange(data, 4, data.length)); - -            return new RawLinkedIdentity(nonce, URI.create(uri)); - -        } catch (IllegalArgumentException e) { -            Log.e(Constants.TAG, "error parsing uri in (suspected) linked id packet"); -            return null; -        } -    } - -    public static RawLinkedIdentity fromResource (LinkedCookieResource res, int nonce) { -        return new RawLinkedIdentity(nonce, res.toUri()); -    } -      public WrappedUserAttribute toUserAttribute () {          return WrappedUserAttribute.fromSubpacket(WrappedUserAttribute.UAT_LINKED_ID, getEncoded());      } -    public static String generateNonce() { +    public static int generateNonce() {          // TODO make this actually random          // byte[] data = new byte[4];          // new SecureRandom().nextBytes(data);          // return Hex.toHexString(data);          // debug for now -        return "01234567"; +        return 1234567;      }  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java index 796e2f120..5df008ed7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java @@ -39,10 +39,11 @@ public class DnsResource extends LinkedCookieResource {          mType = type;      } -    public static String generateText (Context context, byte[] fingerprint, String nonce) { +    public static String generateText (Context context, byte[] fingerprint, int nonce) {          return "pgpid+cookie=" -                + KeyFormattingUtils.convertFingerprintToHex(fingerprint) + ";" + nonce + ""; +                + KeyFormattingUtils.convertFingerprintToHex(fingerprint) + ";" +                + Integer.toHexString(nonce) + "";      } @@ -81,6 +82,10 @@ public class DnsResource extends LinkedCookieResource {          return new DnsResource(flags, params, uri, fqdn, clazz, type);      } +    public String getFqdn() { +        return mFqdn; +    } +      @Override      protected String fetchResource (OperationLog log, int indent) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java index a0f1cf0aa..ba94bae75 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java @@ -28,7 +28,7 @@ public class GenericHttpsResource extends LinkedCookieResource {          super(flags, params, uri);      } -    public static String generateText (Context context, byte[] fingerprint, String nonce) { +    public static String generateText (Context context, byte[] fingerprint, int nonce) {          String cookie = LinkedCookieResource.generate(context, fingerprint, nonce);          return String.format(context.getResources().getString(R.string.linked_id_generic_text), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java index 84277380d..f6ec4f97a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java @@ -35,7 +35,7 @@ public class TwitterResource extends LinkedCookieResource {          super(flags, params, uri);      } -    public static String generateText (Context context, byte[] fingerprint, String nonce) { +    public static String generateText (Context context, byte[] fingerprint, int nonce) {          // nothing special here for now, might change this later          return LinkedCookieResource.generate(context, fingerprint, nonce);      } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index b88cd6006..4a162989f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -53,7 +53,7 @@ import java.io.IOException;   */  public class KeychainDatabase extends SQLiteOpenHelper {      private static final String DATABASE_NAME = "openkeychain.db"; -    private static final int DATABASE_VERSION = 8; +    private static final int DATABASE_VERSION = 9;      static Boolean apgHack = false;      private Context mContext; @@ -61,7 +61,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {          String KEY_RINGS_PUBLIC = "keyrings_public";          String KEY_RINGS_SECRET = "keyrings_secret";          String KEYS = "keys"; -        String USER_PACKETS = "user_ids"; +        String USER_PACKETS = "user_packets";          String CERTS = "certs";          String API_APPS = "api_apps";          String API_ACCOUNTS = "api_accounts"; @@ -119,8 +119,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {                  + UserPacketsColumns.IS_REVOKED + " INTEGER, "                  + UserPacketsColumns.RANK+ " INTEGER, " -                + "PRIMARY KEY(" + UserPacketsColumns.MASTER_KEY_ID + ", " + UserPacketsColumns.USER_ID + "), " -                + "UNIQUE (" + UserPacketsColumns.MASTER_KEY_ID + ", " + UserPacketsColumns.RANK + "), " +                + "PRIMARY KEY(" + UserPacketsColumns.MASTER_KEY_ID + ", " + UserPacketsColumns.RANK + "), "                  + "FOREIGN KEY(" + UserPacketsColumns.MASTER_KEY_ID + ") REFERENCES "                      + Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"              + ")"; @@ -267,6 +266,13 @@ public class KeychainDatabase extends SQLiteOpenHelper {                  } catch (Exception e) {                      // never mind, the column probably already existed                  } +            case 9: +                // tbale name for user_ids changed to user_packets +                db.execSQL("DROP TABLE IF EXISTS certs"); +                db.execSQL("DROP TABLE IF EXISTS user_ids"); +                db.execSQL(CREATE_USER_PACKETS); +                db.execSQL(CREATE_CERTS); +          }          // always do consolidate after upgrade diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 3aa156a8e..31ed89d67 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -62,6 +62,7 @@ public class KeychainProvider extends ContentProvider {      private static final int KEY_RING_SECRET = 204;      private static final int KEY_RING_CERTS = 205;      private static final int KEY_RING_CERTS_SPECIFIC = 206; +    private static final int KEY_RING_LINKED_IDS = 207;      private static final int API_APPS = 301;      private static final int API_APPS_BY_PACKAGE_NAME = 302; @@ -127,6 +128,7 @@ public class KeychainProvider extends ContentProvider {           * key_rings/_/unified           * key_rings/_/keys           * key_rings/_/user_ids +         * key_rings/_/linked_ids           * key_rings/_/public           * key_rings/_/secret           * key_rings/_/certs @@ -143,6 +145,9 @@ public class KeychainProvider extends ContentProvider {                  + KeychainContract.PATH_USER_IDS,                  KEY_RING_USER_IDS);          matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/" +                        + KeychainContract.PATH_LINKED_IDS, +                KEY_RING_LINKED_IDS); +        matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"                  + KeychainContract.PATH_PUBLIC,                  KEY_RING_PUBLIC);          matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/" @@ -469,7 +474,8 @@ public class KeychainProvider extends ContentProvider {              }              case KEY_RINGS_USER_IDS: -            case KEY_RING_USER_IDS: { +            case KEY_RING_USER_IDS: +            case KEY_RING_LINKED_IDS: {                  HashMap<String, String> projectionMap = new HashMap<>();                  projectionMap.put(UserPackets._ID, Tables.USER_PACKETS + ".oid AS _id");                  projectionMap.put(UserPackets.MASTER_KEY_ID, Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID); @@ -494,13 +500,14 @@ public class KeychainProvider extends ContentProvider {                  groupBy = Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID                          + ", " + Tables.USER_PACKETS + "." + UserPackets.RANK; -                // for now, we only respect user ids here, so TYPE must be NULL -                // TODO expand with KEY_RING_USER_PACKETS query type which lifts this restriction -                qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL"); +                if (match == KEY_RING_LINKED_IDS) { +                    qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " = 100"); +                } else { +                    qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL"); +                }                  // If we are searching for a particular keyring's ids, add where -                if (match == KEY_RING_USER_IDS) { -                    // TODO remove with the thing above +                if (match == KEY_RING_USER_IDS || match == KEY_RING_LINKED_IDS) {                      qb.appendWhere(" AND ");                      qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " = ");                      qb.appendWhereEscapeString(uri.getPathSegments().get(1)); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 8a9f36c03..2ff4803fb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -1082,9 +1082,8 @@ public class ProviderHelper {              log.add(LogType.MSG_CON_SAVE_SECRET, indent);              indent += 1; -            final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[]{ -                    KeyRings.PRIVKEY_DATA, KeyRings.FINGERPRINT, KeyRings.HAS_ANY_SECRET -            }, KeyRings.HAS_ANY_SECRET + " = 1", null, null); +            final Cursor cursor = mContentResolver.query(KeyRingData.buildSecretKeyRingUri(), +                    new String[]{ KeyRingData.KEY_RING_DATA }, null, null, null);              if (cursor == null) {                  log.add(LogType.MSG_CON_ERROR_DB, indent); @@ -1106,8 +1105,7 @@ public class ProviderHelper {                      if (cursor.isAfterLast()) {                          return false;                      } -                    ring = new ParcelableKeyRing(KeyFormattingUtils.convertFingerprintToHex(cursor.getBlob(1)), cursor.getBlob(0) -                    ); +                    ring = new ParcelableKeyRing(cursor.getBlob(0));                      cursor.moveToNext();                      return true;                  } @@ -1144,9 +1142,9 @@ public class ProviderHelper {              log.add(LogType.MSG_CON_SAVE_PUBLIC, indent);              indent += 1; -            final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[]{ -                    KeyRings.PUBKEY_DATA, KeyRings.FINGERPRINT -            }, null, null, null); +            final Cursor cursor = mContentResolver.query( +                    KeyRingData.buildPublicKeyRingUri(), +                    new String[]{ KeyRingData.KEY_RING_DATA }, null, null, null);              if (cursor == null) {                  log.add(LogType.MSG_CON_ERROR_DB, indent); @@ -1168,8 +1166,7 @@ public class ProviderHelper {                      if (cursor.isAfterLast()) {                          return false;                      } -                    ring = new ParcelableKeyRing(KeyFormattingUtils.convertFingerprintToHex(cursor.getBlob(1)), cursor.getBlob(0) -                    ); +                    ring = new ParcelableKeyRing(cursor.getBlob(0));                      cursor.moveToNext();                      return true;                  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 6b1d87941..51dec767c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -281,7 +281,7 @@ public class ViewKeyActivity extends BaseActivity implements          // Add the fragment to the 'fragment_container' FrameLayout          // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!          getSupportFragmentManager().beginTransaction() -                .replace(R.id.view_key_fragment, frag) +                .replace(R.id.view_key_fragment, frag, "main")                  .commitAllowingStateLoss();          // do it immediately!          getSupportFragmentManager().executePendingTransactions(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java index c6df016ff..20386b372 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java @@ -20,15 +20,22 @@ package org.sufficientlysecure.keychain.ui;  import android.database.Cursor;  import android.net.Uri; +import android.os.Build;  import android.os.Bundle; +import android.support.v4.app.Fragment;  import android.support.v4.app.LoaderManager;  import android.support.v4.content.CursorLoader;  import android.support.v4.content.Loader;  import android.support.v7.widget.CardView; +import android.transition.Explode; +import android.transition.Fade; +import android.transition.Transition; +import android.transition.TransitionInflater;  import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;  import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener;  import android.widget.ListView;  import org.sufficientlysecure.keychain.Constants; @@ -91,11 +98,34 @@ public class ViewKeyFragment extends LoaderFragment implements                  showUserIdInfo(position);              }          }); -        mLinkedIdsCard.setVisibility(View.GONE); +        mLinkedIds.setOnItemClickListener(new OnItemClickListener() { +            @Override +            public void onItemClick(AdapterView<?> parent, View view, int position, long id) { +                showLinkedId(position); +            } +        });          return root;      } +    private void showLinkedId(final int position) { +        Fragment frag = mLinkedIdsAdapter.getLinkedIdFragment(position); + +        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { +            Transition trans = TransitionInflater.from(getActivity()) +                            .inflateTransition(R.transition.linked_id_card_trans); +            // setSharedElementReturnTransition(trans); +            setExitTransition(new Fade()); +            frag.setSharedElementEnterTransition(trans); +        } + +        getFragmentManager().beginTransaction() +                .replace(R.id.view_key_fragment, frag) +                .addSharedElement(mLinkedIdsCard, "card_linked_ids") +                .addToBackStack(null) +                .commit(); +    } +      private void showUserIdInfo(final int position) {          if (!mIsSecret) {              final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position); @@ -140,10 +170,8 @@ public class ViewKeyFragment extends LoaderFragment implements          Log.i(Constants.TAG, "mDataUri: " + mDataUri); -        // Prepare the loaders. Either re-connect with an existing ones, -        // or start new ones. -        // TODO Is this loader the same as the one in the activity?          getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); +        getLoaderManager().initLoader(LOADER_ID_LINKED_IDS, null, this);      }      public Loader<Cursor> onCreateLoader(int id, Bundle args) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/LinkedIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/LinkedIdsAdapter.java index 1e4968615..a44358172 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/LinkedIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/LinkedIdsAdapter.java @@ -21,24 +21,35 @@ package org.sufficientlysecure.keychain.ui.adapter;  import android.app.Activity;  import android.content.Context;  import android.database.Cursor; -import android.graphics.Typeface;  import android.net.Uri; +import android.support.v4.app.Fragment;  import android.support.v4.content.CursorLoader; +import android.util.Log;  import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;  import android.widget.ImageView;  import android.widget.TextView; +import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.pgp.linked.LinkedIdentity; +import org.sufficientlysecure.keychain.pgp.linked.LinkedResource;  import org.sufficientlysecure.keychain.pgp.linked.RawLinkedIdentity; +import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource;  import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;  import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; +import org.sufficientlysecure.keychain.ui.ViewKeyFragment; +import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment;  import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import java.io.IOException; +import java.util.WeakHashMap; + +  public class LinkedIdsAdapter extends UserAttributesAdapter {      protected LayoutInflater mInflater; +    WeakHashMap<Integer,RawLinkedIdentity> mLinkedIdentityCache = new WeakHashMap<>();      public LinkedIdsAdapter(Context context, Cursor c, int flags) {          super(context, c, flags); @@ -46,106 +57,94 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {      }      @Override +    public void bindView(View view, Context context, Cursor cursor) { + +        RawLinkedIdentity id = getItem(cursor.getPosition()); +        ViewHolder holder = (ViewHolder) view.getTag(); + +        int isVerified = cursor.getInt(INDEX_VERIFIED); +        switch (isVerified) { +            case Certs.VERIFIED_SECRET: +                KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, +                        null, KeyFormattingUtils.STATE_VERIFIED, KeyFormattingUtils.DEFAULT_COLOR); +                break; +            case Certs.VERIFIED_SELF: +                KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, +                        null, KeyFormattingUtils.STATE_UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR); +                break; +            default: +                KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, +                        null, KeyFormattingUtils.STATE_INVALID, KeyFormattingUtils.DEFAULT_COLOR); +                break; +        } + +        if (holder instanceof ViewHolderNonRaw) { +            ((ViewHolderNonRaw) holder).setData(mContext, (LinkedIdentity) id); +        } + +    } + +    @Override      public int getItemViewType(int position) { -        RawLinkedIdentity id = (RawLinkedIdentity) getItem(position); +        RawLinkedIdentity id = getItem(position); -        // TODO return different ids by type +        if (id instanceof LinkedIdentity) { +            LinkedResource res = ((LinkedIdentity) id).mResource; +            if (res instanceof DnsResource) { +                return 1; +            } +        }          return 0;      }      @Override      public int getViewTypeCount() { -        return 1; +        return 2;      }      @Override -    public Object getItem(int position) { +    public RawLinkedIdentity getItem(int position) { +        RawLinkedIdentity ret = mLinkedIdentityCache.get(position); +        if (ret != null) { +            return ret; +        } +          Cursor c = getCursor();          c.moveToPosition(position);          byte[] data = c.getBlob(INDEX_ATTRIBUTE_DATA); -        RawLinkedIdentity identity = RawLinkedIdentity.fromSubpacketData(data); - -        return identity; +        try { +            ret = LinkedIdentity.fromAttributeData(data); +            mLinkedIdentityCache.put(position, ret); +            return ret; +        } catch (IOException e) { +            Log.e(Constants.TAG, "could not read linked identity subpacket data", e); +            return null; +        }      }      @Override -    public void bindView(View view, Context context, Cursor cursor) { -        TextView vName = (TextView) view.findViewById(R.id.user_id_item_name); -        TextView vAddress = (TextView) view.findViewById(R.id.user_id_item_address); -        TextView vComment = (TextView) view.findViewById(R.id.user_id_item_comment); -        ImageView vVerified = (ImageView) view.findViewById(R.id.user_id_item_certified); -        View vVerifiedLayout = view.findViewById(R.id.user_id_item_certified_layout); -        ImageView vEditImage = (ImageView) view.findViewById(R.id.user_id_item_edit_image); -        ImageView vDeleteButton = (ImageView) view.findViewById(R.id.user_id_item_delete_button); -        vDeleteButton.setVisibility(View.GONE); // not used - -        String userId = cursor.getString(INDEX_USER_ID); -        String[] splitUserId = KeyRing.splitUserId(userId); -        if (splitUserId[0] != null) { -            vName.setText(splitUserId[0]); -        } else { -            vName.setText(R.string.user_id_no_name); -        } -        if (splitUserId[1] != null) { -            vAddress.setText(splitUserId[1]); -            vAddress.setVisibility(View.VISIBLE); -        } else { -            vAddress.setVisibility(View.GONE); -        } -        if (splitUserId[2] != null) { -            vComment.setText(splitUserId[2]); -            vComment.setVisibility(View.VISIBLE); -        } else { -            vComment.setVisibility(View.GONE); -        } - -        boolean isPrimary = cursor.getInt(INDEX_IS_PRIMARY) != 0; -        boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0; -        vVerifiedLayout.setVisibility(View.VISIBLE); - -        if (isRevoked) { -            // set revocation icon (can this even be primary?) -            KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray); - -            // disable revoked user ids -            vName.setEnabled(false); -            vAddress.setEnabled(false); -            vComment.setEnabled(false); -        } else { -            vName.setEnabled(true); -            vAddress.setEnabled(true); -            vComment.setEnabled(true); - -            if (isPrimary) { -                vName.setTypeface(null, Typeface.BOLD); -                vAddress.setTypeface(null, Typeface.BOLD); -            } else { -                vName.setTypeface(null, Typeface.NORMAL); -                vAddress.setTypeface(null, Typeface.NORMAL); +    public View newView(Context context, Cursor cursor, ViewGroup parent) { +        int type = getItemViewType(cursor.getPosition()); +        switch(type) { +            case 0: { +                View v = mInflater.inflate(R.layout.linked_id_item_unknown, null); +                ViewHolder holder = new ViewHolder(v); +                v.setTag(holder); +                return v;              } - -            int isVerified = cursor.getInt(INDEX_VERIFIED); -            switch (isVerified) { -                case Certs.VERIFIED_SECRET: -                    KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_VERIFIED, KeyFormattingUtils.DEFAULT_COLOR); -                    break; -                case Certs.VERIFIED_SELF: -                    KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR); -                    break; -                default: -                    KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_INVALID, KeyFormattingUtils.DEFAULT_COLOR); -                    break; +            case 1: { +                View v = mInflater.inflate(R.layout.linked_id_item_dns, null); +                ViewHolder holder = new ViewHolderDns(v); +                v.setTag(holder); +                return v;              } +            default: +                throw new AssertionError("all cases must be covered in LinkedIdsAdapter.newView!");          }      } -    @Override -    public View newView(Context context, Cursor cursor, ViewGroup parent) { -        return mInflater.inflate(R.layout.view_key_adv_user_id_item, null); -    } -      // don't show revoked user ids, irrelevant for average users      public static final String LINKED_IDS_WHERE = UserPackets.IS_REVOKED + " = 0"; @@ -155,4 +154,48 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {                  UserIdsAdapter.USER_PACKETS_PROJECTION, LINKED_IDS_WHERE, null, null);      } +    public Fragment getLinkedIdFragment(int position) { +        RawLinkedIdentity id = getItem(position); + +        return LinkedIdViewFragment.newInstance(id); +    } + +    static class ViewHolder { +        ImageView vVerified; + +        ViewHolder(View view) { +            vVerified = (ImageView) view.findViewById(R.id.user_id_item_certified); +        } +    } + +    static abstract class ViewHolderNonRaw extends ViewHolder { +        ViewHolderNonRaw(View view) { +            super(view); +        } + +        abstract void setData(Context context, LinkedIdentity id); +    } + +    static class ViewHolderDns extends ViewHolderNonRaw { +        TextView vFqdn; + +        ViewHolderDns(View view) { +            super(view); + +            vFqdn = (TextView) view.findViewById(R.id.linked_id_dns_fqdn); +        } + +        @Override +        void setData(Context context, LinkedIdentity id) { +            DnsResource res = (DnsResource) id.mResource; +            vFqdn.setText(res.getFqdn()); +        } + +    } + +    @Override +    public void notifyDataSetChanged() { +        mLinkedIdentityCache.clear(); +        super.notifyDataSetChanged(); +    }  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java index 3bc1b200b..345ccccc0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java @@ -48,4 +48,5 @@ public abstract class UserAttributesAdapter extends CursorAdapter {          mCursor.moveToPosition(position);          return mCursor.getInt(INDEX_VERIFIED);      } +  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep1Fragment.java index 14d5f3b5d..26b0a0539 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep1Fragment.java @@ -73,7 +73,7 @@ public class LinkedIdCreateDnsStep1Fragment extends Fragment {                      return;                  } -                String proofNonce = RawLinkedIdentity.generateNonce(); +                int proofNonce = RawLinkedIdentity.generateNonce();                  String proofText = DnsResource.generateText(getActivity(),                          mLinkedIdWizard.mFingerprint, proofNonce); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep2Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep2Fragment.java index 6c9110ffd..71a3673f2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep2Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep2Fragment.java @@ -41,6 +41,7 @@ import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult;  import org.sufficientlysecure.keychain.operations.results.OperationResult;  import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; +import org.sufficientlysecure.keychain.pgp.linked.LinkedIdentity;  import org.sufficientlysecure.keychain.pgp.linked.RawLinkedIdentity;  import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource;  import org.sufficientlysecure.keychain.service.KeychainIntentService; @@ -80,13 +81,13 @@ public class LinkedIdCreateDnsStep2Fragment extends Fragment {       * Creates new instance of this fragment       */      public static LinkedIdCreateDnsStep2Fragment newInstance -            (String uri, String proofNonce, String proofText) { +            (String uri, int proofNonce, String proofText) {          LinkedIdCreateDnsStep2Fragment frag = new LinkedIdCreateDnsStep2Fragment();          Bundle args = new Bundle();          args.putString(DOMAIN, uri); -        args.putString(NONCE, proofNonce); +        args.putInt(NONCE, proofNonce);          args.putString(TEXT, proofText);          frag.setArguments(args); @@ -237,6 +238,7 @@ public class LinkedIdCreateDnsStep2Fragment extends Fragment {                      mVerifiedResource = resource;                  } else {                      setVerifyProgress(false, false); +                    mVerifiedResource = resource;                      // on error, show error message                      result.createNotify(getActivity()).show();                  } @@ -308,7 +310,7 @@ public class LinkedIdCreateDnsStep2Fragment extends Fragment {                  new SaveKeyringParcel(mLinkedIdWizard.mMasterKeyId, mLinkedIdWizard.mFingerprint);          WrappedUserAttribute ua = -                RawLinkedIdentity.fromResource(mVerifiedResource, mResourceNonce).toUserAttribute(); +                LinkedIdentity.fromResource(mVerifiedResource, mResourceNonce).toUserAttribute();          skp.mAddUserAttribute.add(ua); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep1Fragment.java index 9fe1d43a3..78ca4cfe9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep1Fragment.java @@ -72,7 +72,7 @@ public class LinkedIdCreateHttpsStep1Fragment extends Fragment {                      return;                  } -                String proofNonce = RawLinkedIdentity.generateNonce(); +                int proofNonce = RawLinkedIdentity.generateNonce();                  String proofText = GenericHttpsResource.generateText(getActivity(),                          mLinkedIdWizard.mFingerprint, proofNonce); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java index f3fcc4410..78c7caf53 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java @@ -42,6 +42,7 @@ import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult;  import org.sufficientlysecure.keychain.operations.results.OperationResult;  import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; +import org.sufficientlysecure.keychain.pgp.linked.LinkedIdentity;  import org.sufficientlysecure.keychain.pgp.linked.RawLinkedIdentity;  import org.sufficientlysecure.keychain.pgp.linked.resources.GenericHttpsResource;  import org.sufficientlysecure.keychain.service.KeychainIntentService; @@ -83,13 +84,13 @@ public class LinkedIdCreateHttpsStep2Fragment extends Fragment {       * Creates new instance of this fragment       */      public static LinkedIdCreateHttpsStep2Fragment newInstance -            (String uri, String proofNonce, String proofText) { +            (String uri, int proofNonce, String proofText) {          LinkedIdCreateHttpsStep2Fragment frag = new LinkedIdCreateHttpsStep2Fragment();          Bundle args = new Bundle();          args.putString(URI, uri); -        args.putString(NONCE, proofNonce); +        args.putInt(NONCE, proofNonce);          args.putString(TEXT, proofText);          frag.setArguments(args); @@ -315,7 +316,7 @@ public class LinkedIdCreateHttpsStep2Fragment extends Fragment {                  new SaveKeyringParcel(mLinkedIdWizard.mMasterKeyId, mLinkedIdWizard.mFingerprint);          WrappedUserAttribute ua = -                RawLinkedIdentity.fromResource(mVerifiedResource, mResourceNonce).toUserAttribute(); +                LinkedIdentity.fromResource(mVerifiedResource, mResourceNonce).toUserAttribute();          skp.mAddUserAttribute.add(ua); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java index 8113525be..e966fd71f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java @@ -92,7 +92,7 @@ public class LinkedIdCreateTwitterStep1Fragment extends Fragment {                              return;                          } -                        String proofNonce = RawLinkedIdentity.generateNonce(); +                        int proofNonce = RawLinkedIdentity.generateNonce();                          String proofText = TwitterResource.generateText(getActivity(),                                  mLinkedIdWizard.mFingerprint, proofNonce); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep2Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep2Fragment.java index ab56e7a5d..837b84d40 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep2Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep2Fragment.java @@ -52,13 +52,13 @@ public class LinkedIdCreateTwitterStep2Fragment extends Fragment {       * Creates new instance of this fragment       */      public static LinkedIdCreateTwitterStep2Fragment newInstance -            (String handle, String proofNonce, String proofText) { +            (String handle, int proofNonce, String proofText) {          LinkedIdCreateTwitterStep2Fragment frag = new LinkedIdCreateTwitterStep2Fragment();          Bundle args = new Bundle();          args.putString(HANDLE, handle); -        args.putString(NONCE, proofNonce); +        args.putInt(NONCE, proofNonce);          args.putString(TEXT, proofText);          frag.setArguments(args); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdViewFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdViewFragment.java new file mode 100644 index 000000000..0eb0dcd45 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdViewFragment.java @@ -0,0 +1,45 @@ +package org.sufficientlysecure.keychain.ui.linked; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v7.widget.CardView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.linked.RawLinkedIdentity; + + +public class LinkedIdViewFragment extends Fragment { + +    private CardView mLinkedIdsCard; + +    public static Fragment newInstance(RawLinkedIdentity id) { +        LinkedIdViewFragment frag = new LinkedIdViewFragment(); + +        Bundle args = new Bundle(); +        frag.setArguments(args); + +        return frag; +    } + +    @Override +    public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { +        View root = inflater.inflate(R.layout.linked_id_view_fragment, null); + +        mLinkedIdsCard = (CardView) root.findViewById(R.id.card_linked_ids); + +        root.findViewById(R.id.back_button).setClickable(true); +        root.findViewById(R.id.back_button).setOnClickListener(new OnClickListener() { +            @Override +            public void onClick(View v) { +                getFragmentManager().popBackStack(); +            } +        }); + +        return root; +    } + +}  | 
