From d24bbdc6a13cbc56a5d117e5d5bd9ef3be39e63b Mon Sep 17 00:00:00 2001 From: Dominik Date: Thu, 25 Oct 2012 14:52:13 +0200 Subject: [PATCH] reworking Content Provider --- README.md | 4 +- org_apg/AndroidManifest.xml | 6 + .../android/apg/deprecated/Database.java | 1202 ++++++++--------- .../android/apg/helper/PGPHelper.java | 4 +- .../android/apg/helper/PGPMain.java | 65 +- .../android/apg/provider/ApgContract.java | 63 +- .../android/apg/provider/ApgDatabase.java | 70 +- .../android/apg/provider/ApgProvider.java | 357 +++-- .../android/apg/provider/ProviderHelper.java | 359 ++++- .../android/apg/service/ApgService.java | 4 +- .../apg/service/PassphraseCacheService.java | 2 +- .../android/apg/ui/DecryptActivity.java | 2 +- .../android/apg/ui/EditKeyActivity.java | 2 +- .../android/apg/ui/EncryptActivity.java | 6 +- .../android/apg/ui/PublicKeyListActivity.java | 4 +- .../android/apg/ui/SignKeyActivity.java | 2 +- .../ui/dialog/DeleteKeyDialogFragment.java | 31 +- .../ui/dialog/PassphraseDialogFragment.java | 13 +- 18 files changed, 1277 insertions(+), 919 deletions(-) diff --git a/README.md b/README.md index 88455ff01..c9f756c75 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,9 @@ On error see: http://code.google.com/p/zxing/issues/detail?id=1207 ## Build Spongy Castle -see https://github.com/rtyley/spongycastle +Spongy Castle is the stock Bouncy Castle libraries with a couple of small changes to make it work on Android. + +see http://rtyley.github.com/spongycastle/ # Notes diff --git a/org_apg/AndroidManifest.xml b/org_apg/AndroidManifest.xml index deb62a622..e26106bc6 100644 --- a/org_apg/AndroidManifest.xml +++ b/org_apg/AndroidManifest.xml @@ -338,6 +338,12 @@ + + + sKeyRingsProjection; - public static HashMap sKeysProjection; - public static HashMap sUserIdsProjection; - - private SQLiteDatabase mDb = null; - private int mStatus = 0; - - static { - sKeyRingsProjection = new HashMap(); - sKeyRingsProjection.put(KeyRings._ID, KeyRings._ID); - sKeyRingsProjection.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID); - sKeyRingsProjection.put(KeyRings.TYPE, KeyRings.TYPE); - sKeyRingsProjection.put(KeyRings.WHO_ID, KeyRings.WHO_ID); - sKeyRingsProjection.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA); - - sKeysProjection = new HashMap(); - sKeysProjection.put(Keys._ID, Keys._ID); - sKeysProjection.put(Keys.KEY_ID, Keys.KEY_ID); - sKeysProjection.put(Keys.TYPE, Keys.TYPE); - sKeysProjection.put(Keys.IS_MASTER_KEY, Keys.IS_MASTER_KEY); - sKeysProjection.put(Keys.ALGORITHM, Keys.ALGORITHM); - sKeysProjection.put(Keys.KEY_SIZE, Keys.KEY_SIZE); - sKeysProjection.put(Keys.CAN_SIGN, Keys.CAN_SIGN); - sKeysProjection.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT); - sKeysProjection.put(Keys.IS_REVOKED, Keys.IS_REVOKED); - sKeysProjection.put(Keys.CREATION, Keys.CREATION); - sKeysProjection.put(Keys.EXPIRY, Keys.EXPIRY); - sKeysProjection.put(Keys.KEY_DATA, Keys.KEY_DATA); - sKeysProjection.put(Keys.RANK, Keys.RANK); - - sUserIdsProjection = new HashMap(); - sUserIdsProjection.put(UserIds._ID, UserIds._ID); - sUserIdsProjection.put(UserIds.KEY_ID, UserIds.KEY_ID); - sUserIdsProjection.put(UserIds.USER_ID, UserIds.USER_ID); - sUserIdsProjection.put(UserIds.RANK, UserIds.RANK); - } - - public Database(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - // force upgrade to test things - //onUpgrade(getWritableDatabase(), 1, 2); - mDb = getWritableDatabase(); - } - - @Override - protected void finalize() throws Throwable { - mDb.close(); - super.finalize(); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL("CREATE TABLE " + KeyRings.TABLE_NAME + " (" + - KeyRings._ID + " " + KeyRings._ID_type + "," + - KeyRings.MASTER_KEY_ID + " " + KeyRings.MASTER_KEY_ID_type + ", " + - KeyRings.TYPE + " " + KeyRings.TYPE_type + ", " + - KeyRings.WHO_ID + " " + KeyRings.WHO_ID_type + ", " + - KeyRings.KEY_RING_DATA + " " + KeyRings.KEY_RING_DATA_type + ");"); - - db.execSQL("CREATE TABLE " + Keys.TABLE_NAME + " (" + - Keys._ID + " " + Keys._ID_type + "," + - Keys.KEY_ID + " " + Keys.KEY_ID_type + ", " + - Keys.TYPE + " " + Keys.TYPE_type + ", " + - Keys.IS_MASTER_KEY + " " + Keys.IS_MASTER_KEY_type + ", " + - Keys.ALGORITHM + " " + Keys.ALGORITHM_type + ", " + - Keys.KEY_SIZE + " " + Keys.KEY_SIZE_type + ", " + - Keys.CAN_SIGN + " " + Keys.CAN_SIGN_type + ", " + - Keys.CAN_ENCRYPT + " " + Keys.CAN_ENCRYPT_type + ", " + - Keys.IS_REVOKED + " " + Keys.IS_REVOKED_type + ", " + - Keys.CREATION + " " + Keys.CREATION_type + ", " + - Keys.EXPIRY + " " + Keys.EXPIRY_type + ", " + - Keys.KEY_RING_ID + " " + Keys.KEY_RING_ID_type + ", " + - Keys.KEY_DATA + " " + Keys.KEY_DATA_type + - Keys.RANK + " " + Keys.RANK_type + ");"); - - db.execSQL("CREATE TABLE " + UserIds.TABLE_NAME + " (" + - UserIds._ID + " " + UserIds._ID_type + "," + - UserIds.KEY_ID + " " + UserIds.KEY_ID_type + "," + - UserIds.USER_ID + " " + UserIds.USER_ID_type + "," + - UserIds.RANK + " " + UserIds.RANK_type + ");"); - - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - mDb = db; - for (int version = oldVersion; version < newVersion; ++version) { - switch (version) { - case 1: { // upgrade 1 to 2 - db.execSQL("DROP TABLE IF EXISTS " + KeyRings.TABLE_NAME + ";"); - db.execSQL("DROP TABLE IF EXISTS " + Keys.TABLE_NAME + ";"); - db.execSQL("DROP TABLE IF EXISTS " + UserIds.TABLE_NAME + ";"); - - db.execSQL("CREATE TABLE " + KeyRings.TABLE_NAME + " (" + - KeyRings._ID + " " + KeyRings._ID_type + "," + - KeyRings.MASTER_KEY_ID + " " + KeyRings.MASTER_KEY_ID_type + ", " + - KeyRings.TYPE + " " + KeyRings.TYPE_type + ", " + - KeyRings.WHO_ID + " " + KeyRings.WHO_ID_type + ", " + - KeyRings.KEY_RING_DATA + " " + KeyRings.KEY_RING_DATA_type + ");"); - - - db.execSQL("CREATE TABLE " + Keys.TABLE_NAME + " (" + - Keys._ID + " " + Keys._ID_type + "," + - Keys.KEY_ID + " " + Keys.KEY_ID_type + ", " + - Keys.TYPE + " " + Keys.TYPE_type + ", " + - Keys.IS_MASTER_KEY + " " + Keys.IS_MASTER_KEY_type + ", " + - Keys.ALGORITHM + " " + Keys.ALGORITHM_type + ", " + - Keys.KEY_SIZE + " " + Keys.KEY_SIZE_type + ", " + - Keys.CAN_SIGN + " " + Keys.CAN_SIGN_type + ", " + - Keys.CAN_ENCRYPT + " " + Keys.CAN_ENCRYPT_type + ", " + - Keys.IS_REVOKED + " " + Keys.IS_REVOKED_type + ", " + - Keys.CREATION + " " + Keys.CREATION_type + ", " + - Keys.EXPIRY + " " + Keys.EXPIRY_type + ", " + - Keys.KEY_RING_ID + " " + Keys.KEY_RING_ID_type + ", " + - Keys.KEY_DATA + " " + Keys.KEY_DATA_type + - Keys.RANK + " " + Keys.RANK_type + ");"); - - db.execSQL("CREATE TABLE " + UserIds.TABLE_NAME + " (" + - UserIds._ID + " " + UserIds._ID_type + "," + - UserIds.KEY_ID + " " + UserIds.KEY_ID_type + "," + - UserIds.USER_ID + " " + UserIds.USER_ID_type + "," + - UserIds.RANK + " " + UserIds.RANK_type + ");"); - - Cursor cursor = db.query("public_keys", new String[] { "c_key_data" }, - null, null, null, null, null); - if (cursor != null && cursor.moveToFirst()) { - do { - byte[] data = cursor.getBlob(0); - try { - PGPPublicKeyRing keyRing = new PGPPublicKeyRing(data); - saveKeyRing(keyRing); - } catch (IOException e) { - Log.e("apg.db.upgrade", "key import failed: " + e); - } catch (GeneralException e) { - Log.e("apg.db.upgrade", "key import failed: " + e); - } - } while (cursor.moveToNext()); - } - - if (cursor != null) { - cursor.close(); - } - - cursor = db.query("secret_keys", new String[]{ "c_key_data" }, - null, null, null, null, null); - if (cursor != null && cursor.moveToFirst()) { - do { - byte[] data = cursor.getBlob(0); - try { - PGPSecretKeyRing keyRing = new PGPSecretKeyRing(data); - saveKeyRing(keyRing); - } catch (IOException e) { - Log.e("apg.db.upgrade", "key import failed: " + e); - } catch (PGPException e) { - Log.e("apg.db.upgrade", "key import failed: " + e); - } catch (GeneralException e) { - Log.e("apg.db.upgrade", "key import failed: " + e); - } - } while (cursor.moveToNext()); - } - - if (cursor != null) { - cursor.close(); - } - - db.execSQL("DROP TABLE IF EXISTS public_keys;"); - db.execSQL("DROP TABLE IF EXISTS secret_keys;"); - - break; - } - - default: { - break; - } - } - } - mDb = null; - } - - public int saveKeyRing(PGPPublicKeyRing keyRing) throws IOException, GeneralException { - mDb.beginTransaction(); - ContentValues values = new ContentValues(); - PGPPublicKey masterKey = keyRing.getPublicKey(); - long masterKeyId = masterKey.getKeyID(); - - values.put(KeyRings.MASTER_KEY_ID, masterKeyId); - values.put(KeyRings.TYPE, Id.database.type_public); - values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); - - long rowId = insertOrUpdateKeyRing(values); - int returnValue = mStatus; - - if (rowId == -1) { - throw new GeneralException("saving public key ring " + masterKeyId + " failed"); - } - - Vector seenIds = new Vector(); - int rank = 0; - for (PGPPublicKey key : new IterableIterator(keyRing.getPublicKeys())) { - seenIds.add(saveKey(rowId, key, rank)); - ++rank; - } - - String seenIdsStr = ""; - for (Integer id : seenIds) { - if (seenIdsStr.length() > 0) { - seenIdsStr += ","; - } - seenIdsStr += id; - } - mDb.delete(Keys.TABLE_NAME, - Keys.KEY_RING_ID + " = ? AND " + - Keys._ID + " NOT IN (" + seenIdsStr + ")", - new String[] { "" + rowId }); - - mDb.setTransactionSuccessful(); - mDb.endTransaction(); - return returnValue; - } - - public int saveKeyRing(PGPSecretKeyRing keyRing) throws IOException, GeneralException { - mDb.beginTransaction(); - ContentValues values = new ContentValues(); - PGPSecretKey masterKey = keyRing.getSecretKey(); - long masterKeyId = masterKey.getKeyID(); - - values.put(KeyRings.MASTER_KEY_ID, masterKeyId); - values.put(KeyRings.TYPE, Id.database.type_secret); - values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); - - long rowId = insertOrUpdateKeyRing(values); - int returnValue = mStatus; - - if (rowId == -1) { - throw new GeneralException("saving secret key ring " + masterKeyId + " failed"); - } - - Vector seenIds = new Vector(); - int rank = 0; - for (PGPSecretKey key : new IterableIterator(keyRing.getSecretKeys())) { - seenIds.add(saveKey(rowId, key, rank)); - ++rank; - } - - String seenIdsStr = ""; - for (Integer id : seenIds) { - if (seenIdsStr.length() > 0) { - seenIdsStr += ","; - } - seenIdsStr += id; - } - mDb.delete(Keys.TABLE_NAME, - Keys.KEY_RING_ID + " = ? AND " + - Keys._ID + " NOT IN (" + seenIdsStr + ")", - new String[] { "" + rowId }); - - mDb.setTransactionSuccessful(); - mDb.endTransaction(); - return returnValue; - } - - private int saveKey(long keyRingId, PGPPublicKey key, int rank) - throws IOException, GeneralException { - ContentValues values = new ContentValues(); - - values.put(Keys.KEY_ID, key.getKeyID()); - values.put(Keys.TYPE, Id.database.type_public); - values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); - values.put(Keys.ALGORITHM, key.getAlgorithm()); - values.put(Keys.KEY_SIZE, key.getBitStrength()); - values.put(Keys.CAN_SIGN, PGPHelper.isSigningKey(key)); - values.put(Keys.CAN_ENCRYPT, PGPHelper.isEncryptionKey(key)); - values.put(Keys.IS_REVOKED, key.isRevoked()); - values.put(Keys.CREATION, PGPHelper.getCreationDate(key).getTime() / 1000); - Date expiryDate = PGPHelper.getExpiryDate(key); - if (expiryDate != null) { - values.put(Keys.EXPIRY, expiryDate.getTime() / 1000); - } - values.put(Keys.KEY_RING_ID, keyRingId); - values.put(Keys.KEY_DATA, key.getEncoded()); - values.put(Keys.RANK, rank); - - long rowId = insertOrUpdateKey(values); - - if (rowId == -1) { - throw new GeneralException("saving public key " + key.getKeyID() + " failed"); - } - - Vector seenIds = new Vector(); - int userIdRank = 0; - for (String userId : new IterableIterator(key.getUserIDs())) { - seenIds.add(saveUserId(rowId, userId, userIdRank)); - ++userIdRank; - } - - String seenIdsStr = ""; - for (Integer id : seenIds) { - if (seenIdsStr.length() > 0) { - seenIdsStr += ","; - } - seenIdsStr += id; - } - mDb.delete(UserIds.TABLE_NAME, - UserIds.KEY_ID + " = ? AND " + - UserIds._ID + " NOT IN (" + seenIdsStr + ")", - new String[] { "" + rowId }); - - return (int)rowId; - } - - private int saveKey(long keyRingId, PGPSecretKey key, int rank) - throws IOException, GeneralException { - ContentValues values = new ContentValues(); - - values.put(Keys.KEY_ID, key.getPublicKey().getKeyID()); - values.put(Keys.TYPE, Id.database.type_secret); - values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); - values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm()); - values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength()); - values.put(Keys.CAN_SIGN, PGPHelper.isSigningKey(key)); - values.put(Keys.CAN_ENCRYPT, PGPHelper.isEncryptionKey(key)); - values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked()); - values.put(Keys.CREATION, PGPHelper.getCreationDate(key).getTime() / 1000); - Date expiryDate = PGPHelper.getExpiryDate(key); - if (expiryDate != null) { - values.put(Keys.EXPIRY, expiryDate.getTime() / 1000); - } - values.put(Keys.KEY_RING_ID, keyRingId); - values.put(Keys.KEY_DATA, key.getEncoded()); - values.put(Keys.RANK, rank); - - long rowId = insertOrUpdateKey(values); - - if (rowId == -1) { - throw new GeneralException("saving secret key " + key.getPublicKey().getKeyID() + " failed"); - } - - Vector seenIds = new Vector(); - int userIdRank = 0; - for (String userId : new IterableIterator(key.getUserIDs())) { - seenIds.add(saveUserId(rowId, userId, userIdRank)); - ++userIdRank; - } - - String seenIdsStr = ""; - for (Integer id : seenIds) { - if (seenIdsStr.length() > 0) { - seenIdsStr += ","; - } - seenIdsStr += id; - } - mDb.delete(UserIds.TABLE_NAME, - UserIds.KEY_ID + " = ? AND " + - UserIds._ID + " NOT IN (" + seenIdsStr + ")", - new String[] { "" + rowId }); - - return (int)rowId; - } - - private int saveUserId(long keyId, String userId, int rank) throws GeneralException { - ContentValues values = new ContentValues(); - - values.put(UserIds.KEY_ID, keyId); - values.put(UserIds.USER_ID, userId); - values.put(UserIds.RANK, rank); - - long rowId = insertOrUpdateUserId(values); - - if (rowId == -1) { - throw new GeneralException("saving user id " + userId + " failed"); - } - - return (int)rowId; - } - - private long insertOrUpdateKeyRing(ContentValues values) { - Cursor c = mDb.query(KeyRings.TABLE_NAME, new String[] { KeyRings._ID }, - KeyRings.MASTER_KEY_ID + " = ? AND " + KeyRings.TYPE + " = ?", - new String[] { - values.getAsString(KeyRings.MASTER_KEY_ID), - values.getAsString(KeyRings.TYPE), - }, - null, null, null); - long rowId = -1; - if (c != null && c.moveToFirst()) { - rowId = c.getLong(0); - mDb.update(KeyRings.TABLE_NAME, values, - KeyRings._ID + " = ?", new String[] { "" + rowId }); - mStatus = Id.return_value.updated; - } else { - rowId = mDb.insert(KeyRings.TABLE_NAME, KeyRings.WHO_ID, values); - mStatus = Id.return_value.ok; - } - - if (c != null) { - c.close(); - } - - return rowId; - } - - private long insertOrUpdateKey(ContentValues values) { - Cursor c = mDb.query(Keys.TABLE_NAME, new String[] { Keys._ID }, - Keys.KEY_ID + " = ? AND " + Keys.TYPE + " = ?", - new String[] { - values.getAsString(Keys.KEY_ID), - values.getAsString(Keys.TYPE), - }, - null, null, null); - long rowId = -1; - if (c != null && c.moveToFirst()) { - rowId = c.getLong(0); - mDb.update(Keys.TABLE_NAME, values, - Keys._ID + " = ?", new String[] { "" + rowId }); - } else { - rowId = mDb.insert(Keys.TABLE_NAME, Keys.KEY_DATA, values); - } - - if (c != null) { - c.close(); - } - - return rowId; - } - - private long insertOrUpdateUserId(ContentValues values) { - Cursor c = mDb.query(UserIds.TABLE_NAME, new String[] { UserIds._ID }, - UserIds.KEY_ID + " = ? AND " + UserIds.USER_ID + " = ?", - new String[] { - values.getAsString(UserIds.KEY_ID), - values.getAsString(UserIds.USER_ID), - }, - null, null, null); - long rowId = -1; - if (c != null && c.moveToFirst()) { - rowId = c.getLong(0); - mDb.update(UserIds.TABLE_NAME, values, - UserIds._ID + " = ?", new String[] { "" + rowId }); - } else { - rowId = mDb.insert(UserIds.TABLE_NAME, UserIds.USER_ID, values); - } - - if (c != null) { - c.close(); - } - - return rowId; - } - - public Object getKeyRing(int keyRingId) { - Cursor c = mDb.query(KeyRings.TABLE_NAME, - new String[] { KeyRings.KEY_RING_DATA, KeyRings.TYPE }, - KeyRings._ID + " = ?", - new String[] { - "" + keyRingId, - }, - null, null, null); - byte[] data = null; - Object keyRing = null; - if (c != null && c.moveToFirst()) { - data = c.getBlob(0); - if (data != null) { - try { - if (c.getInt(1) == Id.database.type_public) { - keyRing = new PGPPublicKeyRing(data); - } else { - keyRing = new PGPSecretKeyRing(data); - } - } catch (IOException e) { - // can't load it, then - } catch (PGPException e) { - // can't load it, then - } - } - } - - if (c != null) { - c.close(); - } - - return keyRing; - } - - public byte[] getKeyRingDataFromKeyId(int type, long keyId) { - Cursor c = mDb.query(Keys.TABLE_NAME + " INNER JOIN " + KeyRings.TABLE_NAME + " ON (" + - KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + - Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + ")", - new String[] { KeyRings.TABLE_NAME + "." + KeyRings.KEY_RING_DATA }, - Keys.TABLE_NAME + "." + Keys.KEY_ID + " = ? AND " + - KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", - new String[] { - "" + keyId, - "" + type, - }, - null, null, null); - - byte[] data = null; - if (c != null && c.moveToFirst()) { - data = c.getBlob(0); - } - - if (c != null) { - c.close(); - } - - return data; - } - - public byte[] getKeyDataFromKeyId(int type, long keyId) { - Cursor c = mDb.query(Keys.TABLE_NAME, new String[] { Keys.KEY_DATA }, - Keys.KEY_ID + " = ? AND " + Keys.TYPE + " = ?", - new String[] { - "" + keyId, - "" + type, - }, - null, null, null); - byte[] data = null; - if (c != null && c.moveToFirst()) { - data = c.getBlob(0); - } - - if (c != null) { - c.close(); - } - - return data; - } - -// public void deleteKeyRing(int keyRingId) { -// mDb.beginTransaction(); -// mDb.delete(KeyRings.TABLE_NAME, -// KeyRings._ID + " = ?", new String[] { "" + keyRingId }); +///* +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ // -// Cursor c = mDb.query(Keys.TABLE_NAME, new String[] { Keys._ID }, -// Keys.KEY_RING_ID + " = ?", +//package org.thialfihar.android.apg.deprecated; +// +//import org.spongycastle.openpgp.PGPException; +//import org.spongycastle.openpgp.PGPPublicKey; +//import org.spongycastle.openpgp.PGPPublicKeyRing; +//import org.spongycastle.openpgp.PGPSecretKey; +//import org.spongycastle.openpgp.PGPSecretKeyRing; +//import org.thialfihar.android.apg.Id; +//import org.thialfihar.android.apg.helper.PGPHelper; +//import org.thialfihar.android.apg.util.IterableIterator; +// +//import android.content.ContentValues; +//import android.content.Context; +//import android.database.Cursor; +//import android.database.sqlite.SQLiteDatabase; +//import android.database.sqlite.SQLiteOpenHelper; +//import org.thialfihar.android.apg.util.Log; +// +//import java.io.IOException; +//import java.util.Date; +//import java.util.HashMap; +//import java.util.Vector; +// +//public class Database extends SQLiteOpenHelper { +// public static class GeneralException extends Exception { +// static final long serialVersionUID = 0xf812773343L; +// +// public GeneralException(String message) { +// super(message); +// } +// } +// +// private static final String DATABASE_NAME = "apg"; +// private static final int DATABASE_VERSION = 2; +// +// public static final String AUTHORITY = "org.thialfihar.android.apg.database"; +// +// public static HashMap sKeyRingsProjection; +// public static HashMap sKeysProjection; +// public static HashMap sUserIdsProjection; +// +// private SQLiteDatabase mDb = null; +// private int mStatus = 0; +// +// static { +// sKeyRingsProjection = new HashMap(); +// sKeyRingsProjection.put(KeyRings._ID, KeyRings._ID); +// sKeyRingsProjection.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID); +// sKeyRingsProjection.put(KeyRings.TYPE, KeyRings.TYPE); +// sKeyRingsProjection.put(KeyRings.WHO_ID, KeyRings.WHO_ID); +// sKeyRingsProjection.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA); +// +// sKeysProjection = new HashMap(); +// sKeysProjection.put(Keys._ID, Keys._ID); +// sKeysProjection.put(Keys.KEY_ID, Keys.KEY_ID); +// sKeysProjection.put(Keys.TYPE, Keys.TYPE); +// sKeysProjection.put(Keys.IS_MASTER_KEY, Keys.IS_MASTER_KEY); +// sKeysProjection.put(Keys.ALGORITHM, Keys.ALGORITHM); +// sKeysProjection.put(Keys.KEY_SIZE, Keys.KEY_SIZE); +// sKeysProjection.put(Keys.CAN_SIGN, Keys.CAN_SIGN); +// sKeysProjection.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT); +// sKeysProjection.put(Keys.IS_REVOKED, Keys.IS_REVOKED); +// sKeysProjection.put(Keys.CREATION, Keys.CREATION); +// sKeysProjection.put(Keys.EXPIRY, Keys.EXPIRY); +// sKeysProjection.put(Keys.KEY_DATA, Keys.KEY_DATA); +// sKeysProjection.put(Keys.RANK, Keys.RANK); +// +// sUserIdsProjection = new HashMap(); +// sUserIdsProjection.put(UserIds._ID, UserIds._ID); +// sUserIdsProjection.put(UserIds.KEY_ID, UserIds.KEY_ID); +// sUserIdsProjection.put(UserIds.USER_ID, UserIds.USER_ID); +// sUserIdsProjection.put(UserIds.RANK, UserIds.RANK); +// } +// +// public Database(Context context) { +// super(context, DATABASE_NAME, null, DATABASE_VERSION); +// // force upgrade to test things +// //onUpgrade(getWritableDatabase(), 1, 2); +// mDb = getWritableDatabase(); +// } +// +// @Override +// protected void finalize() throws Throwable { +// mDb.close(); +// super.finalize(); +// } +// +// @Override +// public void onCreate(SQLiteDatabase db) { +// db.execSQL("CREATE TABLE " + KeyRings.TABLE_NAME + " (" + +// KeyRings._ID + " " + KeyRings._ID_type + "," + +// KeyRings.MASTER_KEY_ID + " " + KeyRings.MASTER_KEY_ID_type + ", " + +// KeyRings.TYPE + " " + KeyRings.TYPE_type + ", " + +// KeyRings.WHO_ID + " " + KeyRings.WHO_ID_type + ", " + +// KeyRings.KEY_RING_DATA + " " + KeyRings.KEY_RING_DATA_type + ");"); +// +// db.execSQL("CREATE TABLE " + Keys.TABLE_NAME + " (" + +// Keys._ID + " " + Keys._ID_type + "," + +// Keys.KEY_ID + " " + Keys.KEY_ID_type + ", " + +// Keys.TYPE + " " + Keys.TYPE_type + ", " + +// Keys.IS_MASTER_KEY + " " + Keys.IS_MASTER_KEY_type + ", " + +// Keys.ALGORITHM + " " + Keys.ALGORITHM_type + ", " + +// Keys.KEY_SIZE + " " + Keys.KEY_SIZE_type + ", " + +// Keys.CAN_SIGN + " " + Keys.CAN_SIGN_type + ", " + +// Keys.CAN_ENCRYPT + " " + Keys.CAN_ENCRYPT_type + ", " + +// Keys.IS_REVOKED + " " + Keys.IS_REVOKED_type + ", " + +// Keys.CREATION + " " + Keys.CREATION_type + ", " + +// Keys.EXPIRY + " " + Keys.EXPIRY_type + ", " + +// Keys.KEY_RING_ID + " " + Keys.KEY_RING_ID_type + ", " + +// Keys.KEY_DATA + " " + Keys.KEY_DATA_type + +// Keys.RANK + " " + Keys.RANK_type + ");"); +// +// db.execSQL("CREATE TABLE " + UserIds.TABLE_NAME + " (" + +// UserIds._ID + " " + UserIds._ID_type + "," + +// UserIds.KEY_ID + " " + UserIds.KEY_ID_type + "," + +// UserIds.USER_ID + " " + UserIds.USER_ID_type + "," + +// UserIds.RANK + " " + UserIds.RANK_type + ");"); +// +// } +// +// @Override +// public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { +// mDb = db; +// for (int version = oldVersion; version < newVersion; ++version) { +// switch (version) { +// case 1: { // upgrade 1 to 2 +// db.execSQL("DROP TABLE IF EXISTS " + KeyRings.TABLE_NAME + ";"); +// db.execSQL("DROP TABLE IF EXISTS " + Keys.TABLE_NAME + ";"); +// db.execSQL("DROP TABLE IF EXISTS " + UserIds.TABLE_NAME + ";"); +// +// db.execSQL("CREATE TABLE " + KeyRings.TABLE_NAME + " (" + +// KeyRings._ID + " " + KeyRings._ID_type + "," + +// KeyRings.MASTER_KEY_ID + " " + KeyRings.MASTER_KEY_ID_type + ", " + +// KeyRings.TYPE + " " + KeyRings.TYPE_type + ", " + +// KeyRings.WHO_ID + " " + KeyRings.WHO_ID_type + ", " + +// KeyRings.KEY_RING_DATA + " " + KeyRings.KEY_RING_DATA_type + ");"); +// +// +// db.execSQL("CREATE TABLE " + Keys.TABLE_NAME + " (" + +// Keys._ID + " " + Keys._ID_type + "," + +// Keys.KEY_ID + " " + Keys.KEY_ID_type + ", " + +// Keys.TYPE + " " + Keys.TYPE_type + ", " + +// Keys.IS_MASTER_KEY + " " + Keys.IS_MASTER_KEY_type + ", " + +// Keys.ALGORITHM + " " + Keys.ALGORITHM_type + ", " + +// Keys.KEY_SIZE + " " + Keys.KEY_SIZE_type + ", " + +// Keys.CAN_SIGN + " " + Keys.CAN_SIGN_type + ", " + +// Keys.CAN_ENCRYPT + " " + Keys.CAN_ENCRYPT_type + ", " + +// Keys.IS_REVOKED + " " + Keys.IS_REVOKED_type + ", " + +// Keys.CREATION + " " + Keys.CREATION_type + ", " + +// Keys.EXPIRY + " " + Keys.EXPIRY_type + ", " + +// Keys.KEY_RING_ID + " " + Keys.KEY_RING_ID_type + ", " + +// Keys.KEY_DATA + " " + Keys.KEY_DATA_type + +// Keys.RANK + " " + Keys.RANK_type + ");"); +// +// db.execSQL("CREATE TABLE " + UserIds.TABLE_NAME + " (" + +// UserIds._ID + " " + UserIds._ID_type + "," + +// UserIds.KEY_ID + " " + UserIds.KEY_ID_type + "," + +// UserIds.USER_ID + " " + UserIds.USER_ID_type + "," + +// UserIds.RANK + " " + UserIds.RANK_type + ");"); +// +// Cursor cursor = db.query("public_keys", new String[] { "c_key_data" }, +// null, null, null, null, null); +// if (cursor != null && cursor.moveToFirst()) { +// do { +// byte[] data = cursor.getBlob(0); +// try { +// PGPPublicKeyRing keyRing = new PGPPublicKeyRing(data); +// saveKeyRing(keyRing); +// } catch (IOException e) { +// Log.e("apg.db.upgrade", "key import failed: " + e); +// } catch (GeneralException e) { +// Log.e("apg.db.upgrade", "key import failed: " + e); +// } +// } while (cursor.moveToNext()); +// } +// +// if (cursor != null) { +// cursor.close(); +// } +// +// cursor = db.query("secret_keys", new String[]{ "c_key_data" }, +// null, null, null, null, null); +// if (cursor != null && cursor.moveToFirst()) { +// do { +// byte[] data = cursor.getBlob(0); +// try { +// PGPSecretKeyRing keyRing = new PGPSecretKeyRing(data); +// saveKeyRing(keyRing); +// } catch (IOException e) { +// Log.e("apg.db.upgrade", "key import failed: " + e); +// } catch (PGPException e) { +// Log.e("apg.db.upgrade", "key import failed: " + e); +// } catch (GeneralException e) { +// Log.e("apg.db.upgrade", "key import failed: " + e); +// } +// } while (cursor.moveToNext()); +// } +// +// if (cursor != null) { +// cursor.close(); +// } +// +// db.execSQL("DROP TABLE IF EXISTS public_keys;"); +// db.execSQL("DROP TABLE IF EXISTS secret_keys;"); +// +// break; +// } +// +// default: { +// break; +// } +// } +// } +// mDb = null; +// } +// +// public int saveKeyRing(PGPPublicKeyRing keyRing) throws IOException, GeneralException { +// mDb.beginTransaction(); +// ContentValues values = new ContentValues(); +// PGPPublicKey masterKey = keyRing.getPublicKey(); +// long masterKeyId = masterKey.getKeyID(); +// +// values.put(KeyRings.MASTER_KEY_ID, masterKeyId); +// values.put(KeyRings.TYPE, Id.database.type_public); +// values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); +// +// long rowId = insertOrUpdateKeyRing(values); +// int returnValue = mStatus; +// +// if (rowId == -1) { +// throw new GeneralException("saving public key ring " + masterKeyId + " failed"); +// } +// +// Vector seenIds = new Vector(); +// int rank = 0; +// for (PGPPublicKey key : new IterableIterator(keyRing.getPublicKeys())) { +// seenIds.add(saveKey(rowId, key, rank)); +// ++rank; +// } +// +// String seenIdsStr = ""; +// for (Integer id : seenIds) { +// if (seenIdsStr.length() > 0) { +// seenIdsStr += ","; +// } +// seenIdsStr += id; +// } +// mDb.delete(Keys.TABLE_NAME, +// Keys.KEY_RING_ID + " = ? AND " + +// Keys._ID + " NOT IN (" + seenIdsStr + ")", +// new String[] { "" + rowId }); +// +// mDb.setTransactionSuccessful(); +// mDb.endTransaction(); +// return returnValue; +// } +// +// public int saveKeyRing(PGPSecretKeyRing keyRing) throws IOException, GeneralException { +// mDb.beginTransaction(); +// ContentValues values = new ContentValues(); +// PGPSecretKey masterKey = keyRing.getSecretKey(); +// long masterKeyId = masterKey.getKeyID(); +// +// values.put(KeyRings.MASTER_KEY_ID, masterKeyId); +// values.put(KeyRings.TYPE, Id.database.type_secret); +// values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); +// +// long rowId = insertOrUpdateKeyRing(values); +// int returnValue = mStatus; +// +// if (rowId == -1) { +// throw new GeneralException("saving secret key ring " + masterKeyId + " failed"); +// } +// +// Vector seenIds = new Vector(); +// int rank = 0; +// for (PGPSecretKey key : new IterableIterator(keyRing.getSecretKeys())) { +// seenIds.add(saveKey(rowId, key, rank)); +// ++rank; +// } +// +// String seenIdsStr = ""; +// for (Integer id : seenIds) { +// if (seenIdsStr.length() > 0) { +// seenIdsStr += ","; +// } +// seenIdsStr += id; +// } +// mDb.delete(Keys.TABLE_NAME, +// Keys.KEY_RING_ID + " = ? AND " + +// Keys._ID + " NOT IN (" + seenIdsStr + ")", +// new String[] { "" + rowId }); +// +// mDb.setTransactionSuccessful(); +// mDb.endTransaction(); +// return returnValue; +// } +// +// private int saveKey(long keyRingId, PGPPublicKey key, int rank) +// throws IOException, GeneralException { +// ContentValues values = new ContentValues(); +// +// values.put(Keys.KEY_ID, key.getKeyID()); +// values.put(Keys.TYPE, Id.database.type_public); +// values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); +// values.put(Keys.ALGORITHM, key.getAlgorithm()); +// values.put(Keys.KEY_SIZE, key.getBitStrength()); +// values.put(Keys.CAN_SIGN, PGPHelper.isSigningKey(key)); +// values.put(Keys.CAN_ENCRYPT, PGPHelper.isEncryptionKey(key)); +// values.put(Keys.IS_REVOKED, key.isRevoked()); +// values.put(Keys.CREATION, PGPHelper.getCreationDate(key).getTime() / 1000); +// Date expiryDate = PGPHelper.getExpiryDate(key); +// if (expiryDate != null) { +// values.put(Keys.EXPIRY, expiryDate.getTime() / 1000); +// } +// values.put(Keys.KEY_RING_ID, keyRingId); +// values.put(Keys.KEY_DATA, key.getEncoded()); +// values.put(Keys.RANK, rank); +// +// long rowId = insertOrUpdateKey(values); +// +// if (rowId == -1) { +// throw new GeneralException("saving public key " + key.getKeyID() + " failed"); +// } +// +// Vector seenIds = new Vector(); +// int userIdRank = 0; +// for (String userId : new IterableIterator(key.getUserIDs())) { +// seenIds.add(saveUserId(rowId, userId, userIdRank)); +// ++userIdRank; +// } +// +// String seenIdsStr = ""; +// for (Integer id : seenIds) { +// if (seenIdsStr.length() > 0) { +// seenIdsStr += ","; +// } +// seenIdsStr += id; +// } +// mDb.delete(UserIds.TABLE_NAME, +// UserIds.KEY_ID + " = ? AND " + +// UserIds._ID + " NOT IN (" + seenIdsStr + ")", +// new String[] { "" + rowId }); +// +// return (int)rowId; +// } +// +// private int saveKey(long keyRingId, PGPSecretKey key, int rank) +// throws IOException, GeneralException { +// ContentValues values = new ContentValues(); +// +// values.put(Keys.KEY_ID, key.getPublicKey().getKeyID()); +// values.put(Keys.TYPE, Id.database.type_secret); +// values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); +// values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm()); +// values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength()); +// values.put(Keys.CAN_SIGN, PGPHelper.isSigningKey(key)); +// values.put(Keys.CAN_ENCRYPT, PGPHelper.isEncryptionKey(key)); +// values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked()); +// values.put(Keys.CREATION, PGPHelper.getCreationDate(key).getTime() / 1000); +// Date expiryDate = PGPHelper.getExpiryDate(key); +// if (expiryDate != null) { +// values.put(Keys.EXPIRY, expiryDate.getTime() / 1000); +// } +// values.put(Keys.KEY_RING_ID, keyRingId); +// values.put(Keys.KEY_DATA, key.getEncoded()); +// values.put(Keys.RANK, rank); +// +// long rowId = insertOrUpdateKey(values); +// +// if (rowId == -1) { +// throw new GeneralException("saving secret key " + key.getPublicKey().getKeyID() + " failed"); +// } +// +// Vector seenIds = new Vector(); +// int userIdRank = 0; +// for (String userId : new IterableIterator(key.getUserIDs())) { +// seenIds.add(saveUserId(rowId, userId, userIdRank)); +// ++userIdRank; +// } +// +// String seenIdsStr = ""; +// for (Integer id : seenIds) { +// if (seenIdsStr.length() > 0) { +// seenIdsStr += ","; +// } +// seenIdsStr += id; +// } +// mDb.delete(UserIds.TABLE_NAME, +// UserIds.KEY_ID + " = ? AND " + +// UserIds._ID + " NOT IN (" + seenIdsStr + ")", +// new String[] { "" + rowId }); +// +// return (int)rowId; +// } +// +// private int saveUserId(long keyId, String userId, int rank) throws GeneralException { +// ContentValues values = new ContentValues(); +// +// values.put(UserIds.KEY_ID, keyId); +// values.put(UserIds.USER_ID, userId); +// values.put(UserIds.RANK, rank); +// +// long rowId = insertOrUpdateUserId(values); +// +// if (rowId == -1) { +// throw new GeneralException("saving user id " + userId + " failed"); +// } +// +// return (int)rowId; +// } +// +// private long insertOrUpdateKeyRing(ContentValues values) { +// Cursor c = mDb.query(KeyRings.TABLE_NAME, new String[] { KeyRings._ID }, +// KeyRings.MASTER_KEY_ID + " = ? AND " + KeyRings.TYPE + " = ?", // new String[] { -// "" + keyRingId, +// values.getAsString(KeyRings.MASTER_KEY_ID), +// values.getAsString(KeyRings.TYPE), // }, -// null, null, null); +// null, null, null); +// long rowId = -1; // if (c != null && c.moveToFirst()) { -// do { -// int keyId = c.getInt(0); -// deleteKey(keyId); -// } while (c.moveToNext()); +// rowId = c.getLong(0); +// mDb.update(KeyRings.TABLE_NAME, values, +// KeyRings._ID + " = ?", new String[] { "" + rowId }); +// mStatus = Id.return_value.updated; +// } else { +// rowId = mDb.insert(KeyRings.TABLE_NAME, KeyRings.WHO_ID, values); +// mStatus = Id.return_value.ok; // } // // if (c != null) { // c.close(); // } // -// mDb.setTransactionSuccessful(); -// mDb.endTransaction(); +// return rowId; // } // -// private void deleteKey(int keyId) { -// mDb.delete(Keys.TABLE_NAME, -// Keys._ID + " = ?", new String[] { "" + keyId }); +// private long insertOrUpdateKey(ContentValues values) { +// Cursor c = mDb.query(Keys.TABLE_NAME, new String[] { Keys._ID }, +// Keys.KEY_ID + " = ? AND " + Keys.TYPE + " = ?", +// new String[] { +// values.getAsString(Keys.KEY_ID), +// values.getAsString(Keys.TYPE), +// }, +// null, null, null); +// long rowId = -1; +// if (c != null && c.moveToFirst()) { +// rowId = c.getLong(0); +// mDb.update(Keys.TABLE_NAME, values, +// Keys._ID + " = ?", new String[] { "" + rowId }); +// } else { +// rowId = mDb.insert(Keys.TABLE_NAME, Keys.KEY_DATA, values); +// } // -// mDb.delete(UserIds.TABLE_NAME, -// UserIds.KEY_ID + " = ?", new String[] { "" + keyId }); +// if (c != null) { +// c.close(); +// } +// +// return rowId; // } // -// public SQLiteDatabase db() { -// return mDb; +// private long insertOrUpdateUserId(ContentValues values) { +// Cursor c = mDb.query(UserIds.TABLE_NAME, new String[] { UserIds._ID }, +// UserIds.KEY_ID + " = ? AND " + UserIds.USER_ID + " = ?", +// new String[] { +// values.getAsString(UserIds.KEY_ID), +// values.getAsString(UserIds.USER_ID), +// }, +// null, null, null); +// long rowId = -1; +// if (c != null && c.moveToFirst()) { +// rowId = c.getLong(0); +// mDb.update(UserIds.TABLE_NAME, values, +// UserIds._ID + " = ?", new String[] { "" + rowId }); +// } else { +// rowId = mDb.insert(UserIds.TABLE_NAME, UserIds.USER_ID, values); +// } +// +// if (c != null) { +// c.close(); +// } +// +// return rowId; // } -} +// +// public Object getKeyRing(int keyRingId) { +// Cursor c = mDb.query(KeyRings.TABLE_NAME, +// new String[] { KeyRings.KEY_RING_DATA, KeyRings.TYPE }, +// KeyRings._ID + " = ?", +// new String[] { +// "" + keyRingId, +// }, +// null, null, null); +// byte[] data = null; +// Object keyRing = null; +// if (c != null && c.moveToFirst()) { +// data = c.getBlob(0); +// if (data != null) { +// try { +// if (c.getInt(1) == Id.database.type_public) { +// keyRing = new PGPPublicKeyRing(data); +// } else { +// keyRing = new PGPSecretKeyRing(data); +// } +// } catch (IOException e) { +// // can't load it, then +// } catch (PGPException e) { +// // can't load it, then +// } +// } +// } +// +// if (c != null) { +// c.close(); +// } +// +// return keyRing; +// } +// +// public byte[] getKeyRingDataFromKeyId(int type, long keyId) { +// Cursor c = mDb.query(Keys.TABLE_NAME + " INNER JOIN " + KeyRings.TABLE_NAME + " ON (" + +// KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + +// Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + ")", +// new String[] { KeyRings.TABLE_NAME + "." + KeyRings.KEY_RING_DATA }, +// Keys.TABLE_NAME + "." + Keys.KEY_ID + " = ? AND " + +// KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", +// new String[] { +// "" + keyId, +// "" + type, +// }, +// null, null, null); +// +// byte[] data = null; +// if (c != null && c.moveToFirst()) { +// data = c.getBlob(0); +// } +// +// if (c != null) { +// c.close(); +// } +// +// return data; +// } +// +// public byte[] getKeyDataFromKeyId(int type, long keyId) { +// Cursor c = mDb.query(Keys.TABLE_NAME, new String[] { Keys.KEY_DATA }, +// Keys.KEY_ID + " = ? AND " + Keys.TYPE + " = ?", +// new String[] { +// "" + keyId, +// "" + type, +// }, +// null, null, null); +// byte[] data = null; +// if (c != null && c.moveToFirst()) { +// data = c.getBlob(0); +// } +// +// if (c != null) { +// c.close(); +// } +// +// return data; +// } +// +//// public void deleteKeyRing(int keyRingId) { +//// mDb.beginTransaction(); +//// mDb.delete(KeyRings.TABLE_NAME, +//// KeyRings._ID + " = ?", new String[] { "" + keyRingId }); +//// +//// Cursor c = mDb.query(Keys.TABLE_NAME, new String[] { Keys._ID }, +//// Keys.KEY_RING_ID + " = ?", +//// new String[] { +//// "" + keyRingId, +//// }, +//// null, null, null); +//// if (c != null && c.moveToFirst()) { +//// do { +//// int keyId = c.getInt(0); +//// deleteKey(keyId); +//// } while (c.moveToNext()); +//// } +//// +//// if (c != null) { +//// c.close(); +//// } +//// +//// mDb.setTransactionSuccessful(); +//// mDb.endTransaction(); +//// } +//// +//// private void deleteKey(int keyId) { +//// mDb.delete(Keys.TABLE_NAME, +//// Keys._ID + " = ?", new String[] { "" + keyId }); +//// +//// mDb.delete(UserIds.TABLE_NAME, +//// UserIds.KEY_ID + " = ?", new String[] { "" + keyId }); +//// } +//// +//// public SQLiteDatabase db() { +//// return mDb; +//// } +//} diff --git a/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java b/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java index 960d71286..a5d5ced5e 100644 --- a/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java +++ b/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java @@ -191,7 +191,7 @@ public class PGPHelper { } public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) { - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId); + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, masterKeyId); if (keyRing == null) { return null; } @@ -203,7 +203,7 @@ public class PGPHelper { } public static PGPSecretKey getSigningKey(Context context, long masterKeyId) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, masterKeyId); if (keyRing == null) { return null; } diff --git a/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java b/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java index dc4323090..2c117f288 100644 --- a/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java +++ b/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java @@ -87,9 +87,6 @@ import org.thialfihar.android.apg.R; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.net.Uri; import android.os.Bundle; import android.os.Environment; import org.thialfihar.android.apg.util.Log; @@ -123,8 +120,6 @@ import java.util.regex.Pattern; /** * TODO: * - * - Externalize the authority and content uri constants - * * - Separate this file into different helpers * */ @@ -138,22 +133,6 @@ public class PGPMain { // Not BC due to the use of Spongy Castle for Android public static final String BOUNCY_CASTLE_PROVIDER_NAME = "SC"; - // public static final String AUTHORITY = DataProvider.AUTHORITY; - - // public static final Uri CONTENT_URI_SECRET_KEY_RINGS = Uri.parse("content://" + AUTHORITY - // + "/key_rings/secret/"); - // public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID = Uri.parse("content://" - // + AUTHORITY + "/key_rings/secret/key_id/"); - // public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_EMAILS = Uri.parse("content://" - // + AUTHORITY + "/key_rings/secret/emails/"); - // - // public static final Uri CONTENT_URI_PUBLIC_KEY_RINGS = Uri.parse("content://" + AUTHORITY - // + "/key_rings/public/"); - // public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID = Uri.parse("content://" - // + AUTHORITY + "/key_rings/public/key_id/"); - // public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS = Uri.parse("content://" - // + AUTHORITY + "/key_rings/public/emails/"); - private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] { SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5, @@ -178,8 +157,6 @@ public class PGPMain { private static String mEditPassPhrase = null; - // private static Database mDatabase = null; - public static class ApgGeneralException extends Exception { static final long serialVersionUID = 0xf812773342L; @@ -196,16 +173,6 @@ public class PGPMain { } } - // public static void initialize(Context context) { - // if (mDatabase == null) { - // mDatabase = new Database(context); - // } - // } - // - // public static Database getDatabase() { - // return mDatabase; - // } - public static void setEditPassPhrase(String passPhrase) { mEditPassPhrase = passPhrase; } @@ -484,13 +451,13 @@ public class PGPMain { updateProgress(progress, R.string.progress_savingKeyRing, 90, 100); - mDatabase.saveKeyRing(secretKeyRing); - mDatabase.saveKeyRing(publicKeyRing); + ProviderHelper.saveKeyRing(context, secretKeyRing); + ProviderHelper.saveKeyRing(context, publicKeyRing); updateProgress(progress, R.string.progress_done, 100, 100); } - public static int storeKeyRingInCache(PGPKeyRing keyring) { + public static int storeKeyRingInCache(Context context, PGPKeyRing keyring) { int status = Integer.MIN_VALUE; // out of bounds value (Id.retrun_value.*) try { if (keyring instanceof PGPSecretKeyRing) { @@ -512,11 +479,15 @@ public class PGPMain { } if (save) { - status = mDatabase.saveKeyRing(secretKeyRing); + ProviderHelper.saveKeyRing(context, secretKeyRing); + // TODO: remove status returns, use exceptions! + status = Id.return_value.ok; } } else if (keyring instanceof PGPPublicKeyRing) { PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring; - status = mDatabase.saveKeyRing(publicKeyRing); + ProviderHelper.saveKeyRing(context, publicKeyRing); + // TODO: remove status returns, use exceptions! + status = Id.return_value.ok; } } catch (IOException e) { status = Id.return_value.error; @@ -582,7 +553,7 @@ public class PGPMain { // if this key is what we expect it to be, save it if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing) || (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) { - status = storeKeyRingInCache(keyring); + status = storeKeyRingInCache(context, keyring); } if (status == Id.return_value.error) { @@ -640,12 +611,12 @@ public class PGPMain { updateProgress(progress, i * 100 / keyRingIds.size(), 100); // try to get it as a PGPPublicKeyRing, if that fails try to get it as a SecretKeyRing - PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRing(context, + PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, keyRingIds.get(i)); if (publicKeyRing != null) { publicKeyRing.encode(out); } else { - PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRing(context, + PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, keyRingIds.get(i)); if (secretKeyRing != null) { secretKeyRing.encode(out); @@ -758,7 +729,7 @@ public class PGPMain { } if (signatureKeyId != Id.key.none) { - signingKeyRing = ProviderHelper.getPGPSecretKeyRing(context, signatureKeyId); + signingKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, signatureKeyId); signingKey = PGPHelper.getSigningKey(context, signatureKeyId); if (signingKey == null) { throw new ApgGeneralException(context.getString(R.string.error_signatureFailed)); @@ -911,7 +882,7 @@ public class PGPMain { throw new ApgGeneralException(context.getString(R.string.error_noSignatureKey)); } - signingKeyRing = ProviderHelper.getPGPSecretKeyRing(context, signatureKeyId); + signingKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, signatureKeyId); signingKey = PGPHelper.getSigningKey(context, signatureKeyId); if (signingKey == null) { armorOut.close(); @@ -1027,7 +998,7 @@ public class PGPMain { throw new ApgGeneralException(context.getString(R.string.error_noSignatureKey)); } - signingKeyRing = ProviderHelper.getPGPSecretKeyRing(context, signatureKeyId); + signingKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, signatureKeyId); signingKey = PGPHelper.getSigningKey(context, signatureKeyId); if (signingKey == null) { throw new ApgGeneralException(context.getString(R.string.error_signatureFailed)); @@ -1127,7 +1098,7 @@ public class PGPMain { if (passphrase == null || passphrase.length() <= 0) { throw new ApgGeneralException("Unable to obtain passphrase"); } else { - PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRing(context, pubKeyId); + PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, pubKeyId); PGPSecretKey signingKey = PGPHelper.getSigningKey(context, masterKeyId); if (signingKey == null) { @@ -1385,7 +1356,7 @@ public class PGPMain { signatureIndex = i; signatureKeyId = signature.getKeyID(); String userId = null; - PGPPublicKeyRing sigKeyRing = ProviderHelper.getPGPPublicKeyRing(context, + PGPPublicKeyRing sigKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, signatureKeyId); if (sigKeyRing != null) { userId = PGPHelper.getMainUserId(PGPHelper.getMasterKey(sigKeyRing)); @@ -1551,7 +1522,7 @@ public class PGPMain { } else { signatureKeyId = signature.getKeyID(); String userId = null; - PGPPublicKeyRing sigKeyRing = ProviderHelper.getPGPPublicKeyRing(context, + PGPPublicKeyRing sigKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, signatureKeyId); if (sigKeyRing != null) { userId = PGPHelper.getMainUserId(PGPHelper.getMasterKey(sigKeyRing)); diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java b/org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java index 66c611d4b..05a26157a 100644 --- a/org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java +++ b/org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java @@ -22,25 +22,12 @@ import org.thialfihar.android.apg.Constants; import android.net.Uri; import android.provider.BaseColumns; -/** - * TODO: - * - * Breaking compatibility?: - * - * - change CONTENT_AUTHORITY - * - * - change type names - * - */ public class ApgContract { - // APG1: all rows had a "c_" prefix - interface KeyRingsColumns { - String MASTER_KEY_ROW_ID = "master_key_id"; // TODO: clarify + String MASTER_KEY_ID = "master_key_id"; // not a database id String TYPE = "type"; // see KeyTypes - String WHO_ID = "who_id"; // TODO: is this used? - String KEY_RING_DATA = "key_ring_data"; // blob + String KEY_RING_DATA = "key_ring_data"; // PGPPublicKeyRing / PGPSecretKeyRing blob } interface KeysColumns { @@ -54,13 +41,13 @@ public class ApgContract { String IS_REVOKED = "is_revoked"; String CREATION = "creation"; String EXPIRY = "expiry"; - String KEY_RING_ROW_ID = "key_ring_id"; // foreign key to key_rings._ID - String KEY_DATA = "key_data"; // blob - String RANK = "rank"; // APG1: this was "key_data", TODO: Bug? Is this even used? + 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"; } interface UserIdsColumns { - String KEY_ROW_ID = "key_id"; // foreign key to keys._ID + String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID String USER_ID = "user_id"; // not a database id String RANK = "rank"; } @@ -70,7 +57,6 @@ public class ApgContract { public static final int SECRET = 1; } - // APG1: "org.thialfihar.android.apg.provider"; public static final String CONTENT_AUTHORITY = Constants.PACKAGE_NAME; private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); @@ -81,11 +67,10 @@ public class ApgContract { public static final String PATH_PUBLIC = "public"; public static final String PATH_SECRET = "secret"; + public static final String PATH_BY_MASTER_KEY_ID = "master_key_id"; public static final String PATH_BY_KEY_ID = "key_id"; public static final String PATH_BY_EMAILS = "emails"; - public static final String PATH_RANK = "#"; - public static final String PATH_USER_IDS = "user_ids"; public static final String PATH_KEYS = "keys"; @@ -107,8 +92,13 @@ public class ApgContract { return CONTENT_URI.buildUpon().appendPath(keyRingRowId).build(); } - public static Uri buildPublicKeyRingsByKeyIdUri(String keyRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_BY_KEY_ID).appendPath(keyRowId).build(); + public static Uri buildPublicKeyRingsByMasterKeyIdUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(PATH_BY_MASTER_KEY_ID) + .appendPath(masterKeyId).build(); + } + + public static Uri buildPublicKeyRingsByKeyIdUri(String keyId) { + return CONTENT_URI.buildUpon().appendPath(PATH_BY_KEY_ID).appendPath(keyId).build(); } public static Uri buildPublicKeyRingsByEmailsUri(String emails) { @@ -134,8 +124,13 @@ public class ApgContract { return CONTENT_URI.buildUpon().appendPath(keyRingRowId).build(); } - public static Uri buildSecretKeyRingsByKeyIdUri(String keyRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_BY_KEY_ID).appendPath(keyRowId).build(); + public static Uri buildSecretKeyRingsByMasterKeyIdUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(PATH_BY_MASTER_KEY_ID) + .appendPath(masterKeyId).build(); + } + + public static Uri buildSecretKeyRingsByKeyIdUri(String keyId) { + return CONTENT_URI.buildUpon().appendPath(PATH_BY_KEY_ID).appendPath(keyId).build(); } public static Uri buildSecretKeyRingsByEmailsUri(String emails) { @@ -157,9 +152,9 @@ public class ApgContract { return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_KEYS).build(); } - public static Uri buildPublicKeysRankUri(String keyRingRowId) { + public static Uri buildPublicKeysUri(String keyRingRowId, String keyRowId) { return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_KEYS) - .appendPath(PATH_RANK).build(); + .appendPath(keyRowId).build(); } } @@ -177,9 +172,9 @@ public class ApgContract { return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_KEYS).build(); } - public static Uri buildSecretKeysRankUri(String keyRingRowId) { + public static Uri buildSecretKeysUri(String keyRingRowId, String keyRowId) { return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_KEYS) - .appendPath(PATH_RANK).build(); + .appendPath(keyRowId).build(); } } @@ -198,9 +193,9 @@ public class ApgContract { .build(); } - public static Uri buildPublicUserIdsRankUri(String keyRingRowId) { + public static Uri buildPublicUserIdsUri(String keyRingRowId, String userIdRowId) { return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_USER_IDS) - .appendPath(PATH_RANK).build(); + .appendPath(userIdRowId).build(); } } @@ -219,9 +214,9 @@ public class ApgContract { .build(); } - public static Uri buildSecretUserIdsRankUri(String keyRingRowId) { + public static Uri buildSecretUserIdsUri(String keyRingRowId, String userIdRowId) { return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_USER_IDS) - .appendPath(PATH_RANK).build(); + .appendPath(userIdRowId).build(); } } diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java b/org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java index b70cfa7b6..050320cb6 100644 --- a/org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java +++ b/org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java @@ -30,80 +30,40 @@ import android.provider.BaseColumns; import org.thialfihar.android.apg.util.Log; public class ApgDatabase extends SQLiteOpenHelper { - // APG1: "apg" private static final String DATABASE_NAME = "apg.db"; - // APG1: 2 private static final int DATABASE_VERSION = 3; public interface Tables { String KEY_RINGS = "key_rings"; String KEYS = "keys"; - String USERS = "user_ids"; + String USER_IDS = "user_ids"; } - // APG1: REFERENCES where not implemented private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS - + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY, " + KeyRingsColumns.MASTER_KEY_ROW_ID - + " INT64, " + KeyRingsColumns.TYPE + " INTEGER, " + KeyRingsColumns.WHO_ID - + " INTEGER, " + KeyRingsColumns.KEY_RING_DATA + " BLOB)"; + + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + 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, " + KeysColumns.KEY_ID + " INT64, " - + KeysColumns.TYPE + " INTEGER, " + KeysColumns.IS_MASTER_KEY + " INTEGER, " - + KeysColumns.ALGORITHM + " INTEGER, " + KeysColumns.KEY_SIZE + " INTEGER, " - + KeysColumns.CAN_SIGN + " INTEGER, " + KeysColumns.CAN_ENCRYPT + " INTEGER, " - + KeysColumns.IS_REVOKED + " INTEGER, " + KeysColumns.CREATION + " INTEGER, " - + KeysColumns.EXPIRY + " INTEGER, " + KeysColumns.KEY_RING_ROW_ID + + 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_SIGN + " INTEGER, " + KeysColumns.CAN_ENCRYPT + + " INTEGER, " + KeysColumns.IS_REVOKED + " INTEGER, " + KeysColumns.CREATION + + " INTEGER, " + KeysColumns.EXPIRY + " INTEGER, " + KeysColumns.KEY_RING_ROW_ID + " INTEGER REFERENCES " + Tables.KEY_RINGS + " ON DELETE CASCADE, " + KeysColumns.KEY_DATA + " BLOB," + KeysColumns.RANK + " INTEGER)"; - private static final String CREATE_USER_IDS = "CREATE TABLE IF NOT EXISTS " + Tables.USERS - + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY, " + UserIdsColumns.KEY_ROW_ID - + " INTEGER REFERENCES " + Tables.KEYS + " ON DELETE CASCADE, " - + UserIdsColumns.USER_ID + " TEXT, " + UserIdsColumns.RANK + " INTEGER)"; + private static final String CREATE_USER_IDS = "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS + + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + UserIdsColumns.KEY_RING_ROW_ID + " INTEGER REFERENCES " + Tables.KEY_RINGS + + " ON DELETE CASCADE, " + UserIdsColumns.USER_ID + " TEXT, " + UserIdsColumns.RANK + + " INTEGER)"; ApgDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } - // - // public static HashMap sKeyRingsProjection; - // public static HashMap sKeysProjection; - // public static HashMap sUserIdsProjection; - // - // private SQLiteDatabase mDb = null; - // private int mStatus = 0; - // - // static { - // sKeyRingsProjection = new HashMap(); - // sKeyRingsProjection.put(KeyRings._ID, KeyRings._ID); - // sKeyRingsProjection.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID); - // sKeyRingsProjection.put(KeyRings.TYPE, KeyRings.TYPE); - // sKeyRingsProjection.put(KeyRings.WHO_ID, KeyRings.WHO_ID); - // sKeyRingsProjection.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA); - // - // sKeysProjection = new HashMap(); - // sKeysProjection.put(Keys._ID, Keys._ID); - // sKeysProjection.put(Keys.KEY_ID, Keys.KEY_ID); - // sKeysProjection.put(Keys.TYPE, Keys.TYPE); - // sKeysProjection.put(Keys.IS_MASTER_KEY, Keys.IS_MASTER_KEY); - // sKeysProjection.put(Keys.ALGORITHM, Keys.ALGORITHM); - // sKeysProjection.put(Keys.KEY_SIZE, Keys.KEY_SIZE); - // sKeysProjection.put(Keys.CAN_SIGN, Keys.CAN_SIGN); - // sKeysProjection.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT); - // sKeysProjection.put(Keys.IS_REVOKED, Keys.IS_REVOKED); - // sKeysProjection.put(Keys.CREATION, Keys.CREATION); - // sKeysProjection.put(Keys.EXPIRY, Keys.EXPIRY); - // sKeysProjection.put(Keys.KEY_DATA, Keys.KEY_DATA); - // sKeysProjection.put(Keys.RANK, Keys.RANK); - // - // sUserIdsProjection = new HashMap(); - // sUserIdsProjection.put(UserIds._ID, UserIds._ID); - // sUserIdsProjection.put(UserIds.KEY_ID, UserIds.KEY_ID); - // sUserIdsProjection.put(UserIds.USER_ID, UserIds.USER_ID); - // sUserIdsProjection.put(UserIds.RANK, UserIds.RANK); - // } - @Override public void onCreate(SQLiteDatabase db) { Log.w(Constants.TAG, "Creating database..."); diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java b/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java index 06d07fe5e..fce03600d 100644 --- a/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java +++ b/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java @@ -54,22 +54,28 @@ public class ApgProvider extends ContentProvider { private static final UriMatcher sUriMatcher = buildUriMatcher(); private static final int PUBLIC_KEY_RING = 101; - private static final int PUBLIC_KEY_RING_ROW_ID = 102; - private static final int PUBLIC_KEY_RING_BY_KEY_ID = 103; // TODO: Is this row id??? - private static final int PUBLIC_KEY_RING_BY_EMAILS = 104; + private static final int PUBLIC_KEY_RING_BY_ROW_ID = 102; + private static final int PUBLIC_KEY_RING_BY_MASTER_KEY_ID = 103; + private static final int PUBLIC_KEY_RING_BY_KEY_ID = 104; + private static final int PUBLIC_KEY_RING_BY_EMAILS = 105; + private static final int PUBLIC_KEY_RING_KEY = 111; - private static final int PUBLIC_KEY_RING_KEY_RANK = 112; + private static final int PUBLIC_KEY_RING_KEY_BY_ROW_ID = 112; + private static final int PUBLIC_KEY_RING_USER_ID = 121; - private static final int PUBLIC_KEY_RING_USER_ID_RANK = 122; + private static final int PUBLIC_KEY_RING_USER_ID_BY_ROW_ID = 122; private static final int SECRET_KEY_RING = 201; - private static final int SECRET_KEY_RING_ROW_ID = 202; - private static final int SECRET_KEY_RING_BY_KEY_ID = 203; - private static final int SECRET_KEY_RING_BY_EMAILS = 204; + private static final int SECRET_KEY_RING_BY_ROW_ID = 202; + private static final int SECRET_KEY_RING_BY_MASTER_KEY_ID = 203; + private static final int SECRET_KEY_RING_BY_KEY_ID = 204; + private static final int SECRET_KEY_RING_BY_EMAILS = 205; + private static final int SECRET_KEY_RING_KEY = 211; - private static final int SECRET_KEY_RING_KEY_RANK = 212; + private static final int SECRET_KEY_RING_KEY_BY_ROW_ID = 212; + private static final int SECRET_KEY_RING_USER_ID = 221; - private static final int SECRET_KEY_RING_USER_ID_RANK = 222; + private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222; private static final int DATA_STREAM = 301; @@ -86,7 +92,8 @@ public class ApgProvider extends ContentProvider { * *
          * key_rings/public
