aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2015-03-02 14:39:28 +0100
committerVincent Breitmoser <valodim@mugenguild.com>2015-03-02 14:39:28 +0100
commit2f83291920e024b0f8038fe0caa747051b41cf1c (patch)
tree780fc0975e56b3dbd8a1eb4cb2988ac3e2e23ea1 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider
parentaa22a0defcf94d5f734d3a00288f5c8d916d2e57 (diff)
parent4e29d027af05fc574dc5398d2fb3afcdf3defc70 (diff)
downloadopen-keychain-2f83291920e024b0f8038fe0caa747051b41cf1c.tar.gz
open-keychain-2f83291920e024b0f8038fe0caa747051b41cf1c.tar.bz2
open-keychain-2f83291920e024b0f8038fe0caa747051b41cf1c.zip
NON-WORKING Merge branch 'development' into linked-identities
Conflicts: OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java OpenKeychain/src/main/res/layout/view_key_main_fragment.xml OpenKeychain/src/main/res/values/strings.xml extern/spongycastle
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java22
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java26
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java62
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java124
4 files changed, 185 insertions, 49 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
index f4e00c36c..5856589c4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
@@ -85,6 +85,11 @@ public class KeychainContract {
String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name
}
+ interface ApiAppsAllowedKeysColumns {
+ String KEY_ID = "key_id"; // not a database id
+ String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name
+ }
+
public static final String CONTENT_AUTHORITY = Constants.PACKAGE_NAME + ".provider";
private static final Uri BASE_CONTENT_URI_INTERNAL = Uri
@@ -106,6 +111,7 @@ public class KeychainContract {
public static final String BASE_API_APPS = "api_apps";
public static final String PATH_ACCOUNTS = "accounts";
+ public static final String PATH_ALLOWED_KEYS = "allowed_keys";
public static class KeyRings implements BaseColumns, KeysColumns, UserPacketsColumns {
public static final String MASTER_KEY_ID = KeysColumns.MASTER_KEY_ID;
@@ -305,6 +311,22 @@ public class KeychainContract {
}
}
+ public static class ApiAllowedKeys implements ApiAppsAllowedKeysColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
+ .appendPath(BASE_API_APPS).build();
+
+ /**
+ * Use if multiple items get returned
+ */
+ public static final String CONTENT_TYPE
+ = "vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.api_apps.allowed_keys";
+
+ public static Uri buildBaseUri(String packageName) {
+ return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ALLOWED_KEYS)
+ .build();
+ }
+ }
+
public static class Certs implements CertsColumns, BaseColumns {
public static final String USER_ID = UserPacketsColumns.USER_ID;
public static final String SIGNER_UID = "signer_user_id";
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 5ce5eec17..b88cd6006 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
@@ -29,6 +29,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAllowedKeysColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.CertsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
@@ -52,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 = 7;
+ private static final int DATABASE_VERSION = 8;
static Boolean apgHack = false;
private Context mContext;
@@ -64,6 +65,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
String CERTS = "certs";
String API_APPS = "api_apps";
String API_ACCOUNTS = "api_accounts";
+ String API_ALLOWED_KEYS = "api_allowed_keys";
}
private static final String CREATE_KEYRINGS_PUBLIC =
@@ -166,6 +168,18 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE"
+ ")";
+ private static final String CREATE_API_APPS_ALLOWED_KEYS =
+ "CREATE TABLE IF NOT EXISTS " + Tables.API_ALLOWED_KEYS + " ("
+ + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + ApiAppsAllowedKeysColumns.KEY_ID + " INTEGER, "
+ + ApiAppsAllowedKeysColumns.PACKAGE_NAME + " TEXT NOT NULL, "
+
+ + "UNIQUE(" + ApiAppsAllowedKeysColumns.KEY_ID + ", "
+ + ApiAppsAllowedKeysColumns.PACKAGE_NAME + "), "
+ + "FOREIGN KEY(" + ApiAppsAllowedKeysColumns.PACKAGE_NAME + ") REFERENCES "
+ + Tables.API_APPS + "(" + ApiAppsAllowedKeysColumns.PACKAGE_NAME + ") ON DELETE CASCADE"
+ + ")";
+
KeychainDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
@@ -195,6 +209,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
db.execSQL(CREATE_CERTS);
db.execSQL(CREATE_API_APPS);
db.execSQL(CREATE_API_APPS_ACCOUNTS);
+ db.execSQL(CREATE_API_APPS_ALLOWED_KEYS);
}
@Override
@@ -243,6 +258,15 @@ public class KeychainDatabase extends SQLiteOpenHelper {
case 6:
db.execSQL("ALTER TABLE user_ids ADD COLUMN type INTEGER");
db.execSQL("ALTER TABLE user_ids ADD COLUMN attribute_data BLOB");
+ case 7:
+ // consolidate
+ case 8:
+ // new table for allowed key ids in API
+ try {
+ db.execSQL(CREATE_API_APPS_ALLOWED_KEYS);
+ } catch (Exception e) {
+ // never mind, the column probably already existed
+ }
}
// 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 29b9c5f9f..3aa156a8e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
@@ -32,6 +32,7 @@ import android.text.TextUtils;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
@@ -63,9 +64,10 @@ public class KeychainProvider extends ContentProvider {
private static final int KEY_RING_CERTS_SPECIFIC = 206;
private static final int API_APPS = 301;
- private static final int API_APPS_BY_PACKAGE_NAME = 303;
- private static final int API_ACCOUNTS = 304;
- private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306;
+ private static final int API_APPS_BY_PACKAGE_NAME = 302;
+ private static final int API_ACCOUNTS = 303;
+ private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 304;
+ private static final int API_ALLOWED_KEYS = 305;
private static final int KEY_RINGS_FIND_BY_EMAIL = 400;
private static final int KEY_RINGS_FIND_BY_SUBKEY = 401;
@@ -162,6 +164,8 @@ public class KeychainProvider extends ContentProvider {
*
* api_apps/_/accounts
* api_apps/_/accounts/_ (account name)
+ *
+ * api_apps/_/allowed_keys
* </pre>
*/
matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS);
@@ -172,6 +176,9 @@ public class KeychainProvider extends ContentProvider {
matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/"
+ KeychainContract.PATH_ACCOUNTS + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME);
+ matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/"
+ + KeychainContract.PATH_ALLOWED_KEYS, API_ALLOWED_KEYS);
+
return matcher;
}
@@ -223,6 +230,9 @@ public class KeychainProvider extends ContentProvider {
case API_ACCOUNTS_BY_ACCOUNT_NAME:
return ApiAccounts.CONTENT_ITEM_TYPE;
+ case API_ALLOWED_KEYS:
+ return ApiAllowedKeys.CONTENT_TYPE;
+
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
@@ -248,7 +258,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_UNIFIED:
case KEY_RINGS_FIND_BY_EMAIL:
case KEY_RINGS_FIND_BY_SUBKEY: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(KeyRings._ID, Tables.KEYS + ".oid AS _id");
projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
projectionMap.put(KeyRings.KEY_ID, Tables.KEYS + "." + Keys.KEY_ID);
@@ -432,7 +442,7 @@ public class KeychainProvider extends ContentProvider {
}
case KEY_RING_KEYS: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(Keys._ID, Tables.KEYS + ".oid AS _id");
projectionMap.put(Keys.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
projectionMap.put(Keys.RANK, Tables.KEYS + "." + Keys.RANK);
@@ -460,7 +470,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_USER_IDS:
case KEY_RING_USER_IDS: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ 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);
projectionMap.put(UserPackets.TYPE, Tables.USER_PACKETS + "." + UserPackets.TYPE);
@@ -507,7 +517,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_PUBLIC:
case KEY_RING_PUBLIC: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_PUBLIC + ".oid AS _id");
projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID);
projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA);
@@ -525,7 +535,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_SECRET:
case KEY_RING_SECRET: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_SECRET + ".oid AS _id");
projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID);
projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA);
@@ -543,7 +553,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RING_CERTS:
case KEY_RING_CERTS_SPECIFIC: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(Certs._ID, Tables.CERTS + ".oid AS " + Certs._ID);
projectionMap.put(Certs.MASTER_KEY_ID, Tables.CERTS + "." + Certs.MASTER_KEY_ID);
projectionMap.put(Certs.RANK, Tables.CERTS + "." + Certs.RANK);
@@ -614,6 +624,12 @@ public class KeychainProvider extends ContentProvider {
qb.appendWhereEscapeString(uri.getLastPathSegment());
break;
+ case API_ALLOWED_KEYS:
+ qb.setTables(Tables.API_ALLOWED_KEYS);
+ qb.appendWhere(Tables.API_ALLOWED_KEYS + "." + ApiAccounts.PACKAGE_NAME + " = ");
+ qb.appendWhereEscapeString(uri.getPathSegments().get(1));
+
+ break;
default:
throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")");
@@ -701,7 +717,7 @@ public class KeychainProvider extends ContentProvider {
db.insertOrThrow(Tables.API_APPS, null, values);
break;
- case API_ACCOUNTS:
+ case API_ACCOUNTS: {
// set foreign key automatically based on given uri
// e.g., api_apps/com.example.app/accounts/
String packageName = uri.getPathSegments().get(1);
@@ -709,12 +725,21 @@ public class KeychainProvider extends ContentProvider {
db.insertOrThrow(Tables.API_ACCOUNTS, null, values);
break;
+ }
+ case API_ALLOWED_KEYS: {
+ // set foreign key automatically based on given uri
+ // e.g., api_apps/com.example.app/allowed_keys/
+ String packageName = uri.getPathSegments().get(1);
+ values.put(ApiAllowedKeys.PACKAGE_NAME, packageName);
+ db.insertOrThrow(Tables.API_ALLOWED_KEYS, null, values);
+ break;
+ }
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
- if(keyId != null) {
+ if (keyId != null) {
uri = KeyRings.buildGenericKeyRingUri(keyId);
rowUri = uri;
}
@@ -777,6 +802,10 @@ public class KeychainProvider extends ContentProvider {
count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, additionalSelection),
selectionArgs);
break;
+ case API_ALLOWED_KEYS:
+ count = db.delete(Tables.API_ALLOWED_KEYS, buildDefaultApiAllowedKeysSelection(uri, additionalSelection),
+ selectionArgs);
+ break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
@@ -869,4 +898,15 @@ public class KeychainProvider extends ContentProvider {
+ andSelection;
}
+ private String buildDefaultApiAllowedKeysSelection(Uri uri, String selection) {
+ String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(1));
+
+ String andSelection = "";
+ if (!TextUtils.isEmpty(selection)) {
+ andSelection = " AND (" + selection + ")";
+ }
+
+ return ApiAllowedKeys.PACKAGE_NAME + "=" + packageName + andSelection;
+ }
+
}
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 c3990229d..8a9f36c03 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -37,6 +37,12 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
+import org.sufficientlysecure.keychain.operations.ImportExportOperation;
+import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
+import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
@@ -44,26 +50,27 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.operations.ImportExportOperation;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
import org.sufficientlysecure.keychain.pgp.WrappedSignature;
+import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.remote.AccountSettings;
import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
-import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
-import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
-import org.sufficientlysecure.keychain.util.ParcelableFileCache;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.ParcelableFileCache;
+import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
+import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import org.sufficientlysecure.keychain.util.Utf8Util;
@@ -170,7 +177,7 @@ public class ProviderHelper {
Cursor cursor = mContentResolver.query(uri, proj, selection, null, null);
try {
- HashMap<String, Object> result = new HashMap<String, Object>(proj.length);
+ HashMap<String, Object> result = new HashMap<>(proj.length);
if (cursor != null && cursor.moveToFirst()) {
int pos = 0;
for (String p : proj) {
@@ -221,7 +228,7 @@ public class ProviderHelper {
}, KeyRings.HAS_ANY_SECRET + " = 1", null, null);
try {
- LongSparseArray<CanonicalizedPublicKey> result = new LongSparseArray<CanonicalizedPublicKey>();
+ LongSparseArray<CanonicalizedPublicKey> result = new LongSparseArray<>();
if (cursor != null && cursor.moveToFirst()) do {
long masterKeyId = cursor.getLong(0);
@@ -350,7 +357,7 @@ public class ProviderHelper {
mIndent += 1;
// save all keys and userIds included in keyRing object in database
- operations = new ArrayList<ContentProviderOperation>();
+ operations = new ArrayList<>();
log(LogType.MSG_IP_INSERT_KEYRING);
{ // insert keyring
@@ -440,7 +447,7 @@ public class ProviderHelper {
// classify and order user ids. primary are moved to the front, revoked to the back,
// otherwise the order in the keyfile is preserved.
- List<UserPacketItem> uids = new ArrayList<UserPacketItem>();
+ List<UserPacketItem> uids = new ArrayList<>();
if (trustedKeys.size() == 0) {
log(LogType.MSG_IP_UID_CLASSIFYING_ZERO);
@@ -460,7 +467,7 @@ public class ProviderHelper {
log(LogType.MSG_IP_UID_PROCESSING, userId);
mIndent += 1;
// look through signatures for this specific key
- for (WrappedSignature cert : new IterableIterator<WrappedSignature>(
+ for (WrappedSignature cert : new IterableIterator<>(
masterKey.getSignaturesForRawId(rawUserId))) {
long certId = cert.getKeyId();
// self signature
@@ -472,7 +479,7 @@ public class ProviderHelper {
item.selfCert = cert;
item.isPrimary = cert.isPrimaryUserId();
} else {
- item.isRevoked = true;
+ item.selfRevocation = cert;
log(LogType.MSG_IP_UID_REVOKED);
}
continue;
@@ -560,7 +567,7 @@ public class ProviderHelper {
}
mIndent += 1;
// look through signatures for this specific key
- for (WrappedSignature cert : new IterableIterator<WrappedSignature>(
+ for (WrappedSignature cert : new IterableIterator<>(
masterKey.getSignaturesForUserAttribute(userAttribute))) {
long certId = cert.getKeyId();
// self signature
@@ -568,10 +575,11 @@ public class ProviderHelper {
// NOTE self-certificates are already verified during canonicalization,
// AND we know there is at most one cert plus at most one revocation
+ // AND the revocation only exists if there is no newer certification
if (!cert.isRevocation()) {
item.selfCert = cert;
} else {
- item.isRevoked = true;
+ item.selfRevocation = cert;
log(LogType.MSG_IP_UAT_REVOKED);
}
continue;
@@ -642,16 +650,21 @@ public class ProviderHelper {
for (int userIdRank = 0; userIdRank < uids.size(); userIdRank++) {
UserPacketItem item = uids.get(userIdRank);
operations.add(buildUserIdOperations(masterKeyId, item, userIdRank));
- if (item.selfCert != null) {
- // TODO get rid of "self verified" status? this cannot even happen anymore!
- operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert,
- selfCertsAreTrusted ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF));
+
+ if (item.selfCert == null) {
+ throw new AssertionError("User ids MUST be self-certified at this point!!");
}
- // don't bother with trusted certs if the uid is revoked, anyways
- if (item.isRevoked) {
+
+ if (item.selfRevocation != null) {
+ operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfRevocation,
+ Certs.VERIFIED_SELF));
+ // don't bother with trusted certs if the uid is revoked, anyways
continue;
}
+ operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert,
+ selfCertsAreTrusted ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF));
+
// iterate over signatures
for (int i = 0; i < item.trustedCerts.size() ; i++) {
WrappedSignature sig = item.trustedCerts.valueAt(i);
@@ -710,12 +723,17 @@ public class ProviderHelper {
String userId;
byte[] attributeData;
boolean isPrimary = false;
- boolean isRevoked = false;
WrappedSignature selfCert;
- LongSparseArray<WrappedSignature> trustedCerts = new LongSparseArray<WrappedSignature>();
+ WrappedSignature selfRevocation;
+ LongSparseArray<WrappedSignature> trustedCerts = new LongSparseArray<>();
@Override
public int compareTo(UserPacketItem o) {
+ // revoked keys always come last!
+ //noinspection DoubleNegation
+ if ( (selfRevocation != null) != (o.selfRevocation != null)) {
+ return selfRevocation != null ? 1 : -1;
+ }
// if one is a user id, but the other isn't, the user id always comes first.
// we compare for null values here, so != is the correct operator!
// noinspection NumberEquality
@@ -726,10 +744,6 @@ public class ProviderHelper {
if (isPrimary != o.isPrimary) {
return isPrimary ? -1 : 1;
}
- // revoked keys always come last!
- if (isRevoked != o.isRevoked) {
- return isRevoked ? 1 : -1;
- }
return 0;
}
}
@@ -1053,6 +1067,11 @@ public class ProviderHelper {
log.add(LogType.MSG_CON, indent);
indent += 1;
+ if (mConsolidateCritical) {
+ log.add(LogType.MSG_CON_RECURSIVE, indent);
+ return new ConsolidateResult(ConsolidateResult.RESULT_OK, log);
+ }
+
progress.setProgress(R.string.progress_con_saving, 0, 100);
// The consolidate operation can never be cancelled!
@@ -1075,7 +1094,7 @@ public class ProviderHelper {
// No keys existing might be a legitimate option, we write an empty file in that case
cursor.moveToFirst();
ParcelableFileCache<ParcelableKeyRing> cache =
- new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
+ new ParcelableFileCache<>(mContext, "consolidate_secret.pcl");
cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring;
@@ -1137,7 +1156,7 @@ public class ProviderHelper {
// No keys existing might be a legitimate option, we write an empty file in that case
cursor.moveToFirst();
ParcelableFileCache<ParcelableKeyRing> cache =
- new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl");
+ new ParcelableFileCache<>(mContext, "consolidate_public.pcl");
cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring;
@@ -1219,13 +1238,11 @@ public class ProviderHelper {
log.add(LogType.MSG_CON_DB_CLEAR, indent);
mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null);
- ParcelableFileCache<ParcelableKeyRing> cacheSecret =
- new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
- ParcelableFileCache<ParcelableKeyRing> cachePublic =
- new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl");
+ ParcelableFileCache<ParcelableKeyRing> cacheSecret, cachePublic;
// Set flag that we have a cached consolidation here
try {
+ cacheSecret = new ParcelableFileCache<>(mContext, "consolidate_secret.pcl");
IteratorWithSize<ParcelableKeyRing> itSecrets = cacheSecret.readCache(false);
int numSecrets = itSecrets.getSize();
@@ -1253,6 +1270,7 @@ public class ProviderHelper {
try {
+ cachePublic = new ParcelableFileCache<>(mContext, "consolidate_public.pcl");
IteratorWithSize<ParcelableKeyRing> itPublics = cachePublic.readCache();
int numPublics = itPublics.getSize();
@@ -1308,7 +1326,6 @@ public class ProviderHelper {
progress.setProgress(100, 100);
log.add(LogType.MSG_CON_SUCCESS, indent);
- indent -= 1;
return new ConsolidateResult(ConsolidateResult.RESULT_OK, log);
@@ -1349,7 +1366,7 @@ public class ProviderHelper {
values.put(UserPackets.USER_ID, item.userId);
values.put(UserPackets.ATTRIBUTE_DATA, item.attributeData);
values.put(UserPackets.IS_PRIMARY, item.isPrimary);
- values.put(UserPackets.IS_REVOKED, item.isRevoked);
+ values.put(UserPackets.IS_REVOKED, item.selfRevocation != null);
values.put(UserPackets.RANK, rank);
Uri uri = UserPackets.buildUserIdsUri(masterKeyId);
@@ -1380,7 +1397,7 @@ public class ProviderHelper {
public ArrayList<String> getRegisteredApiApps() {
Cursor cursor = mContentResolver.query(ApiApps.CONTENT_URI, null, null, null, null);
- ArrayList<String> packageNames = new ArrayList<String>();
+ ArrayList<String> packageNames = new ArrayList<>();
try {
if (cursor != null) {
int packageNameCol = cursor.getColumnIndex(ApiApps.PACKAGE_NAME);
@@ -1485,7 +1502,7 @@ public class ProviderHelper {
}
public Set<Long> getAllKeyIdsForApp(Uri uri) {
- Set<Long> keyIds = new HashSet<Long>();
+ Set<Long> keyIds = new HashSet<>();
Cursor cursor = mContentResolver.query(uri, null, null, null, null);
try {
@@ -1504,8 +1521,41 @@ public class ProviderHelper {
return keyIds;
}
+ public Set<Long> getAllowedKeyIdsForApp(Uri uri) {
+ Set<Long> keyIds = new HashSet<>();
+
+ Cursor cursor = mContentResolver.query(uri, null, null, null, null);
+ try {
+ if (cursor != null) {
+ int keyIdColumn = cursor.getColumnIndex(KeychainContract.ApiAllowedKeys.KEY_ID);
+ while (cursor.moveToNext()) {
+ keyIds.add(cursor.getLong(keyIdColumn));
+ }
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ return keyIds;
+ }
+
+ public void saveAllowedKeyIdsForApp(Uri uri, Set<Long> allowedKeyIds)
+ throws RemoteException, OperationApplicationException {
+ // wipe whole table of allowed keys for this account
+ mContentResolver.delete(uri, null, null);
+
+ // re-insert allowed key ids
+ for (Long keyId : allowedKeyIds) {
+ ContentValues values = new ContentValues();
+ values.put(ApiAllowedKeys.KEY_ID, keyId);
+ mContentResolver.insert(uri, values);
+ }
+ }
+
public Set<String> getAllFingerprints(Uri uri) {
- Set<String> fingerprints = new HashSet<String>();
+ Set<String> fingerprints = new HashSet<>();
String[] projection = new String[]{KeyRings.FINGERPRINT};
Cursor cursor = mContentResolver.query(uri, projection, null, null, null);
try {