diff options
Diffstat (limited to 'OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider')
4 files changed, 185 insertions, 45 deletions
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java index 46928c6fa..93ee50a5e 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -43,7 +43,7 @@ public class KeychainContract { String CREATION = "creation"; String EXPIRY = "expiry"; String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID - String KEY_DATA = "key_data"; // PGPPublicKey / PGPSecretKey blob + String KEY_DATA = "key_data"; // PGPPublicKey/PGPSecretKey blob String RANK = "rank"; } @@ -53,8 +53,13 @@ public class KeychainContract { String RANK = "rank"; } - interface CryptoConsumersColumns { + interface ApiAppsColumns { String PACKAGE_NAME = "package_name"; + String KEY_ID = "key_id"; // not a database id + String ASCII_ARMOR = "ascii_armor"; + String ENCRYPTION_ALGORITHM = "encryption_algorithm"; + String HASH_ALORITHM = "hash_algorithm"; + String COMPRESSION = "compression"; } public static final class KeyTypes { @@ -82,7 +87,8 @@ public class KeychainContract { public static final String PATH_USER_IDS = "user_ids"; public static final String PATH_KEYS = "keys"; - public static final String BASE_CRYPTO_CONSUMERS = "crypto_consumers"; + public static final String BASE_API_APPS = "api_apps"; + public static final String PATH_BY_PACKAGE_NAME = "package_name"; public static class KeyRings implements KeyRingsColumns, BaseColumns { public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() @@ -213,15 +219,24 @@ public class KeychainContract { } } - public static class CryptoConsumers implements CryptoConsumersColumns, BaseColumns { + public static class ApiApps implements ApiAppsColumns, BaseColumns { public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() - .appendPath(BASE_CRYPTO_CONSUMERS).build(); + .appendPath(BASE_API_APPS).build(); /** Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.crypto_consumers"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_apps"; /** Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.crypto_consumers"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_apps"; + + public static Uri buildIdUri(String rowId) { + return CONTENT_URI.buildUpon().appendPath(rowId).build(); + } + + public static Uri buildByPackageNameUri(String packageName) { + return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME).appendPath(packageName) + .build(); + } } public static class DataStream { diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index f30292b52..6da96f45f 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -18,7 +18,7 @@ package org.sufficientlysecure.keychain.provider; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.provider.KeychainContract.CryptoConsumersColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; @@ -37,7 +37,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { String KEY_RINGS = "key_rings"; String KEYS = "keys"; String USER_IDS = "user_ids"; - String CRYPTO_CONSUMERS = "crypto_consumers"; + String API_APPS = "api_apps"; } private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS @@ -64,10 +64,14 @@ public class KeychainDatabase extends SQLiteOpenHelper { + UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)"; - private static final String CREATE_CRYPTO_CONSUMERS = "CREATE TABLE IF NOT EXISTS " - + Tables.CRYPTO_CONSUMERS + " (" + BaseColumns._ID - + " INTEGER PRIMARY KEY AUTOINCREMENT, " + CryptoConsumersColumns.PACKAGE_NAME - + " TEXT UNIQUE)"; + private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + + Tables.API_APPS + " (" + BaseColumns._ID + + " INTEGER PRIMARY KEY AUTOINCREMENT, " + ApiAppsColumns.PACKAGE_NAME + + " TEXT UNIQUE, " + ApiAppsColumns.KEY_ID + " INT64, " + + ApiAppsColumns.ASCII_ARMOR + " INTEGER, " + + ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + + ApiAppsColumns.HASH_ALORITHM + " INTEGER, " + + ApiAppsColumns.COMPRESSION + " INTEGER)"; KeychainDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -80,7 +84,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL(CREATE_KEY_RINGS); db.execSQL(CREATE_KEYS); db.execSQL(CREATE_USER_IDS); - db.execSQL(CREATE_CRYPTO_CONSUMERS); + db.execSQL(CREATE_API_APPS); } @Override @@ -108,7 +112,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { + " = 1 WHERE " + KeysColumns.IS_MASTER_KEY + "= 1;"); break; case 4: - db.execSQL(CREATE_CRYPTO_CONSUMERS); + db.execSQL(CREATE_API_APPS); default: break; diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 49286b9ce..edb82e632 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,13 +17,11 @@ package org.sufficientlysecure.keychain.provider; -import java.io.File; -import java.io.FileNotFoundException; import java.util.Arrays; import java.util.HashMap; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.provider.KeychainContract.CryptoConsumers; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes; @@ -44,7 +42,6 @@ import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; -import android.os.ParcelFileDescriptor; import android.provider.BaseColumns; import android.text.TextUtils; @@ -81,7 +78,9 @@ public class KeychainProvider extends ContentProvider { private static final int SECRET_KEY_RING_USER_ID = 221; private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222; - private static final int CRYPTO_CONSUMERS = 301; + private static final int API_APPS = 301; + private static final int API_APPS_BY_ROW_ID = 302; + private static final int API_APPS_BY_PACKAGE_NAME = 303; // private static final int DATA_STREAM = 401; @@ -227,9 +226,12 @@ public class KeychainProvider extends ContentProvider { SECRET_KEY_RING_USER_ID_BY_ROW_ID); /** - * Crypto Consumers + * API apps */ - matcher.addURI(authority, KeychainContract.BASE_CRYPTO_CONSUMERS, CRYPTO_CONSUMERS); + matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/#", API_APPS_BY_ROW_ID); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" + + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_APPS_BY_PACKAGE_NAME); /** * data stream @@ -290,8 +292,12 @@ public class KeychainProvider extends ContentProvider { case SECRET_KEY_RING_USER_ID_BY_ROW_ID: return UserIds.CONTENT_ITEM_TYPE; - case CRYPTO_CONSUMERS: - return CryptoConsumers.CONTENT_TYPE; + case API_APPS: + return ApiApps.CONTENT_TYPE; + + case API_APPS_BY_ROW_ID: + case API_APPS_BY_PACKAGE_NAME: + return ApiApps.CONTENT_ITEM_TYPE; default: throw new UnsupportedOperationException("Unknown uri: " + uri); @@ -600,10 +606,23 @@ public class KeychainProvider extends ContentProvider { qb.appendWhereEscapeString(uri.getLastPathSegment()); break; - - case CRYPTO_CONSUMERS: - qb.setTables(Tables.CRYPTO_CONSUMERS); - + + case API_APPS: + qb.setTables(Tables.API_APPS); + + break; + case API_APPS_BY_ROW_ID: + qb.setTables(Tables.API_APPS); + + qb.appendWhere(BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + break; + case API_APPS_BY_PACKAGE_NAME: + qb.setTables(Tables.API_APPS); + qb.appendWhere(ApiApps.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + break; default: @@ -653,6 +672,7 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values); rowUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_KEY: @@ -660,11 +680,13 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEYS, null, values); rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_USER_ID: rowId = db.insertOrThrow(Tables.USER_IDS, null, values); rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING: @@ -672,6 +694,7 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values); rowUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING_KEY: @@ -679,6 +702,7 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEYS, null, values); rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING_USER_ID: @@ -686,13 +710,17 @@ public class KeychainProvider extends ContentProvider { rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId)); break; + case API_APPS: + rowId = db.insertOrThrow(Tables.API_APPS, null, values); + rowUri = ApiApps.buildIdUri(Long.toString(rowId)); + + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); } // notify of changes in db getContext().getContentResolver().notifyChange(uri, null); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); } catch (SQLiteConstraintException e) { Log.e(Constants.TAG, "Constraint exception on insert! Entry already existing?"); @@ -720,6 +748,7 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.KEY_RINGS, buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_MASTER_KEY_ID: @@ -728,24 +757,33 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.KEY_RINGS, buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_KEY_BY_ROW_ID: case SECRET_KEY_RING_KEY_BY_ROW_ID: count = db.delete(Tables.KEYS, buildDefaultKeysSelection(uri, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: case SECRET_KEY_RING_USER_ID_BY_ROW_ID: count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection), selectionArgs); break; + case API_APPS_BY_ROW_ID: + count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, false, selection), + selectionArgs); + break; + case API_APPS_BY_PACKAGE_NAME: + count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, true, selection), + selectionArgs); + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); } // notify of changes in db getContext().getContentResolver().notifyChange(uri, null); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); return count; } @@ -771,6 +809,8 @@ public class KeychainProvider extends ContentProvider { values, buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + break; case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_MASTER_KEY_ID: @@ -781,6 +821,8 @@ public class KeychainProvider extends ContentProvider { values, buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + break; case PUBLIC_KEY_RING_KEY_BY_ROW_ID: case SECRET_KEY_RING_KEY_BY_ROW_ID: @@ -788,19 +830,28 @@ public class KeychainProvider extends ContentProvider { .update(Tables.KEYS, values, buildDefaultKeysSelection(uri, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + break; case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: case SECRET_KEY_RING_USER_ID_BY_ROW_ID: count = db.update(Tables.USER_IDS, values, buildDefaultUserIdsSelection(uri, selection), selectionArgs); break; + case API_APPS_BY_ROW_ID: + count = db.update(Tables.API_APPS, values, + buildDefaultApiAppsSelection(uri, false, selection), selectionArgs); + break; + case API_APPS_BY_PACKAGE_NAME: + count = db.update(Tables.API_APPS, values, + buildDefaultApiAppsSelection(uri, true, selection), selectionArgs); + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); } // notify of changes in db getContext().getContentResolver().notifyChange(uri, null); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); } catch (SQLiteConstraintException e) { Log.e(Constants.TAG, "Constraint exception on update! Entry already existing?"); @@ -883,6 +934,29 @@ public class KeychainProvider extends ContentProvider { return BaseColumns._ID + "=" + rowId + andForeignKeyRing + andSelection; } + /** + * Build default selection statement for API apps. If no extra selection is specified only build + * where clause with rowId + * + * @param uri + * @param selection + * @return + */ + private String buildDefaultApiAppsSelection(Uri uri, boolean packageSelection, String selection) { + String lastPathSegment = uri.getLastPathSegment(); + + String andSelection = ""; + if (!TextUtils.isEmpty(selection)) { + andSelection = " AND (" + selection + ")"; + } + + if (packageSelection) { + return ApiApps.PACKAGE_NAME + "=" + lastPathSegment + andSelection; + } else { + return BaseColumns._ID + "=" + lastPathSegment + andSelection; + } + } + // @Override // public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { // int match = mUriMatcher.match(uri); @@ -899,10 +973,12 @@ public class KeychainProvider extends ContentProvider { * updated, or deleted */ private void sendBroadcastDatabaseChange(int keyType, String contentItemType) { - Intent intent = new Intent(); - intent.setAction(ACTION_BROADCAST_DATABASE_CHANGE); - intent.putExtra(EXTRA_BROADCAST_KEY_TYPE, keyType); - intent.putExtra(EXTRA_BROADCAST_CONTENT_ITEM_TYPE, contentItemType); - getContext().sendBroadcast(intent, Constants.PERMISSION_ACCESS_API); + // TODO: Disabled, old API + // Intent intent = new Intent(); + // intent.setAction(ACTION_BROADCAST_DATABASE_CHANGE); + // intent.putExtra(EXTRA_BROADCAST_KEY_TYPE, keyType); + // intent.putExtra(EXTRA_BROADCAST_CONTENT_ITEM_TYPE, contentItemType); + // + // getContext().sendBroadcast(intent, Constants.PERMISSION_ACCESS_API); } } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 57d3b54d6..d0fcfe999 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -31,11 +31,12 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.helper.PgpConversionHelper; import org.sufficientlysecure.keychain.helper.PgpHelper; import org.sufficientlysecure.keychain.helper.PgpMain; -import org.sufficientlysecure.keychain.provider.KeychainContract.CryptoConsumers; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; +import org.sufficientlysecure.keychain.remote_api.AppSettings; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -718,13 +719,13 @@ public class ProviderHelper { return cursor; } - public static ArrayList<String> getCryptoConsumers(Context context) { - Cursor cursor = context.getContentResolver().query(CryptoConsumers.CONTENT_URI, null, null, - null, null); + public static ArrayList<String> getRegisteredApiApps(Context context) { + Cursor cursor = context.getContentResolver().query(ApiApps.CONTENT_URI, null, null, null, + null); ArrayList<String> packageNames = new ArrayList<String>(); if (cursor != null) { - int packageNameCol = cursor.getColumnIndex(CryptoConsumers.PACKAGE_NAME); + int packageNameCol = cursor.getColumnIndex(ApiApps.PACKAGE_NAME); if (cursor.moveToFirst()) { do { packageNames.add(cursor.getString(packageNameCol)); @@ -739,9 +740,53 @@ public class ProviderHelper { return packageNames; } - public static void addCryptoConsumer(Context context, String packageName) { + private static void contentValueForApiApps() { + + } + + public static void insertApiApp(Context context, AppSettings appSettings) { ContentValues values = new ContentValues(); - values.put(CryptoConsumers.PACKAGE_NAME, packageName); - context.getContentResolver().insert(CryptoConsumers.CONTENT_URI, values); + values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName()); + values.put(ApiApps.KEY_ID, appSettings.getKeyId()); + values.put(ApiApps.ASCII_ARMOR, appSettings.isAsciiArmor()); + // TODO: other parameters + context.getContentResolver().insert(ApiApps.CONTENT_URI, values); + } + + public static void updateApiApp(Context context, AppSettings appSettings, Uri uri) { + final ContentValues cv = new ContentValues(); + cv.put(KeychainContract.ApiApps.KEY_ID, appSettings.getKeyId()); + + cv.put(KeychainContract.ApiApps.ASCII_ARMOR, appSettings.isAsciiArmor()); + // TODO: other parameters + + if (context.getContentResolver().update(uri, cv, null, null) <= 0) { + throw new RuntimeException(); + } + } + + public static AppSettings getApiAppSettings(Context context, Uri uri) { + AppSettings settings = new AppSettings(); + Cursor cur = context.getContentResolver().query(uri, null, null, null, null); + if (cur == null) { + return null; + } + if (cur.moveToFirst()) { + settings.setPackageName(cur.getString(cur + .getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); + + settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.ApiApps.KEY_ID))); + + settings.setAsciiArmor(cur.getInt(cur + .getColumnIndexOrThrow(KeychainContract.ApiApps.ASCII_ARMOR)) == 1); + + settings.setPackageName(cur.getString(cur + .getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); + + settings.setPackageName(cur.getString(cur + .getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); + } + + return settings; } } |