-         * key_rings/public/_
+         * key_rings/public/#
+         * key_rings/public/master_key_id/_
          * key_rings/public/key_id/_
          * key_rings/public/emails/_
          * 
@@ -94,8 +101,10 @@ public class ApgProvider extends ContentProvider { matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC, PUBLIC_KEY_RING); matcher.addURI(authority, - ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC + "/*", - PUBLIC_KEY_RING_ROW_ID); + ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC + "/#", + PUBLIC_KEY_RING_BY_ROW_ID); + matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC + "/" + + ApgContract.PATH_BY_MASTER_KEY_ID + "/*", PUBLIC_KEY_RING_BY_MASTER_KEY_ID); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC + "/" + ApgContract.PATH_BY_KEY_ID + "/*", PUBLIC_KEY_RING_BY_KEY_ID); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC + "/" @@ -105,45 +114,46 @@ public class ApgProvider extends ContentProvider { * public keys * *
-         * key_rings/public/_/keys
-         * key_rings/public/_/keys/#
+         * key_rings/public/#/keys
+         * key_rings/public/#/keys/#
          * 
*/ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC - + "/*/" + ApgContract.PATH_KEYS, PUBLIC_KEY_RING_KEY); + + "/#/" + ApgContract.PATH_KEYS, PUBLIC_KEY_RING_KEY); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC - + "/*/" + ApgContract.PATH_KEYS + "/" + ApgContract.PATH_RANK, - PUBLIC_KEY_RING_KEY_RANK); + + "/#/" + ApgContract.PATH_KEYS + "/#", PUBLIC_KEY_RING_KEY_BY_ROW_ID); /** * public user ids * *
-         * key_rings/public/_/user_ids
-         * key_rings/public/_/user_ids/#
+         * key_rings/public/#/user_ids
+         * key_rings/public/#/user_ids/#
          * 
*/ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC - + "/*/" + ApgContract.PATH_USER_IDS, PUBLIC_KEY_RING_USER_ID); + + "/#/" + ApgContract.PATH_USER_IDS, PUBLIC_KEY_RING_USER_ID); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC - + "/*/" + ApgContract.PATH_USER_IDS + "/" + ApgContract.PATH_RANK, - PUBLIC_KEY_RING_USER_ID_RANK); + + "/#/" + ApgContract.PATH_USER_IDS + "/#", PUBLIC_KEY_RING_USER_ID_BY_ROW_ID); /** * secret key rings * *
          * key_rings/secret
-         * key_rings/secret/*
-         * key_rings/secret/key_id/*
-         * key_rings/secret/emails/*
+         * key_rings/secret/#
+         * key_rings/secret/master_key_id/_
+         * key_rings/secret/key_id/_
+         * key_rings/secret/emails/_
          * 
*/ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET, SECRET_KEY_RING); matcher.addURI(authority, - ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET + "/*", - SECRET_KEY_RING_ROW_ID); + ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET + "/#", + SECRET_KEY_RING_BY_ROW_ID); + matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET + "/" + + ApgContract.PATH_BY_MASTER_KEY_ID + "/*", SECRET_KEY_RING_BY_MASTER_KEY_ID); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET + "/" + ApgContract.PATH_BY_KEY_ID + "/*", SECRET_KEY_RING_BY_KEY_ID); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET + "/" @@ -153,29 +163,27 @@ public class ApgProvider extends ContentProvider { * secret keys * *
-         * key_rings/secret/_/keys
-         * key_rings/secret/_/keys/#
+         * key_rings/secret/#/keys
+         * key_rings/secret/#/keys/#
          * 
*/ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET - + "/*/" + ApgContract.PATH_KEYS, SECRET_KEY_RING_KEY); + + "/#/" + ApgContract.PATH_KEYS, SECRET_KEY_RING_KEY); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET - + "/*/" + ApgContract.PATH_KEYS + "/" + ApgContract.PATH_RANK, - SECRET_KEY_RING_KEY_RANK); + + "/#/" + ApgContract.PATH_KEYS + "/#", SECRET_KEY_RING_KEY_BY_ROW_ID); /** * secret user ids * *
-         * key_rings/secret/_/user_ids
-         * key_rings/secret/_/user_ids/#
+         * key_rings/secret/#/user_ids
+         * key_rings/secret/#/user_ids/#
          * 
*/ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET - + "/*/" + ApgContract.PATH_USER_IDS, SECRET_KEY_RING_USER_ID); + + "/#/" + ApgContract.PATH_USER_IDS, SECRET_KEY_RING_USER_ID); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET - + "/*/" + ApgContract.PATH_USER_IDS + "/" + ApgContract.PATH_RANK, - SECRET_KEY_RING_USER_ID_RANK); + + "/#/" + ApgContract.PATH_USER_IDS + "/#", SECRET_KEY_RING_USER_ID_BY_ROW_ID); /** * data stream @@ -208,40 +216,42 @@ public class ApgProvider extends ContentProvider { case PUBLIC_KEY_RING_BY_EMAILS: return PublicKeyRings.CONTENT_TYPE; - case PUBLIC_KEY_RING_ROW_ID: + case PUBLIC_KEY_RING_BY_ROW_ID: + case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case PUBLIC_KEY_RING_BY_KEY_ID: return PublicKeyRings.CONTENT_ITEM_TYPE; case PUBLIC_KEY_RING_KEY: return PublicKeys.CONTENT_TYPE; - case PUBLIC_KEY_RING_KEY_RANK: + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: return PublicKeys.CONTENT_ITEM_TYPE; case PUBLIC_KEY_RING_USER_ID: return PublicUserIds.CONTENT_TYPE; - case PUBLIC_KEY_RING_USER_ID_RANK: + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: return PublicUserIds.CONTENT_ITEM_TYPE; case SECRET_KEY_RING: case SECRET_KEY_RING_BY_EMAILS: return SecretKeyRings.CONTENT_TYPE; - case SECRET_KEY_RING_ROW_ID: + case SECRET_KEY_RING_BY_ROW_ID: + case SECRET_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_KEY_ID: return SecretKeyRings.CONTENT_ITEM_TYPE; case SECRET_KEY_RING_KEY: return SecretKeys.CONTENT_TYPE; - case SECRET_KEY_RING_KEY_RANK: + case SECRET_KEY_RING_KEY_BY_ROW_ID: return SecretKeys.CONTENT_ITEM_TYPE; case SECRET_KEY_RING_USER_ID: return SecretUserIds.CONTENT_TYPE; - case SECRET_KEY_RING_USER_ID_RANK: + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: return SecretUserIds.CONTENT_ITEM_TYPE; default: @@ -259,24 +269,24 @@ public class ApgProvider extends ContentProvider { int type; switch (match) { case PUBLIC_KEY_RING: - case PUBLIC_KEY_RING_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_KEY: - case PUBLIC_KEY_RING_KEY_RANK: + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: case PUBLIC_KEY_RING_USER_ID: - case PUBLIC_KEY_RING_USER_ID_RANK: + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: type = KeyTypes.PUBLIC; break; case SECRET_KEY_RING: - case SECRET_KEY_RING_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_KEY: - case SECRET_KEY_RING_KEY_RANK: + case SECRET_KEY_RING_KEY_BY_ROW_ID: case SECRET_KEY_RING_USER_ID: - case SECRET_KEY_RING_USER_ID_RANK: + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: type = KeyTypes.SECRET; break; @@ -301,76 +311,93 @@ public class ApgProvider extends ContentProvider { int match = sUriMatcher.match(uri); - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = " + getKeyType(match)); - switch (match) { - case PUBLIC_KEY_RING_ROW_ID: - case SECRET_KEY_RING_ROW_ID: - qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ROW_ID - + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + case PUBLIC_KEY_RING_BY_ROW_ID: + case SECRET_KEY_RING_BY_ROW_ID: + qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = " + + getKeyType(match)); + + qb.appendWhere(Tables.KEY_RINGS + "." + BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + // break omitted intentionally + + case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: + case SECRET_KEY_RING_BY_MASTER_KEY_ID: + qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); // break omitted intentionally case PUBLIC_KEY_RING: case SECRET_KEY_RING: + 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.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + Tables.USERS - + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " + Tables.USERS - + "." + UserIdsColumns.KEY_ROW_ID + " AND " + Tables.USERS + "." - + UserIdsColumns.RANK + " = '0') "); + + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " + + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0') "); projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); - projectionMap.put(KeyRingsColumns.MASTER_KEY_ROW_ID, Tables.KEY_RINGS + "." - + KeyRingsColumns.MASTER_KEY_ROW_ID); - projectionMap.put(UserIdsColumns.USER_ID, Tables.USERS + "." + UserIdsColumns.USER_ID); + projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + + KeyRingsColumns.MASTER_KEY_ID); + projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + + UserIdsColumns.USER_ID); if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USERS + "." + UserIdsColumns.USER_ID + " ASC"; + sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; } break; case SECRET_KEY_RING_BY_KEY_ID: case PUBLIC_KEY_RING_BY_KEY_ID: + qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = " + + getKeyType(match)); + qb.setTables(Tables.KEYS + " AS tmp INNER JOIN " + Tables.KEY_RINGS + " ON (" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + "tmp." + KeysColumns.KEY_RING_ROW_ID + ")" + " INNER JOIN " + Tables.KEYS + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." + KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "." - + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + Tables.USERS - + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " + Tables.USERS - + "." + UserIdsColumns.KEY_ROW_ID + " AND " + Tables.USERS + "." - + UserIdsColumns.RANK + " = '0') "); + + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " + + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0') "); projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); - projectionMap.put(KeyRingsColumns.MASTER_KEY_ROW_ID, Tables.KEY_RINGS + "." - + KeyRingsColumns.MASTER_KEY_ROW_ID); - projectionMap.put(UserIdsColumns.USER_ID, Tables.USERS + "." + UserIdsColumns.USER_ID); + projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + + KeyRingsColumns.MASTER_KEY_ID); + projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + + UserIdsColumns.USER_ID); - qb.appendWhere(" AND tmp." + KeysColumns.KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(3)); + qb.appendWhere("tmp." + KeysColumns.KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); break; case SECRET_KEY_RING_BY_EMAILS: case PUBLIC_KEY_RING_BY_EMAILS: + qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = " + + getKeyType(match)); + 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.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + Tables.USERS - + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " + Tables.USERS - + "." + UserIdsColumns.KEY_ROW_ID + " AND " + Tables.USERS + "." - + UserIdsColumns.RANK + " = '0') "); + + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " + + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0') "); projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); - projectionMap.put(KeyRingsColumns.MASTER_KEY_ROW_ID, Tables.KEY_RINGS + "." - + KeyRingsColumns.MASTER_KEY_ROW_ID); - projectionMap.put(UserIdsColumns.USER_ID, Tables.USERS + "." + UserIdsColumns.USER_ID); + projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + + KeyRingsColumns.MASTER_KEY_ID); + projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + + UserIdsColumns.USER_ID); - String emails = uri.getPathSegments().get(3); + String emails = uri.getLastPathSegment(); String chunks[] = emails.split(" *, *"); boolean gotCondition = false; String emailWhere = ""; @@ -388,13 +415,46 @@ public class ApgProvider extends ContentProvider { } if (gotCondition) { - qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " - + Tables.USERS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_ROW_ID + " = " + qb.appendWhere("EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " + Tables.USER_IDS + + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID + " = " + Tables.KEYS + "." + BaseColumns._ID + " AND (" + emailWhere + "))"); } break; + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: + case SECRET_KEY_RING_KEY_BY_ROW_ID: + String keyRowId = uri.getLastPathSegment(); + qb.appendWhere(BaseColumns._ID + " = " + keyRowId); + + // break omitted intentionally + + case PUBLIC_KEY_RING_KEY: + case SECRET_KEY_RING_KEY: + qb.setTables(Tables.KEYS); + qb.appendWhere(KeysColumns.TYPE + " = " + getKeyType(match)); + + String foreignKeyRingRowId = uri.getPathSegments().get(2); + qb.appendWhere(KeysColumns.KEY_RING_ROW_ID + " = " + foreignKeyRingRowId); + + break; + + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: + String userIdRowId = uri.getLastPathSegment(); + qb.appendWhere(BaseColumns._ID + " = " + userIdRowId); + + // break omitted intentionally + + case PUBLIC_KEY_RING_USER_ID: + case SECRET_KEY_RING_USER_ID: + qb.setTables(Tables.USER_IDS); + + String foreignKeyRowId = uri.getPathSegments().get(2); + qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = " + foreignKeyRowId); + + break; + default: throw new IllegalArgumentException("Unknown URI " + uri); @@ -410,9 +470,6 @@ public class ApgProvider extends ContentProvider { orderBy = sortOrder; } - Log.d(Constants.TAG, - qb.buildQuery(projection, selection, selectionArgs, null, null, orderBy, null) - .replace("WHERE", "WHERE\n")); Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); // Tell the cursor what uri to watch, so it knows when its source data changes @@ -448,7 +505,7 @@ public class ApgProvider extends ContentProvider { break; case PUBLIC_KEY_RING_USER_ID: - db.insertOrThrow(Tables.USERS, null, values); + db.insertOrThrow(Tables.USER_IDS, null, values); rowUri = PublicUserIds.buildPublicUserIdsUri(values.getAsString(PublicUserIds._ID)); break; @@ -468,7 +525,7 @@ public class ApgProvider extends ContentProvider { break; case SECRET_KEY_RING_USER_ID: - db.insertOrThrow(Tables.USERS, null, values); + db.insertOrThrow(Tables.USER_IDS, null, values); rowUri = SecretUserIds.buildSecretUserIdsUri(values.getAsString(SecretUserIds._ID)); break; @@ -496,16 +553,28 @@ public class ApgProvider extends ContentProvider { final int match = sUriMatcher.match(uri); switch (match) { - case PUBLIC_KEY_RING_ROW_ID: - // corresponding keys and userids are deleted by ON DELETE CASCADE + case PUBLIC_KEY_RING_BY_ROW_ID: + // corresponding keys and userIds are deleted by ON DELETE CASCADE count = db.delete(Tables.KEY_RINGS, - buildDefaultSelection(uri, KeyTypes.PUBLIC, selection), selectionArgs); + buildDefaultKeyRingsSelection(uri, KeyTypes.PUBLIC, selection), selectionArgs); break; - case SECRET_KEY_RING_ROW_ID: - // corresponding keys and userids are deleted by ON DELETE CASCADE + case SECRET_KEY_RING_BY_ROW_ID: + // corresponding keys and userIds are deleted by ON DELETE CASCADE count = db.delete(Tables.KEY_RINGS, - buildDefaultSelection(uri, KeyTypes.SECRET, selection), selectionArgs); + buildDefaultKeyRingsSelection(uri, KeyTypes.SECRET, selection), selectionArgs); break; + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: + count = db.delete(Tables.KEYS, + buildDefaultKeysSelection(uri, KeyTypes.PUBLIC, selection), selectionArgs); + case SECRET_KEY_RING_KEY_BY_ROW_ID: + count = db.delete(Tables.KEYS, + buildDefaultKeysSelection(uri, KeyTypes.SECRET, selection), selectionArgs); + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: + count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection), + selectionArgs); + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: + count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection), + selectionArgs); default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -527,13 +596,31 @@ public class ApgProvider extends ContentProvider { try { final int match = sUriMatcher.match(uri); switch (match) { - case PUBLIC_KEY_RING_ROW_ID: + case PUBLIC_KEY_RING_BY_ROW_ID: count = db.update(Tables.KEY_RINGS, values, - buildDefaultSelection(uri, KeyTypes.PUBLIC, selection), selectionArgs); + buildDefaultKeyRingsSelection(uri, KeyTypes.PUBLIC, selection), + selectionArgs); break; - case SECRET_KEY_RING_ROW_ID: + case SECRET_KEY_RING_BY_ROW_ID: count = db.update(Tables.KEY_RINGS, values, - buildDefaultSelection(uri, KeyTypes.SECRET, selection), selectionArgs); + buildDefaultKeyRingsSelection(uri, KeyTypes.SECRET, selection), + selectionArgs); + break; + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: + count = db.update(Tables.KEYS, values, + buildDefaultKeysSelection(uri, KeyTypes.PUBLIC, selection), selectionArgs); + break; + case SECRET_KEY_RING_KEY_BY_ROW_ID: + count = db.update(Tables.KEYS, values, + buildDefaultKeysSelection(uri, KeyTypes.SECRET, selection), selectionArgs); + break; + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: + count = db.update(Tables.USER_IDS, values, + buildDefaultUserIdsSelection(uri, selection), selectionArgs); + break; + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: + count = db.update(Tables.USER_IDS, values, + buildDefaultUserIdsSelection(uri, selection), selectionArgs); break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); @@ -549,26 +636,78 @@ public class ApgProvider extends ContentProvider { } /** - * Build default selection statement. If no extra selection is specified only build where clause - * with rowId + * 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 buildDefaultSelection(Uri uri, Integer keyType, String selection) { - String rowId = uri.getPathSegments().get(1); - String andWhere = ""; - if (!TextUtils.isEmpty(selection)) { - andWhere = " AND (" + selection + ")"; - } + private String buildDefaultKeyRingsSelection(Uri uri, Integer keyType, String selection) { + String rowId = uri.getLastPathSegment(); String andType = ""; if (keyType != null) { andType = " AND " + KeyRingsColumns.TYPE + "=" + keyType; } - return BaseColumns._ID + "=" + rowId + andType + andWhere; + String andSelection = ""; + if (!TextUtils.isEmpty(selection)) { + andSelection = " AND (" + selection + ")"; + } + + return BaseColumns._ID + "=" + rowId + andType + andSelection; + } + + /** + * Build default selection statement for Keys. If no extra selection is specified only build + * where clause with rowId + * + * @param uri + * @param selection + * @return + */ + private String buildDefaultKeysSelection(Uri uri, Integer keyType, String selection) { + String rowId = uri.getLastPathSegment(); + + String foreignKeyRingRowId = uri.getPathSegments().get(2); + String andForeignKeyRing = " AND " + KeysColumns.KEY_RING_ROW_ID + " = " + + foreignKeyRingRowId; + + String andType = ""; + if (keyType != null) { + andType = " AND " + KeysColumns.TYPE + "=" + keyType; + } + + String andSelection = ""; + if (!TextUtils.isEmpty(selection)) { + andSelection = " AND (" + selection + ")"; + } + + return BaseColumns._ID + "=" + rowId + andForeignKeyRing + andType + andSelection; + } + + /** + * Build default selection statement for UserIds. If no extra selection is specified only build + * where clause with rowId + * + * @param uri + * @param selection + * @return + */ + private String buildDefaultUserIdsSelection(Uri uri, String selection) { + String rowId = uri.getLastPathSegment(); + + String foreignKeyRingRowId = uri.getPathSegments().get(2); + String andForeignKeyRing = " AND " + KeysColumns.KEY_RING_ROW_ID + " = " + + foreignKeyRingRowId; + + String andSelection = ""; + if (!TextUtils.isEmpty(selection)) { + andSelection = " AND (" + selection + ")"; + } + + return BaseColumns._ID + "=" + rowId + andForeignKeyRing + andSelection; } @Override @@ -577,7 +716,7 @@ public class ApgProvider extends ContentProvider { if (match != DATA_STREAM) { throw new FileNotFoundException(); } - String fileName = uri.getPathSegments().get(1); + String fileName = uri.getLastPathSegment(); File file = new File(getContext().getFilesDir().getAbsolutePath(), fileName); return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); } diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java b/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java index 00fe51a7b..e37049c7e 100644 --- a/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java +++ b/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java @@ -1,42 +1,108 @@ package org.thialfihar.android.apg.provider; import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; import java.util.Vector; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.helper.PGPConversionHelper; import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.helper.PGPMain.ApgGeneralException; import org.thialfihar.android.apg.provider.ApgContract.PublicKeyRings; import org.thialfihar.android.apg.provider.ApgContract.PublicKeys; +import org.thialfihar.android.apg.provider.ApgContract.PublicUserIds; import org.thialfihar.android.apg.provider.ApgContract.SecretKeyRings; import org.thialfihar.android.apg.provider.ApgContract.SecretKeys; +import org.thialfihar.android.apg.provider.ApgContract.SecretUserIds; +import org.thialfihar.android.apg.util.IterableIterator; import org.thialfihar.android.apg.util.Log; +import android.content.ContentProviderOperation; import android.content.ContentResolver; -import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; +import android.content.OperationApplicationException; import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; import android.net.Uri; +import android.os.RemoteException; public class ProviderHelper { + // + // public static HashMap sKeyRingsProjection; + // public static HashMap sKeysProjection; + // public static HashMap sUserIdsProjection; + // + // private SQLiteDatabase mDb = null; + // private int mStatus = 0; + // + // static { + // sKeyRingsProjection = new HashMap(); + // sKeyRingsProjection.put(KeyRings._ID, KeyRings._ID); + // sKeyRingsProjection.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID); + // sKeyRingsProjection.put(KeyRings.TYPE, KeyRings.TYPE); + // sKeyRingsProjection.put(KeyRings.WHO_ID, KeyRings.WHO_ID); + // sKeyRingsProjection.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA); + // + // sKeysProjection = new HashMap(); + // sKeysProjection.put(Keys._ID, Keys._ID); + // sKeysProjection.put(Keys.KEY_ID, Keys.KEY_ID); + // sKeysProjection.put(Keys.TYPE, Keys.TYPE); + // sKeysProjection.put(Keys.IS_MASTER_KEY, Keys.IS_MASTER_KEY); + // sKeysProjection.put(Keys.ALGORITHM, Keys.ALGORITHM); + // sKeysProjection.put(Keys.KEY_SIZE, Keys.KEY_SIZE); + // sKeysProjection.put(Keys.CAN_SIGN, Keys.CAN_SIGN); + // sKeysProjection.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT); + // sKeysProjection.put(Keys.IS_REVOKED, Keys.IS_REVOKED); + // sKeysProjection.put(Keys.CREATION, Keys.CREATION); + // sKeysProjection.put(Keys.EXPIRY, Keys.EXPIRY); + // sKeysProjection.put(Keys.KEY_DATA, Keys.KEY_DATA); + // sKeysProjection.put(Keys.RANK, Keys.RANK); + // + // sUserIdsProjection = new HashMap(); + // sUserIdsProjection.put(UserIds._ID, UserIds._ID); + // sUserIdsProjection.put(UserIds.KEY_ID, UserIds.KEY_ID); + // sUserIdsProjection.put(UserIds.USER_ID, UserIds.USER_ID); + // sUserIdsProjection.put(UserIds.RANK, UserIds.RANK); + // } + /** - * Retrieves the actual PGPPublicKeyRing object from the database blob associated with the rowId + * Retrieves the actual PGPPublicKeyRing object from the database blob associated with the + * maserKeyId * * @param context - * @param rowId + * @param masterKeyId * @return */ + public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context, + long masterKeyId) { + Uri queryUri = PublicKeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long + .toString(masterKeyId)); + Cursor cursor = context.getContentResolver() + .query(queryUri, new String[] { PublicKeyRings._ID, PublicKeyRings.KEY_RING_DATA }, + null, null, null); + + PGPPublicKeyRing keyRing = null; + if (cursor != null && cursor.moveToFirst()) { + int keyRingDataCol = cursor.getColumnIndex(PublicKeyRings.KEY_RING_DATA); + + byte[] data = cursor.getBlob(keyRingDataCol); + if (data != null) { + keyRing = PGPConversionHelper.BytesToPGPPublicKeyRing(data); + } + } + + if (cursor != null) { + cursor.close(); + } + + return keyRing; + } + public static PGPPublicKeyRing getPGPPublicKeyRing(Context context, long rowId) { Uri queryUri = PublicKeyRings.buildPublicKeyRingsUri(Long.toString(rowId)); Cursor cursor = context.getContentResolver() @@ -61,12 +127,38 @@ public class ProviderHelper { } /** - * Retrieves the actual PGPSecretKeyRing object from the database blob associated with the rowId + * Retrieves the actual PGPSecretKeyRing object from the database blob associated with the + * maserKeyId * * @param context - * @param rowId + * @param masterKeyId * @return */ + public static PGPSecretKeyRing getPGPSecretKeyRingByMasterKeyId(Context context, + long masterKeyId) { + Uri queryUri = SecretKeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long + .toString(masterKeyId)); + Cursor cursor = context.getContentResolver() + .query(queryUri, new String[] { SecretKeyRings._ID, SecretKeyRings.KEY_RING_DATA }, + null, null, null); + + PGPSecretKeyRing keyRing = null; + if (cursor != null && cursor.moveToFirst()) { + int keyRingDataCol = cursor.getColumnIndex(SecretKeyRings.KEY_RING_DATA); + + byte[] data = cursor.getBlob(keyRingDataCol); + if (data != null) { + keyRing = PGPConversionHelper.BytesToPGPSecretKeyRing(data); + } + } + + if (cursor != null) { + cursor.close(); + } + + return keyRing; + } + public static PGPSecretKeyRing getPGPSecretKeyRing(Context context, long rowId) { Uri queryUri = SecretKeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); Cursor cursor = context.getContentResolver() @@ -91,7 +183,7 @@ public class ProviderHelper { } public static PGPSecretKey getPGPSecretKey(Context context, long keyId) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, keyId); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, keyId); if (keyRing == null) { return null; } @@ -99,7 +191,7 @@ public class ProviderHelper { } public static PGPPublicKey getPGPPublicKey(Context context, long keyId) { - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(context, keyId); + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, keyId); if (keyRing == null) { return null; } @@ -107,36 +199,221 @@ public class ProviderHelper { return keyRing.getPublicKey(keyId); } - // public static String getMainUserId(long keyRowId, int type) { - // Uri queryUri = SecretKeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); - // Cursor cursor = context.getContentResolver() - // .query(queryUri, new String[] { SecretKeyRings._ID, SecretKeyRings.KEY_RING_DATA }, - // null, null, null); + /** + * Saves PGPPublicKeyRing with its keys and userIds in DB + * + * @param context + * @param keyRing + * @return + * @throws IOException + * @throws GeneralException + */ + public static void saveKeyRing(Context context, PGPPublicKeyRing keyRing) throws IOException { + PGPPublicKey masterKey = keyRing.getPublicKey(); + long masterKeyId = masterKey.getKeyID(); - // SQLiteDatabase db = mDatabase.db(); - // Cursor c = db.query(Keys.TABLE_NAME + " INNER JOIN " + KeyRings.TABLE_NAME + " ON (" - // + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." - // + Keys.KEY_RING_ID + ") " + " INNER JOIN " + Keys.TABLE_NAME + " AS masterKey ON (" - // + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + "masterKey." - // + Keys.KEY_RING_ID + " AND " + "masterKey." + Keys.IS_MASTER_KEY + " = '1') " - // + " INNER JOIN " + UserIds.TABLE_NAME + " ON (" + UserIds.TABLE_NAME + "." - // + UserIds.KEY_ID + " = " + "masterKey." + Keys._ID + " AND " + UserIds.TABLE_NAME - // + "." + UserIds.RANK + " = '0')", new String[] { UserIds.USER_ID }, Keys.TABLE_NAME - // + "." + Keys.KEY_ID + " = ? AND " + KeyRings.TABLE_NAME + "." + KeyRings.TYPE - // + " = ?", new String[] { "" + keyRowId, "" + type, }, null, null, null); - // String userId = ""; - // if (c != null && c.moveToFirst()) { - // do { - // userId = c.getString(0); - // } while (c.moveToNext()); - // } - // - // if (c != null) { - // c.close(); - // } - // - // return userId; - // } + // delete old version of this keyRing, which also deletes all keys and userIds on cascade + Uri deleteUri = PublicKeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long + .toString(masterKeyId)); + context.getContentResolver().delete(deleteUri, null, null); + + ContentValues values = new ContentValues(); + values.put(PublicKeyRings.MASTER_KEY_ID, masterKeyId); + values.put(PublicKeyRings.KEY_RING_DATA, keyRing.getEncoded()); + + // insert new version of this keyRing + Uri uri = PublicKeyRings.buildPublicKeyRingsByMasterKeyIdUri(values + .getAsString(PublicKeyRings.MASTER_KEY_ID)); + Uri insertedUri = context.getContentResolver().insert(uri, values); + long keyRingRowId = Long.getLong(insertedUri.getLastPathSegment()); + + // save all keys and userIds included in keyRing object in database + ArrayList operations = new ArrayList(); + + int rank = 0; + for (PGPPublicKey key : new IterableIterator(keyRing.getPublicKeys())) { + operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank)); + ++rank; + } + + int userIdRank = 0; + for (String userId : new IterableIterator(masterKey.getUserIDs())) { + operations.add(buildPublicUserIdOperations(context, keyRingRowId, userId, userIdRank)); + ++userIdRank; + } + + try { + context.getContentResolver().applyBatch(ApgContract.CONTENT_AUTHORITY, operations); + } catch (RemoteException e) { + Log.e(Constants.TAG, "applyBatch failed!", e); + } catch (OperationApplicationException e) { + Log.e(Constants.TAG, "applyBatch failed!", e); + } + } + + /** + * Saves PGPSecretKeyRing with its keys and userIds in DB + * + * @param context + * @param keyRing + * @return + * @throws IOException + * @throws GeneralException + */ + public static void saveKeyRing(Context context, PGPSecretKeyRing keyRing) throws IOException { + PGPSecretKey masterKey = keyRing.getSecretKey(); + long masterKeyId = masterKey.getKeyID(); + + // delete old version of this keyRing, which also deletes all keys and userIds on cascade + Uri deleteUri = SecretKeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long + .toString(masterKeyId)); + context.getContentResolver().delete(deleteUri, null, null); + + ContentValues values = new ContentValues(); + values.put(SecretKeyRings.MASTER_KEY_ID, masterKeyId); + values.put(SecretKeyRings.KEY_RING_DATA, keyRing.getEncoded()); + + // insert new version of this keyRing + Uri uri = SecretKeyRings.buildSecretKeyRingsByMasterKeyIdUri(values + .getAsString(SecretKeyRings.MASTER_KEY_ID)); + Uri insertedUri = context.getContentResolver().insert(uri, values); + long keyRingRowId = Long.getLong(insertedUri.getLastPathSegment()); + + // save all keys and userIds included in keyRing object in database + ArrayList operations = new ArrayList(); + + int rank = 0; + for (PGPSecretKey key : new IterableIterator(keyRing.getSecretKeys())) { + operations.add(buildSecretKeyOperations(context, keyRingRowId, key, rank)); + ++rank; + } + + int userIdRank = 0; + for (String userId : new IterableIterator(masterKey.getUserIDs())) { + operations.add(buildSecretUserIdOperations(context, keyRingRowId, userId, userIdRank)); + ++userIdRank; + } + + try { + context.getContentResolver().applyBatch(ApgContract.CONTENT_AUTHORITY, operations); + } catch (RemoteException e) { + Log.e(Constants.TAG, "applyBatch failed!", e); + } catch (OperationApplicationException e) { + Log.e(Constants.TAG, "applyBatch failed!", e); + } + } + + /** + * 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 { + ContentValues values = new ContentValues(); + values.put(PublicKeys.KEY_ID, key.getKeyID()); + values.put(PublicKeys.IS_MASTER_KEY, key.isMasterKey()); + values.put(PublicKeys.ALGORITHM, key.getAlgorithm()); + values.put(PublicKeys.KEY_SIZE, key.getBitStrength()); + values.put(PublicKeys.CAN_SIGN, PGPHelper.isSigningKey(key)); + values.put(PublicKeys.CAN_ENCRYPT, PGPHelper.isEncryptionKey(key)); + values.put(PublicKeys.IS_REVOKED, key.isRevoked()); + values.put(PublicKeys.CREATION, PGPHelper.getCreationDate(key).getTime() / 1000); + Date expiryDate = PGPHelper.getExpiryDate(key); + if (expiryDate != null) { + values.put(PublicKeys.EXPIRY, expiryDate.getTime() / 1000); + } + values.put(PublicKeys.KEY_RING_ROW_ID, keyRingRowId); + values.put(PublicKeys.KEY_DATA, key.getEncoded()); + values.put(PublicKeys.RANK, rank); + + Uri uri = PublicKeys.buildPublicKeysUri(Long.toString(keyRingRowId)); + + return ContentProviderOperation.newInsert(uri).withValues(values).build(); + } + + /** + * 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) { + ContentValues values = new ContentValues(); + values.put(PublicUserIds.KEY_RING_ROW_ID, keyRingRowId); + values.put(PublicUserIds.USER_ID, userId); + values.put(PublicUserIds.RANK, rank); + + Uri uri = PublicUserIds.buildPublicUserIdsUri(Long.toString(keyRingRowId)); + + return ContentProviderOperation.newInsert(uri).withValues(values).build(); + } + + /** + * 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 { + ContentValues values = new ContentValues(); + values.put(SecretKeys.KEY_ID, key.getKeyID()); + values.put(SecretKeys.IS_MASTER_KEY, key.isMasterKey()); + values.put(SecretKeys.ALGORITHM, key.getPublicKey().getAlgorithm()); + values.put(SecretKeys.KEY_SIZE, key.getPublicKey().getBitStrength()); + values.put(SecretKeys.CAN_SIGN, PGPHelper.isSigningKey(key)); + values.put(SecretKeys.CAN_ENCRYPT, PGPHelper.isEncryptionKey(key)); + values.put(SecretKeys.IS_REVOKED, key.getPublicKey().isRevoked()); + values.put(SecretKeys.CREATION, PGPHelper.getCreationDate(key).getTime() / 1000); + Date expiryDate = PGPHelper.getExpiryDate(key); + if (expiryDate != null) { + values.put(SecretKeys.EXPIRY, expiryDate.getTime() / 1000); + } + values.put(SecretKeys.KEY_RING_ROW_ID, keyRingRowId); + values.put(SecretKeys.KEY_DATA, key.getEncoded()); + values.put(SecretKeys.RANK, rank); + + Uri uri = SecretKeys.buildSecretKeysUri(Long.toString(keyRingRowId)); + + return ContentProviderOperation.newInsert(uri).withValues(values).build(); + } + + /** + * 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) { + ContentValues values = new ContentValues(); + values.put(SecretUserIds.KEY_RING_ROW_ID, keyRingRowId); + values.put(SecretUserIds.USER_ID, userId); + values.put(SecretUserIds.RANK, rank); + + Uri uri = SecretUserIds.buildSecretUserIdsUri(Long.toString(keyRingRowId)); + + return ContentProviderOperation.newInsert(uri).withValues(values).build(); + } /** * Retrieves ids of all SecretKeyRings diff --git a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java index 95434ab30..4a38e8af7 100644 --- a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java +++ b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java @@ -743,7 +743,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater { /* Operation */ HkpKeyServer server = new HkpKeyServer(keyServer); - PGPPublicKeyRing keyring = ProviderHelper.getPGPPublicKeyRing(this, keyRingId); + PGPPublicKeyRing keyring = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, keyRingId); if (keyring != null) { boolean uploaded = PGPMain.uploadKeyRingToServer(server, (PGPPublicKeyRing) keyring); @@ -807,7 +807,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater { signaturePassPhrase); // store the signed key in our local cache - int retval = PGPMain.storeKeyRingInCache(signedPubKeyRing); + int retval = PGPMain.storeKeyRingInCache(this, signedPubKeyRing); if (retval != Id.return_value.ok && retval != Id.return_value.updated) { throw new ApgGeneralException("Failed to store signed key in local cache"); } diff --git a/org_apg/src/org/thialfihar/android/apg/service/PassphraseCacheService.java b/org_apg/src/org/thialfihar/android/apg/service/PassphraseCacheService.java index 1909facd3..403c4a20d 100644 --- a/org_apg/src/org/thialfihar/android/apg/service/PassphraseCacheService.java +++ b/org_apg/src/org/thialfihar/android/apg/service/PassphraseCacheService.java @@ -88,7 +88,7 @@ public class PassphraseCacheService extends Service { // try to get real key id long realId = keyId; if (realId != Id.key.symmetric) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, keyId); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, keyId); if (keyRing == null) { return null; } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java index a72842369..880349760 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java @@ -334,7 +334,7 @@ public class DecryptActivity extends SherlockFragmentActivity { if (mSignatureKeyId == 0) { return; } - PGPPublicKeyRing key = ProviderHelper.getPGPPublicKeyRing(DecryptActivity.this, + PGPPublicKeyRing key = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(DecryptActivity.this, mSignatureKeyId); if (key != null) { Intent intent = new Intent(DecryptActivity.this, KeyServerQueryActivity.class); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java index ca0c1f281..eb9b543ae 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java @@ -309,7 +309,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { if (keyId != 0) { PGPSecretKey masterKey = null; - mKeyRing = ProviderHelper.getPGPSecretKeyRing(this, keyId); + mKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, keyId); if (mKeyRing != null) { masterKey = PGPHelper.getMasterKey(mKeyRing); for (PGPSecretKey key : new IterableIterator( diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java index 7a4686d53..02aada874 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java @@ -441,7 +441,7 @@ public class EncryptActivity extends SherlockFragmentActivity { long signatureKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); long encryptionKeyIds[] = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); if (signatureKeyId != 0) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(this, signatureKeyId); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, signatureKeyId); PGPSecretKey masterKey = null; if (keyRing != null) { masterKey = PGPHelper.getMasterKey(keyRing); @@ -457,7 +457,7 @@ public class EncryptActivity extends SherlockFragmentActivity { if (encryptionKeyIds != null) { Vector goodIds = new Vector(); for (int i = 0; i < encryptionKeyIds.length; ++i) { - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(this, + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, encryptionKeyIds[i]); PGPPublicKey masterKey = null; if (keyRing == null) { @@ -958,7 +958,7 @@ public class EncryptActivity extends SherlockFragmentActivity { } else { String uid = getResources().getString(R.string.unknownUserId); String uidExtra = ""; - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(this, getSecretKeyId()); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, getSecretKeyId()); if (keyRing != null) { PGPSecretKey key = PGPHelper.getMasterKey(keyRing); if (key != null) { diff --git a/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java index 03f76a6c0..c6cc6e028 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java @@ -116,7 +116,7 @@ public class PublicKeyListActivity extends KeyListActivity { mSelectedItem = groupPosition; final int keyRingId = mListAdapter.getKeyRingId(groupPosition); long keyId = 0; - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(this, keyRingId); + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, keyRingId); if (keyRing != null) { keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID(); } @@ -149,7 +149,7 @@ public class PublicKeyListActivity extends KeyListActivity { mSelectedItem = groupPosition; final int keyRingId = mListAdapter.getKeyRingId(groupPosition); long keyId = 0; - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(this, keyRingId); + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, keyRingId); if (keyRing != null) { keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID(); } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java index e711109fc..4fbb621a8 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java @@ -155,7 +155,7 @@ public class SignKeyActivity extends SherlockFragmentActivity { * handles the UI bits of the signing process on the UI thread */ private void initiateSigning() { - PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRing(this, mPubKeyId); + PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, mPubKeyId); if (pubring != null) { // if we have already signed this key, dont bother doing it again boolean alreadySigned = false; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/dialog/DeleteKeyDialogFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/dialog/DeleteKeyDialogFragment.java index 3a5ed9948..105c45bd2 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/dialog/DeleteKeyDialogFragment.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/dialog/DeleteKeyDialogFragment.java @@ -22,7 +22,6 @@ import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.helper.PGPMain; import org.thialfihar.android.apg.provider.ProviderHelper; import org.thialfihar.android.apg.util.Log; @@ -41,7 +40,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { private Messenger mMessenger; private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_DELETE_KEY_RING_ID = "delete_file"; + private static final String ARG_DELETE_KEY_RING_ROW_ID = "delete_file"; private static final String ARG_KEY_TYPE = "key_type"; public static final int MESSAGE_OKAY = 1; @@ -49,13 +48,13 @@ public class DeleteKeyDialogFragment extends DialogFragment { /** * Creates new instance of this delete file dialog fragment */ - public static DeleteKeyDialogFragment newInstance(Messenger messenger, int deleteKeyRingId, + public static DeleteKeyDialogFragment newInstance(Messenger messenger, int deleteKeyRingRowId, int keyType) { DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_MESSENGER, messenger); - args.putInt(ARG_DELETE_KEY_RING_ID, deleteKeyRingId); + args.putInt(ARG_DELETE_KEY_RING_ROW_ID, deleteKeyRingRowId); args.putInt(ARG_KEY_TYPE, keyType); frag.setArguments(args); @@ -70,20 +69,20 @@ public class DeleteKeyDialogFragment extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { final FragmentActivity activity = getActivity(); - final int deleteKeyRingId = getArguments().getInt(ARG_DELETE_KEY_RING_ID); + final int deleteKeyRingRowId = getArguments().getInt(ARG_DELETE_KEY_RING_ROW_ID); final int keyType = getArguments().getInt(ARG_KEY_TYPE); // TODO: better way to do this? String userId = activity.getString(R.string.unknownUserId); - Object keyRing = PGPMain.getKeyRing(deleteKeyRingId); - if (keyRing != null) { - if (keyRing instanceof PGPPublicKeyRing) { - userId = PGPHelper.getMainUserIdSafe(activity, - PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing)); - } else { - userId = PGPHelper.getMainUserIdSafe(activity, - PGPHelper.getMasterKey((PGPSecretKeyRing) keyRing)); - } + + if (keyType == Id.type.public_key) { + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(activity, + deleteKeyRingRowId); + userId = PGPHelper.getMainUserIdSafe(activity, PGPHelper.getMasterKey(keyRing)); + } else { + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(activity, + deleteKeyRingRowId); + userId = PGPHelper.getMainUserIdSafe(activity, PGPHelper.getMasterKey(keyRing)); } AlertDialog.Builder builder = new AlertDialog.Builder(activity); @@ -95,9 +94,9 @@ public class DeleteKeyDialogFragment extends DialogFragment { builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { if (keyType == Id.type.public_key) { - ProviderHelper.deletePublicKeyRing(activity, deleteKeyRingId); + ProviderHelper.deletePublicKeyRing(activity, deleteKeyRingRowId); } else { - ProviderHelper.deleteSecretKeyRing(activity, deleteKeyRingId); + ProviderHelper.deleteSecretKeyRing(activity, deleteKeyRingRowId); } dismiss(); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java index 230423715..de2462b39 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java @@ -40,6 +40,7 @@ import android.os.Messenger; import android.os.RemoteException; import android.support.v4.app.DialogFragment; +import org.thialfihar.android.apg.provider.ProviderHelper; import org.thialfihar.android.apg.service.PassphraseCacheService; import org.thialfihar.android.apg.util.Log; @@ -103,7 +104,11 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor private static boolean hasPassphrase(Context context, long secretKeyId) { // check if the key has no passphrase try { - PGPSecretKey secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId)); + // TODO: by master key id??? + PGPSecretKey secretKey = PGPHelper.getMasterKey(ProviderHelper + .getPGPSecretKeyRingByMasterKeyId(context, secretKeyId)); + // PGPSecretKey secretKey = + // PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId)); Log.d(Constants.TAG, "Check if key has no passphrase..."); PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( @@ -149,7 +154,11 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor secretKey = null; alert.setMessage(R.string.passPhraseForSymmetricEncryption); } else { - secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId)); + // TODO: by master key id??? + secretKey = PGPHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByMasterKeyId( + activity, secretKeyId)); + // secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId)); + if (secretKey == null) { alert.setTitle(R.string.title_keyNotFound); alert.setMessage(getString(R.string.keyNotFound, secretKeyId));