aboutsummaryrefslogtreecommitdiffstats
path: root/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java')
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java361
1 files changed, 319 insertions, 42 deletions
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<String, String> sKeyRingsProjection;
+ // public static HashMap<String, String> sKeysProjection;
+ // public static HashMap<String, String> sUserIdsProjection;
+ //
+ // private SQLiteDatabase mDb = null;
+ // private int mStatus = 0;
+ //
+ // static {
+ // sKeyRingsProjection = new HashMap<String, String>();
+ // 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<String, String>();
+ // 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<String, String>();
+ // 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);
-
- // 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;
- // }
+ /**
+ * 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();
+
+ // 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<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
+
+ int rank = 0;
+ for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
+ operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank));
+ ++rank;
+ }
+
+ int userIdRank = 0;
+ for (String userId : new IterableIterator<String>(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<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
+
+ int rank = 0;
+ for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
+ operations.add(buildSecretKeyOperations(context, keyRingRowId, key, rank));
+ ++rank;
+ }
+
+ int userIdRank = 0;
+ for (String userId : new IterableIterator<String>(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