diff options
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider')
4 files changed, 489 insertions, 531 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index d2381f6f0..d8de30b37 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -45,6 +45,7 @@ public class KeychainContract { String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID String KEY_DATA = "key_data"; // PGPPublicKey/PGPSecretKey blob String RANK = "rank"; + String FINGERPRINT = "fingerprint"; } interface UserIdsColumns { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 60c5c91a8..3a00f3101 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -31,7 +31,7 @@ import android.provider.BaseColumns; public class KeychainDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "apg.db"; - private static final int DATABASE_VERSION = 6; + private static final int DATABASE_VERSION = 7; public interface Tables { String KEY_RINGS = "key_rings"; @@ -42,33 +42,45 @@ public class KeychainDatabase extends SQLiteOpenHelper { private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + KeyRingsColumns.MASTER_KEY_ID + " INT64, " + KeyRingsColumns.TYPE + " INTEGER, " + + KeyRingsColumns.MASTER_KEY_ID + " INT64, " + + KeyRingsColumns.TYPE + " INTEGER, " + KeyRingsColumns.KEY_RING_DATA + " BLOB)"; private static final String CREATE_KEYS = "CREATE TABLE IF NOT EXISTS " + Tables.KEYS + " (" - + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KeysColumns.KEY_ID - + " INT64, " + KeysColumns.TYPE + " INTEGER, " + KeysColumns.IS_MASTER_KEY - + " INTEGER, " + KeysColumns.ALGORITHM + " INTEGER, " + KeysColumns.KEY_SIZE - + " INTEGER, " + KeysColumns.CAN_CERTIFY + " INTEGER, " + KeysColumns.CAN_SIGN - + " INTEGER, " + KeysColumns.CAN_ENCRYPT + " INTEGER, " + KeysColumns.IS_REVOKED - + " INTEGER, " + KeysColumns.CREATION + " INTEGER, " + KeysColumns.EXPIRY - + " INTEGER, " + KeysColumns.KEY_DATA + " BLOB," + KeysColumns.RANK + " INTEGER, " + + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + KeysColumns.KEY_ID + " INT64, " + + KeysColumns.TYPE + " INTEGER, " + + KeysColumns.IS_MASTER_KEY + " INTEGER, " + + KeysColumns.ALGORITHM + " INTEGER, " + + KeysColumns.KEY_SIZE + " INTEGER, " + + KeysColumns.CAN_CERTIFY + " INTEGER, " + + KeysColumns.CAN_SIGN + " INTEGER, " + + KeysColumns.CAN_ENCRYPT + " INTEGER, " + + KeysColumns.IS_REVOKED + " INTEGER, " + + KeysColumns.CREATION + " INTEGER, " + + KeysColumns.EXPIRY + " INTEGER, " + + KeysColumns.KEY_DATA + " BLOB," + + KeysColumns.RANK + " INTEGER, " + + KeysColumns.FINGERPRINT + " BLOB, " + KeysColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, FOREIGN KEY(" + KeysColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)"; private static final String CREATE_USER_IDS = "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + UserIdsColumns.USER_ID + " TEXT, " + UserIdsColumns.RANK + " INTEGER, " + + UserIdsColumns.USER_ID + " TEXT, " + + UserIdsColumns.RANK + " INTEGER, " + UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, FOREIGN KEY(" + UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)"; 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.PACKAGE_SIGNATURE - + " BLOB, " + ApiAppsColumns.KEY_ID + " INT64, " + ApiAppsColumns.ENCRYPTION_ALGORITHM - + " INTEGER, " + ApiAppsColumns.HASH_ALORITHM + " INTEGER, " + + ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, " + + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB, " + + ApiAppsColumns.KEY_ID + " INT64, " + + ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + + ApiAppsColumns.HASH_ALORITHM + " INTEGER, " + ApiAppsColumns.COMPRESSION + " INTEGER)"; KeychainDatabase(Context context) { @@ -103,21 +115,24 @@ public class KeychainDatabase extends SQLiteOpenHelper { Log.w(Constants.TAG, "Upgrading database to version " + version); switch (version) { - case 3: - db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.CAN_CERTIFY - + " INTEGER DEFAULT 0;"); - db.execSQL("UPDATE " + Tables.KEYS + " SET " + KeysColumns.CAN_CERTIFY - + " = 1 WHERE " + KeysColumns.IS_MASTER_KEY + "= 1;"); - break; - case 4: - db.execSQL(CREATE_API_APPS); - case 5: - // new column: package_signature - db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS); - db.execSQL(CREATE_API_APPS); - - default: - break; + case 3: + db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.CAN_CERTIFY + + " INTEGER DEFAULT 0;"); + db.execSQL("UPDATE " + Tables.KEYS + " SET " + KeysColumns.CAN_CERTIFY + + " = 1 WHERE " + KeysColumns.IS_MASTER_KEY + "= 1;"); + break; + case 4: + db.execSQL(CREATE_API_APPS); + case 5: + // new column: package_signature + db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS); + db.execSQL(CREATE_API_APPS); + case 6: + // new column: fingerprint + db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.FINGERPRINT + + " BLOB;"); + default: + break; } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 70fb11e47..62fcf4f84 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -96,7 +96,7 @@ public class KeychainProvider extends ContentProvider { /** * public key rings - * + * * <pre> * key_rings/public * key_rings/public/# @@ -128,7 +128,7 @@ public class KeychainProvider extends ContentProvider { /** * public keys - * + * * <pre> * key_rings/public/#/keys * key_rings/public/#/keys/# @@ -143,7 +143,7 @@ public class KeychainProvider extends ContentProvider { /** * public user ids - * + * * <pre> * key_rings/public/#/user_ids * key_rings/public/#/user_ids/# @@ -158,7 +158,7 @@ public class KeychainProvider extends ContentProvider { /** * secret key rings - * + * * <pre> * key_rings/secret * key_rings/secret/# @@ -190,7 +190,7 @@ public class KeychainProvider extends ContentProvider { /** * secret keys - * + * * <pre> * key_rings/secret/#/keys * key_rings/secret/#/keys/# @@ -205,7 +205,7 @@ public class KeychainProvider extends ContentProvider { /** * secret user ids - * + * * <pre> * key_rings/secret/#/user_ids * key_rings/secret/#/user_ids/# @@ -228,7 +228,7 @@ public class KeychainProvider extends ContentProvider { /** * data stream - * + * * <pre> * data / _ * </pre> @@ -240,7 +240,9 @@ public class KeychainProvider extends ContentProvider { private KeychainDatabase mApgDatabase; - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public boolean onCreate() { mUriMatcher = buildUriMatcher(); @@ -248,94 +250,96 @@ public class KeychainProvider extends ContentProvider { return true; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public String getType(Uri uri) { final int match = mUriMatcher.match(uri); switch (match) { - case PUBLIC_KEY_RING: - case PUBLIC_KEY_RING_BY_EMAILS: - case PUBLIC_KEY_RING_BY_LIKE_EMAIL: - case SECRET_KEY_RING: - case SECRET_KEY_RING_BY_EMAILS: - case SECRET_KEY_RING_BY_LIKE_EMAIL: - return KeyRings.CONTENT_TYPE; - - case PUBLIC_KEY_RING_BY_ROW_ID: - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: - case PUBLIC_KEY_RING_BY_KEY_ID: - case SECRET_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_MASTER_KEY_ID: - case SECRET_KEY_RING_BY_KEY_ID: - return KeyRings.CONTENT_ITEM_TYPE; - - case PUBLIC_KEY_RING_KEY: - case SECRET_KEY_RING_KEY: - return Keys.CONTENT_TYPE; - - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - return Keys.CONTENT_ITEM_TYPE; - - case PUBLIC_KEY_RING_USER_ID: - case SECRET_KEY_RING_USER_ID: - return UserIds.CONTENT_TYPE; - - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - return UserIds.CONTENT_ITEM_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); + case PUBLIC_KEY_RING: + case PUBLIC_KEY_RING_BY_EMAILS: + case PUBLIC_KEY_RING_BY_LIKE_EMAIL: + case SECRET_KEY_RING: + case SECRET_KEY_RING_BY_EMAILS: + case SECRET_KEY_RING_BY_LIKE_EMAIL: + return KeyRings.CONTENT_TYPE; + + case PUBLIC_KEY_RING_BY_ROW_ID: + case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: + case PUBLIC_KEY_RING_BY_KEY_ID: + case SECRET_KEY_RING_BY_ROW_ID: + case SECRET_KEY_RING_BY_MASTER_KEY_ID: + case SECRET_KEY_RING_BY_KEY_ID: + return KeyRings.CONTENT_ITEM_TYPE; + + case PUBLIC_KEY_RING_KEY: + case SECRET_KEY_RING_KEY: + return Keys.CONTENT_TYPE; + + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: + case SECRET_KEY_RING_KEY_BY_ROW_ID: + return Keys.CONTENT_ITEM_TYPE; + + case PUBLIC_KEY_RING_USER_ID: + case SECRET_KEY_RING_USER_ID: + return UserIds.CONTENT_TYPE; + + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: + return UserIds.CONTENT_ITEM_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); } } /** * Returns type of the query (secret/public) - * + * * @param uri * @return */ private int getKeyType(int match) { int type; switch (match) { - case PUBLIC_KEY_RING: - case PUBLIC_KEY_RING_BY_ROW_ID: - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: - case PUBLIC_KEY_RING_BY_KEY_ID: - case PUBLIC_KEY_RING_BY_EMAILS: - case PUBLIC_KEY_RING_BY_LIKE_EMAIL: - case PUBLIC_KEY_RING_KEY: - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case PUBLIC_KEY_RING_USER_ID: - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - type = KeyTypes.PUBLIC; - break; - - case SECRET_KEY_RING: - case SECRET_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_MASTER_KEY_ID: - case SECRET_KEY_RING_BY_KEY_ID: - case SECRET_KEY_RING_BY_EMAILS: - case SECRET_KEY_RING_BY_LIKE_EMAIL: - case SECRET_KEY_RING_KEY: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - type = KeyTypes.SECRET; - break; - - default: - Log.e(Constants.TAG, "Unknown match " + match); - type = -1; - break; + case PUBLIC_KEY_RING: + case PUBLIC_KEY_RING_BY_ROW_ID: + case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: + case PUBLIC_KEY_RING_BY_KEY_ID: + case PUBLIC_KEY_RING_BY_EMAILS: + case PUBLIC_KEY_RING_BY_LIKE_EMAIL: + case PUBLIC_KEY_RING_KEY: + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: + case PUBLIC_KEY_RING_USER_ID: + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: + type = KeyTypes.PUBLIC; + break; + + case SECRET_KEY_RING: + case SECRET_KEY_RING_BY_ROW_ID: + case SECRET_KEY_RING_BY_MASTER_KEY_ID: + case SECRET_KEY_RING_BY_KEY_ID: + case SECRET_KEY_RING_BY_EMAILS: + case SECRET_KEY_RING_BY_LIKE_EMAIL: + case SECRET_KEY_RING_KEY: + case SECRET_KEY_RING_KEY_BY_ROW_ID: + case SECRET_KEY_RING_USER_ID: + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: + type = KeyTypes.SECRET; + break; + + default: + Log.e(Constants.TAG, "Unknown match " + match); + type = -1; + break; } return type; @@ -343,17 +347,20 @@ public class KeychainProvider extends ContentProvider { /** * Set result of query to specific columns, don't show blob column for external content provider - * + * * @return */ private HashMap<String, String> getProjectionMapForKeyRings() { HashMap<String, String> projectionMap = new HashMap<String, String>(); projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); - projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." - + KeyRingsColumns.MASTER_KEY_ID); projectionMap.put(KeyRingsColumns.KEY_RING_DATA, Tables.KEY_RINGS + "." + KeyRingsColumns.KEY_RING_DATA); + projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID); + // TODO: deprecated master key id + //projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.KEY_ID); + projectionMap.put(KeysColumns.FINGERPRINT, Tables.KEYS + "." + KeysColumns.FINGERPRINT); + projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID); return projectionMap; @@ -361,7 +368,7 @@ public class KeychainProvider extends ContentProvider { /** * Set result of query to specific columns, don't show blob column for external content provider - * + * * @return */ private HashMap<String, String> getProjectionMapForKeys() { @@ -386,22 +393,20 @@ public class KeychainProvider extends ContentProvider { } /** - * Builds default query for keyRings: KeyRings table is joined with UserIds - * - * @param qb - * @param match - * @param isMasterKey - * @param sortOrder - * @return + * Builds default query for keyRings: KeyRings table is joined with UserIds and Keys */ - private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, int match, String sortOrder) { + private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, int match) { // public or secret keyring qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - // join keyrings with userIds to every keyring - qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.USER_IDS + " ON " + "(" - + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." + // join keyrings with keys and userIds + // Only get user id and key with rank 0 (main user id and main key) + qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" + + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." + + KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "." + + KeysColumns.RANK + " = '0') " + " INNER JOIN " + Tables.USER_IDS + " ON " + + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0')"); @@ -411,16 +416,11 @@ public class KeychainProvider extends ContentProvider { } /** - * Builds default query for keyRings: KeyRings table is joined with Keys and UserIds - * - * @param qb - * @param match - * @param isMasterKey - * @param sortOrder - * @return + * Builds default query for keyRings: KeyRings table is joined with UserIds and Keys + * <p/> + * Here only one key should be selected in the query to return a single keyring! */ - private SQLiteQueryBuilder buildKeyRingQueryWithKeys(SQLiteQueryBuilder qb, int match, - String sortOrder) { + private SQLiteQueryBuilder buildKeyRingQueryWithSpecificKey(SQLiteQueryBuilder qb, int match) { // public or secret keyring qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); @@ -438,11 +438,13 @@ public class KeychainProvider extends ContentProvider { return qb; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @SuppressWarnings("deprecation") @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { + String sortOrder) { Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")"); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); @@ -451,169 +453,169 @@ public class KeychainProvider extends ContentProvider { int match = mUriMatcher.match(uri); switch (match) { - case PUBLIC_KEY_RING: - case SECRET_KEY_RING: - qb = buildKeyRingQuery(qb, match, sortOrder); + case PUBLIC_KEY_RING: + case SECRET_KEY_RING: + qb = buildKeyRingQuery(qb, match); - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; - } + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + } - break; + break; - case PUBLIC_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_ROW_ID: - qb = buildKeyRingQuery(qb, match, sortOrder); + case PUBLIC_KEY_RING_BY_ROW_ID: + case SECRET_KEY_RING_BY_ROW_ID: + qb = buildKeyRingQuery(qb, match); - qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); + qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; - } + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + } - break; + break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: - case SECRET_KEY_RING_BY_MASTER_KEY_ID: - qb = buildKeyRingQuery(qb, match, sortOrder); + case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: + case SECRET_KEY_RING_BY_MASTER_KEY_ID: + qb = buildKeyRingQuery(qb, match); - qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); + qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; - } - - break; + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + } - case SECRET_KEY_RING_BY_KEY_ID: - case PUBLIC_KEY_RING_BY_KEY_ID: - qb = buildKeyRingQueryWithKeys(qb, match, sortOrder); + break; - qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); + case SECRET_KEY_RING_BY_KEY_ID: + case PUBLIC_KEY_RING_BY_KEY_ID: + qb = buildKeyRingQueryWithSpecificKey(qb, match); - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; - } + qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); - break; + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + } - case SECRET_KEY_RING_BY_EMAILS: - case PUBLIC_KEY_RING_BY_EMAILS: - qb = buildKeyRingQuery(qb, match, sortOrder); + break; - String emails = uri.getLastPathSegment(); - String chunks[] = emails.split(" *, *"); - boolean gotCondition = false; - String emailWhere = ""; - for (int i = 0; i < chunks.length; ++i) { - if (chunks[i].length() == 0) { - continue; + case SECRET_KEY_RING_BY_EMAILS: + case PUBLIC_KEY_RING_BY_EMAILS: + qb = buildKeyRingQuery(qb, match); + + String emails = uri.getLastPathSegment(); + String chunks[] = emails.split(" *, *"); + boolean gotCondition = false; + String emailWhere = ""; + for (int i = 0; i < chunks.length; ++i) { + if (chunks[i].length() == 0) { + continue; + } + if (i != 0) { + emailWhere += " OR "; + } + emailWhere += "tmp." + UserIdsColumns.USER_ID + " LIKE "; + // match '*<email>', so it has to be at the *end* of the user id + emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">"); + gotCondition = true; } - if (i != 0) { - emailWhere += " OR "; - } - emailWhere += "tmp." + UserIdsColumns.USER_ID + " LIKE "; - // match '*<email>', so it has to be at the *end* of the user id - emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">"); - gotCondition = true; - } - if (gotCondition) { - qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " - + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID - + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + emailWhere - + "))"); - } + if (gotCondition) { + qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " + + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID + + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + emailWhere + + "))"); + } - break; + break; - case SECRET_KEY_RING_BY_LIKE_EMAIL: - case PUBLIC_KEY_RING_BY_LIKE_EMAIL: - qb = buildKeyRingQuery(qb, match, sortOrder); + case SECRET_KEY_RING_BY_LIKE_EMAIL: + case PUBLIC_KEY_RING_BY_LIKE_EMAIL: + qb = buildKeyRingQuery(qb, match); - String likeEmail = uri.getLastPathSegment(); + String likeEmail = uri.getLastPathSegment(); - String likeEmailWhere = "tmp." + UserIdsColumns.USER_ID + " LIKE " - + DatabaseUtils.sqlEscapeString("%<%" + likeEmail + "%>"); + String likeEmailWhere = "tmp." + UserIdsColumns.USER_ID + " LIKE " + + DatabaseUtils.sqlEscapeString("%<%" + likeEmail + "%>"); - qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " - + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID - + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + likeEmailWhere - + "))"); + qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " + + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID + + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + likeEmailWhere + + "))"); - break; + break; - case PUBLIC_KEY_RING_KEY: - case SECRET_KEY_RING_KEY: - qb.setTables(Tables.KEYS); - qb.appendWhere(KeysColumns.TYPE + " = "); - qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); + case PUBLIC_KEY_RING_KEY: + case SECRET_KEY_RING_KEY: + qb.setTables(Tables.KEYS); + qb.appendWhere(KeysColumns.TYPE + " = "); + qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - qb.setProjectionMap(getProjectionMapForKeys()); + qb.setProjectionMap(getProjectionMapForKeys()); - break; + break; - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - qb.setTables(Tables.KEYS); - qb.appendWhere(KeysColumns.TYPE + " = "); - qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: + case SECRET_KEY_RING_KEY_BY_ROW_ID: + qb.setTables(Tables.KEYS); + qb.appendWhere(KeysColumns.TYPE + " = "); + qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - qb.appendWhere(" AND " + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); + qb.appendWhere(" AND " + BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); - qb.setProjectionMap(getProjectionMapForKeys()); + qb.setProjectionMap(getProjectionMapForKeys()); - break; + break; - case PUBLIC_KEY_RING_USER_ID: - case SECRET_KEY_RING_USER_ID: - qb.setTables(Tables.USER_IDS); - qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + case PUBLIC_KEY_RING_USER_ID: + case SECRET_KEY_RING_USER_ID: + qb.setTables(Tables.USER_IDS); + qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - break; + break; - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - qb.setTables(Tables.USER_IDS); - qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: + qb.setTables(Tables.USER_IDS); + qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - qb.appendWhere(" AND " + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); + qb.appendWhere(" AND " + BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); - break; + break; - case API_APPS: - qb.setTables(Tables.API_APPS); + case API_APPS: + qb.setTables(Tables.API_APPS); - break; - case API_APPS_BY_ROW_ID: - 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()); + 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; + case API_APPS_BY_PACKAGE_NAME: + qb.setTables(Tables.API_APPS); + qb.appendWhere(ApiApps.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - break; + break; - default: - throw new IllegalArgumentException("Unknown URI " + uri); + default: + throw new IllegalArgumentException("Unknown URI " + uri); } @@ -634,14 +636,16 @@ public class KeychainProvider extends ContentProvider { Log.d(Constants.TAG, "Query: " + qb.buildQuery(projection, selection, selectionArgs, null, null, - orderBy, null)); + orderBy, null)); Log.d(Constants.TAG, "Cursor: " + DatabaseUtils.dumpCursorToString(c)); } return c; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public Uri insert(Uri uri, ContentValues values) { Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")"); @@ -654,56 +658,56 @@ public class KeychainProvider extends ContentProvider { final int match = mUriMatcher.match(uri); switch (match) { - case PUBLIC_KEY_RING: - values.put(KeyRings.TYPE, KeyTypes.PUBLIC); - - 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: - values.put(Keys.TYPE, KeyTypes.PUBLIC); - - 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: - values.put(KeyRings.TYPE, KeyTypes.SECRET); - - 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: - values.put(Keys.TYPE, KeyTypes.SECRET); - - 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: - rowId = db.insertOrThrow(Tables.USER_IDS, null, values); - 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); + case PUBLIC_KEY_RING: + values.put(KeyRings.TYPE, KeyTypes.PUBLIC); + + 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: + values.put(Keys.TYPE, KeyTypes.PUBLIC); + + 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: + values.put(KeyRings.TYPE, KeyTypes.SECRET); + + 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: + values.put(Keys.TYPE, KeyTypes.SECRET); + + 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: + rowId = db.insertOrThrow(Tables.USER_IDS, null, values); + 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 @@ -716,7 +720,9 @@ public class KeychainProvider extends ContentProvider { return rowUri; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { Log.v(Constants.TAG, "delete(uri=" + uri + ")"); @@ -728,113 +734,115 @@ public class KeychainProvider extends ContentProvider { String defaultSelection = null; switch (match) { - case PUBLIC_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_ROW_ID: - defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment(); - // corresponding keys and userIds are deleted by ON DELETE CASCADE - 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: - defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment(); - // corresponding keys and userIds are deleted by ON DELETE CASCADE - 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); - - return count; - } - - /** {@inheritDoc} */ - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")"); - - final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); - - String defaultSelection = null; - int count = 0; - try { - final int match = mUriMatcher.match(uri); - switch (match) { case PUBLIC_KEY_RING_BY_ROW_ID: case SECRET_KEY_RING_BY_ROW_ID: defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment(); - - count = db.update( - Tables.KEY_RINGS, - values, - buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), - selection), selectionArgs); + // corresponding keys and userIds are deleted by ON DELETE CASCADE + 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: defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment(); - - count = db.update( - Tables.KEY_RINGS, - values, - buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), - selection), selectionArgs); + // corresponding keys and userIds are deleted by ON DELETE CASCADE + 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 - .update(Tables.KEYS, values, - buildDefaultKeysSelection(uri, getKeyType(match), selection), - selectionArgs); + 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.update(Tables.USER_IDS, values, - buildDefaultUserIdsSelection(uri, selection), selectionArgs); + count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection), + selectionArgs); break; case API_APPS_BY_ROW_ID: - count = db.update(Tables.API_APPS, values, - buildDefaultApiAppsSelection(uri, false, selection), selectionArgs); + count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, false, selection), + selectionArgs); break; case API_APPS_BY_PACKAGE_NAME: - count = db.update(Tables.API_APPS, values, - buildDefaultApiAppsSelection(uri, true, selection), selectionArgs); + 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); + + return count; + } + + /** + * {@inheritDoc} + */ + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")"); + + final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); + + String defaultSelection = null; + int count = 0; + try { + final int match = mUriMatcher.match(uri); + switch (match) { + case PUBLIC_KEY_RING_BY_ROW_ID: + case SECRET_KEY_RING_BY_ROW_ID: + defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment(); + + count = db.update( + Tables.KEY_RINGS, + 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: + defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment(); + + count = db.update( + Tables.KEY_RINGS, + 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: + count = db + .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 @@ -850,13 +858,13 @@ public class KeychainProvider extends ContentProvider { /** * Build default selection statement for KeyRings. If no extra selection is specified only build * where clause with rowId - * + * * @param uri * @param selection * @return */ private String buildDefaultKeyRingsSelection(String defaultSelection, Integer keyType, - String selection) { + String selection) { String andType = ""; if (keyType != null) { andType = " AND " + KeyRingsColumns.TYPE + "=" + keyType; @@ -873,7 +881,7 @@ public class KeychainProvider extends ContentProvider { /** * Build default selection statement for Keys. If no extra selection is specified only build * where clause with rowId - * + * * @param uri * @param selection * @return @@ -901,7 +909,7 @@ public class KeychainProvider extends ContentProvider { /** * Build default selection statement for UserIds. If no extra selection is specified only build * where clause with rowId - * + * * @param uri * @param selection * @return @@ -924,7 +932,7 @@ public class KeychainProvider extends ContentProvider { /** * Build default selection statement for API apps. If no extra selection is specified only build * where clause with rowId - * + * * @param uri * @param selection * @return diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 10404e0ff..a1d7ad511 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -23,6 +23,8 @@ import java.util.ArrayList; import java.util.Date; import org.spongycastle.bcpg.ArmoredOutputStream; +import org.spongycastle.bcpg.UserAttributePacket; +import org.spongycastle.bcpg.UserAttributeSubpacket; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; @@ -55,10 +57,6 @@ public class ProviderHelper { /** * Private helper method to get PGPKeyRing from database - * - * @param context - * @param queryUri - * @return */ public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) { Cursor cursor = context.getContentResolver().query(queryUri, @@ -83,10 +81,6 @@ public class ProviderHelper { /** * Retrieves the actual PGPPublicKeyRing object from the database blob based on the rowId - * - * @param context - * @param rowId - * @return */ public static PGPPublicKeyRing getPGPPublicKeyRingByRowId(Context context, long rowId) { Uri queryUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)); @@ -95,10 +89,6 @@ public class ProviderHelper { /** * Retrieves the actual PGPPublicKeyRing object from the database blob based on the maserKeyId - * - * @param context - * @param masterKeyId - * @return */ public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context, long masterKeyId) { @@ -109,10 +99,6 @@ public class ProviderHelper { /** * Retrieves the actual PGPPublicKeyRing object from the database blob associated with a key * with this keyId - * - * @param context - * @param keyId - * @return */ public static PGPPublicKeyRing getPGPPublicKeyRingByKeyId(Context context, long keyId) { Uri queryUri = KeyRings.buildPublicKeyRingsByKeyIdUri(Long.toString(keyId)); @@ -122,10 +108,6 @@ public class ProviderHelper { /** * Retrieves the actual PGPPublicKey object from the database blob associated with a key with * this keyId - * - * @param context - * @param keyId - * @return */ public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) { PGPPublicKeyRing keyRing = getPGPPublicKeyRingByKeyId(context, keyId); @@ -138,10 +120,6 @@ public class ProviderHelper { /** * Retrieves the actual PGPSecretKeyRing object from the database blob based on the rowId - * - * @param context - * @param rowId - * @return */ public static PGPSecretKeyRing getPGPSecretKeyRingByRowId(Context context, long rowId) { Uri queryUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); @@ -150,10 +128,6 @@ public class ProviderHelper { /** * Retrieves the actual PGPSecretKeyRing object from the database blob based on the maserKeyId - * - * @param context - * @param masterKeyId - * @return */ public static PGPSecretKeyRing getPGPSecretKeyRingByMasterKeyId(Context context, long masterKeyId) { @@ -164,10 +138,6 @@ public class ProviderHelper { /** * Retrieves the actual PGPSecretKeyRing object from the database blob associated with a key * with this keyId - * - * @param context - * @param keyId - * @return */ public static PGPSecretKeyRing getPGPSecretKeyRingByKeyId(Context context, long keyId) { Uri queryUri = KeyRings.buildSecretKeyRingsByKeyIdUri(Long.toString(keyId)); @@ -177,10 +147,6 @@ public class ProviderHelper { /** * Retrieves the actual PGPSecretKey object from the database blob associated with a key with * this keyId - * - * @param context - * @param keyId - * @return */ public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) { PGPSecretKeyRing keyRing = getPGPSecretKeyRingByKeyId(context, keyId); @@ -193,12 +159,6 @@ public class ProviderHelper { /** * Saves PGPPublicKeyRing with its keys and userIds in DB - * - * @param context - * @param keyRing - * @return - * @throws IOException - * @throws GeneralException */ @SuppressWarnings("unchecked") public static void saveKeyRing(Context context, PGPPublicKeyRing keyRing) throws IOException { @@ -263,12 +223,6 @@ public class ProviderHelper { /** * Saves PGPSecretKeyRing with its keys and userIds in DB - * - * @param context - * @param keyRing - * @return - * @throws IOException - * @throws GeneralException */ @SuppressWarnings("unchecked") public static void saveKeyRing(Context context, PGPSecretKeyRing keyRing) throws IOException { @@ -333,13 +287,6 @@ public class ProviderHelper { /** * Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing - * - * @param context - * @param keyRingRowId - * @param key - * @param rank - * @return - * @throws IOException */ private static ContentProviderOperation buildPublicKeyOperations(Context context, long keyRingRowId, PGPPublicKey key, int rank) throws IOException { @@ -367,13 +314,6 @@ public class ProviderHelper { /** * Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing - * - * @param context - * @param keyRingRowId - * @param key - * @param rank - * @return - * @throws IOException */ private static ContentProviderOperation buildPublicUserIdOperations(Context context, long keyRingRowId, String userId, int rank) { @@ -389,13 +329,6 @@ public class ProviderHelper { /** * Build ContentProviderOperation to add PGPSecretKey to database corresponding to a keyRing - * - * @param context - * @param keyRingRowId - * @param key - * @param rank - * @return - * @throws IOException */ private static ContentProviderOperation buildSecretKeyOperations(Context context, long keyRingRowId, PGPSecretKey key, int rank) throws IOException { @@ -432,13 +365,6 @@ public class ProviderHelper { /** * Build ContentProviderOperation to add SecretUserIds to database corresponding to a keyRing - * - * @param context - * @param keyRingRowId - * @param key - * @param rank - * @return - * @throws IOException */ private static ContentProviderOperation buildSecretUserIdOperations(Context context, long keyRingRowId, String userId, int rank) { @@ -454,10 +380,6 @@ public class ProviderHelper { /** * Private helper method - * - * @param context - * @param queryUri - * @return */ private static ArrayList<Long> getKeyRingsMasterKeyIds(Context context, Uri queryUri) { Cursor cursor = context.getContentResolver().query(queryUri, @@ -482,9 +404,6 @@ public class ProviderHelper { /** * Retrieves ids of all SecretKeyRings - * - * @param context - * @return */ public static ArrayList<Long> getSecretKeyRingsMasterKeyIds(Context context) { Uri queryUri = KeyRings.buildSecretKeyRingsUri(); @@ -493,9 +412,6 @@ public class ProviderHelper { /** * Retrieves ids of all PublicKeyRings - * - * @param context - * @return */ public static ArrayList<Long> getPublicKeyRingsMasterKeyIds(Context context) { Uri queryUri = KeyRings.buildPublicKeyRingsUri(); @@ -514,10 +430,6 @@ public class ProviderHelper { /** * Get master key id of keyring by its row id - * - * @param context - * @param keyRingRowId - * @return */ public static long getPublicMasterKeyId(Context context, long keyRingRowId) { Uri queryUri = KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowId)); @@ -526,10 +438,6 @@ public class ProviderHelper { /** * Get empty status of master key of keyring by its row id - * - * @param context - * @param keyRingRowId - * @return */ public static boolean getSecretMasterKeyCanSign(Context context, long keyRingRowId) { Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId)); @@ -538,11 +446,6 @@ public class ProviderHelper { /** * Private helper method to get master key private empty status of keyring by its row id - * - * @param context - * @param queryUri - * @param keyRingRowId - * @return */ private static boolean getMasterKeyCanSign(Context context, Uri queryUri, long keyRingRowId) { String[] projection = new String[]{ @@ -572,10 +475,6 @@ public class ProviderHelper { /** * Get master key id of keyring by its row id - * - * @param context - * @param keyRingRowId - * @return */ public static long getSecretMasterKeyId(Context context, long keyRingRowId) { Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId)); @@ -583,41 +482,84 @@ public class ProviderHelper { } /** - * Private helper method to get master key id of keyring by its row id - * - * @param context - * @param queryUri - * @param keyRingRowId - * @return + * Get master key id of key */ public static long getMasterKeyId(Context context, Uri queryUri) { String[] projection = new String[]{KeyRings.MASTER_KEY_ID}; - - ContentResolver cr = context.getContentResolver(); - Cursor cursor = cr.query(queryUri, projection, null, null, null); + Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null); long masterKeyId = -1; - if (cursor != null && cursor.moveToFirst()) { - int masterKeyIdCol = cursor.getColumnIndex(KeyRings.MASTER_KEY_ID); - - masterKeyId = cursor.getLong(masterKeyIdCol); - } + try { + if (cursor != null && cursor.moveToFirst()) { + int masterKeyIdCol = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID); - if (cursor != null) { - cursor.close(); + masterKeyId = cursor.getLong(masterKeyIdCol); + } + } finally { + if (cursor != null) { + cursor.close(); + } } return masterKeyId; } - public static ArrayList<String> getPublicKeyRingsAsArmoredString(Context context, - long[] masterKeyIds) { - return getKeyRingsAsArmoredString(context, KeyRings.buildPublicKeyRingsUri(), masterKeyIds); - } + /** + * Get fingerprint of key + */ + public static byte[] getFingerprint(Context context, Uri queryUri) { + String[] projection = new String[]{Keys.FINGERPRINT}; + Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null); - public static ArrayList<String> getSecretKeyRingsAsArmoredString(Context context, - long[] masterKeyIds) { - return getKeyRingsAsArmoredString(context, KeyRings.buildSecretKeyRingsUri(), masterKeyIds); + byte[] fingerprint = null; + try { + if (cursor != null && cursor.moveToFirst()) { + int col = cursor.getColumnIndexOrThrow(Keys.FINGERPRINT); + + fingerprint = cursor.getBlob(col); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + // FALLBACK: If fingerprint is not in database, get it from key blob! + // this could happen if the key was saved by a previous version of Keychain! + if (fingerprint == null) { + Log.d(Constants.TAG, "FALLBACK: fingerprint is not in database, get it from key blob!"); + + // get master key id + projection = new String[]{KeyRings.MASTER_KEY_ID}; + cursor = context.getContentResolver().query(queryUri, projection, null, null, null); + long masterKeyId = 0; + try { + if (cursor != null && cursor.moveToFirst()) { + int col = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID); + + masterKeyId = cursor.getLong(col); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, masterKeyId); + // if it is no public key get it from your own keys... + if (key == null) { + PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, masterKeyId); + if (secretKey == null) { + Log.e(Constants.TAG, "Key could not be found!"); + return null; + } + key = secretKey.getPublicKey(); + } + + fingerprint = key.getFingerprint(); + } + + return fingerprint; } public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri, @@ -681,14 +623,6 @@ public class ProviderHelper { } } - public static byte[] getPublicKeyRingsAsByteArray(Context context, long[] masterKeyIds) { - return getKeyRingsAsByteArray(context, KeyRings.buildPublicKeyRingsUri(), masterKeyIds); - } - - public static byte[] getSecretKeyRingsAsByteArray(Context context, long[] masterKeyIds) { - return getKeyRingsAsByteArray(context, KeyRings.buildSecretKeyRingsUri(), masterKeyIds); - } - public static byte[] getKeyRingsAsByteArray(Context context, Uri uri, long[] masterKeyIds) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); |