aboutsummaryrefslogtreecommitdiffstats
path: root/org_apg
diff options
context:
space:
mode:
authorDominik <dominik@dominikschuermann.de>2012-09-18 18:35:14 +0200
committerDominik <dominik@dominikschuermann.de>2012-09-18 18:35:14 +0200
commitfb49f9e9c8d1b6d27a489c047431925974738a24 (patch)
treeb62d226914cd6d5598e4c4181ae583c01915811b /org_apg
parenta507204b9e5f04795cf719f85f5844ae3431f4c9 (diff)
downloadopen-keychain-fb49f9e9c8d1b6d27a489c047431925974738a24.tar.gz
open-keychain-fb49f9e9c8d1b6d27a489c047431925974738a24.tar.bz2
open-keychain-fb49f9e9c8d1b6d27a489c047431925974738a24.zip
started restructuring APGs Provider and Database
Diffstat (limited to 'org_apg')
-rw-r--r--org_apg/AndroidManifest.xml4
-rw-r--r--org_apg/src/org/thialfihar/android/apg/Id.java8
-rw-r--r--org_apg/src/org/thialfihar/android/apg/deprecated/DataProvider.java381
-rw-r--r--org_apg/src/org/thialfihar/android/apg/deprecated/Database.java617
-rw-r--r--org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java148
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java235
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java143
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java589
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/DataProvider.java381
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/Database.java617
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/KeyRings.java33
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/Keys.java51
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java79
-rw-r--r--org_apg/src/org/thialfihar/android/apg/provider/UserIds.java31
-rw-r--r--org_apg/src/org/thialfihar/android/apg/service/ApgService.java32
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java7
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java24
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java2
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java2
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java2
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java8
-rw-r--r--org_apg/src/org/thialfihar/android/apg/util/Compatibility.java3
22 files changed, 2164 insertions, 1233 deletions
diff --git a/org_apg/AndroidManifest.xml b/org_apg/AndroidManifest.xml
index dfa366de3..deb62a622 100644
--- a/org_apg/AndroidManifest.xml
+++ b/org_apg/AndroidManifest.xml
@@ -46,7 +46,7 @@
-->
<uses-sdk
- android:minSdkVersion="7"
+ android:minSdkVersion="8"
android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.INTERNET" />
@@ -339,7 +339,7 @@
<service android:name=".service.ApgService" />
<provider
- android:name=".provider.DataProvider"
+ android:name=".deprecated.DataProvider"
android:authorities="org.thialfihar.android.apg.provider"
android:readPermission="org.thialfihar.android.apg.permission.READ_KEY_DETAILS" />
diff --git a/org_apg/src/org/thialfihar/android/apg/Id.java b/org_apg/src/org/thialfihar/android/apg/Id.java
index 4c83437a1..e683f43b4 100644
--- a/org_apg/src/org/thialfihar/android/apg/Id.java
+++ b/org_apg/src/org/thialfihar/android/apg/Id.java
@@ -147,10 +147,10 @@ public final class Id {
public static final int export_keys = 0x21070002;
}
- public static final class database {
- public static final int type_public = 0;
- public static final int type_secret = 1;
- }
+// public static final class database {
+// public static final int type_public = 0;
+// public static final int type_secret = 1;
+// }
public static final class type {
public static final int public_key = 0x21070001;
diff --git a/org_apg/src/org/thialfihar/android/apg/deprecated/DataProvider.java b/org_apg/src/org/thialfihar/android/apg/deprecated/DataProvider.java
new file mode 100644
index 000000000..e377fc8c4
--- /dev/null
+++ b/org_apg/src/org/thialfihar/android/apg/deprecated/DataProvider.java
@@ -0,0 +1,381 @@
+///*
+// * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+// *
+// * 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.
+// */
+//
+//package org.thialfihar.android.apg.deprecated;
+//
+//import java.io.File;
+//import java.io.FileNotFoundException;
+//import java.util.HashMap;
+//
+//import org.thialfihar.android.apg.Id;
+//
+//import android.content.ContentProvider;
+//import android.content.ContentValues;
+//import android.content.UriMatcher;
+//import android.database.Cursor;
+//import android.database.DatabaseUtils;
+//import android.database.sqlite.SQLiteQueryBuilder;
+//import android.net.Uri;
+//import android.os.ParcelFileDescriptor;
+//import android.text.TextUtils;
+//
+//public class DataProvider extends ContentProvider {
+// public static final String AUTHORITY = "org.thialfihar.android.apg.provider";
+//
+// private static final int PUBLIC_KEY_RING = 101;
+// private static final int PUBLIC_KEY_RING_ID = 102;
+// private static final int PUBLIC_KEY_RING_BY_KEY_ID = 103;
+// private static final int PUBLIC_KEY_RING_BY_EMAILS = 104;
+// 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_USER_ID = 121;
+// private static final int PUBLIC_KEY_RING_USER_ID_RANK = 122;
+//
+// private static final int SECRET_KEY_RING = 201;
+// private static final int SECRET_KEY_RING_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_KEY = 211;
+// private static final int SECRET_KEY_RING_KEY_RANK = 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 DATA_STREAM = 301;
+//
+// private static final String PUBLIC_KEY_RING_CONTENT_DIR_TYPE =
+// "vnd.android.cursor.dir/vnd.thialfihar.apg.public.key_ring";
+// private static final String PUBLIC_KEY_RING_CONTENT_ITEM_TYPE =
+// "vnd.android.cursor.item/vnd.thialfihar.apg.public.key_ring";
+//
+// private static final String PUBLIC_KEY_CONTENT_DIR_TYPE =
+// "vnd.android.cursor.dir/vnd.thialfihar.apg.public.key";
+// private static final String PUBLIC_KEY_CONTENT_ITEM_TYPE =
+// "vnd.android.cursor.item/vnd.thialfihar.apg.public.key";
+//
+// private static final String SECRET_KEY_RING_CONTENT_DIR_TYPE =
+// "vnd.android.cursor.dir/vnd.thialfihar.apg.secret.key_ring";
+// private static final String SECRET_KEY_RING_CONTENT_ITEM_TYPE =
+// "vnd.android.cursor.item/vnd.thialfihar.apg.secret.key_ring";
+//
+// private static final String SECRET_KEY_CONTENT_DIR_TYPE =
+// "vnd.android.cursor.dir/vnd.thialfihar.apg.secret.key";
+// private static final String SECRET_KEY_CONTENT_ITEM_TYPE =
+// "vnd.android.cursor.item/vnd.thialfihar.apg.secret.key";
+//
+// private static final String USER_ID_CONTENT_DIR_TYPE =
+// "vnd.android.cursor.dir/vnd.thialfihar.apg.user_id";
+// private static final String USER_ID_CONTENT_ITEM_TYPE =
+// "vnd.android.cursor.item/vnd.thialfihar.apg.user_id";
+//
+// public static final String _ID = "_id";
+// public static final String MASTER_KEY_ID = "master_key_id";
+// public static final String KEY_ID = "key_id";
+// public static final String USER_ID = "user_id";
+//
+// private static final UriMatcher mUriMatcher;
+//
+// private Database mDb;
+//
+// static {
+// mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/public/key_id/*", PUBLIC_KEY_RING_BY_KEY_ID);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/public/emails/*", PUBLIC_KEY_RING_BY_EMAILS);
+//
+// mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/keys", PUBLIC_KEY_RING_KEY);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/keys/#", PUBLIC_KEY_RING_KEY_RANK);
+//
+// mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/user_ids", PUBLIC_KEY_RING_USER_ID);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/user_ids/#", PUBLIC_KEY_RING_USER_ID_RANK);
+//
+// mUriMatcher.addURI(AUTHORITY, "key_rings/public", PUBLIC_KEY_RING);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/public/*", PUBLIC_KEY_RING_ID);
+//
+// mUriMatcher.addURI(AUTHORITY, "key_rings/secret/key_id/*", SECRET_KEY_RING_BY_KEY_ID);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/secret/emails/*", SECRET_KEY_RING_BY_EMAILS);
+//
+// mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/keys", SECRET_KEY_RING_KEY);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/keys/#", SECRET_KEY_RING_KEY_RANK);
+//
+// mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/user_ids", SECRET_KEY_RING_USER_ID);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/user_ids/#", SECRET_KEY_RING_USER_ID_RANK);
+//
+// mUriMatcher.addURI(AUTHORITY, "key_rings/secret", SECRET_KEY_RING);
+// mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*", SECRET_KEY_RING_ID);
+//
+// mUriMatcher.addURI(AUTHORITY, "data/*", DATA_STREAM);
+// }
+//
+// @Override
+// public boolean onCreate() {
+// mDb = new Database(getContext());
+// return true;
+// }
+//
+// @Override
+// public Cursor query(Uri uri, String[] projection, String selection,
+// String[] selectionArgs, String sortOrder) {
+// // TODO: implement the others, then use them for the lists
+// SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+// HashMap<String, String> projectionMap = new HashMap<String, String>();
+//
+// int match = mUriMatcher.match(uri);
+// int type;
+// switch (match) {
+// case PUBLIC_KEY_RING:
+// case PUBLIC_KEY_RING_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_USER_ID:
+// case PUBLIC_KEY_RING_USER_ID_RANK:
+// type = Id.database.type_public;
+// break;
+//
+// case SECRET_KEY_RING:
+// case SECRET_KEY_RING_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_USER_ID:
+// case SECRET_KEY_RING_USER_ID_RANK:
+// type = Id.database.type_secret;
+// break;
+//
+// default: {
+// throw new IllegalArgumentException("Unknown URI " + uri);
+// }
+// }
+//
+// qb.appendWhere(KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = " + type);
+//
+// switch (match) {
+// case PUBLIC_KEY_RING_ID:
+// case SECRET_KEY_RING_ID: {
+// qb.appendWhere(" AND " +
+// KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID + " = ");
+// qb.appendWhereEscapeString(uri.getPathSegments().get(2));
+//
+// // break omitted intentionally
+// }
+//
+// case PUBLIC_KEY_RING:
+// case SECRET_KEY_RING: {
+// qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " +
+// "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " +
+// Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " +
+// Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" +
+// ") " +
+// " INNER JOIN " + UserIds.TABLE_NAME + " ON " +
+// "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " +
+// UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " +
+// UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ");
+//
+// projectionMap.put(_ID,
+// KeyRings.TABLE_NAME + "." + KeyRings._ID);
+// projectionMap.put(MASTER_KEY_ID,
+// KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID);
+// projectionMap.put(USER_ID,
+// UserIds.TABLE_NAME + "." + UserIds.USER_ID);
+//
+// if (TextUtils.isEmpty(sortOrder)) {
+// sortOrder = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC";
+// }
+//
+// break;
+// }
+//
+// case SECRET_KEY_RING_BY_KEY_ID:
+// case PUBLIC_KEY_RING_BY_KEY_ID: {
+// qb.setTables(Keys.TABLE_NAME + " AS tmp INNER JOIN " +
+// KeyRings.TABLE_NAME + " ON (" +
+// KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " +
+// "tmp." + Keys.KEY_RING_ID + ")" +
+// " INNER JOIN " + Keys.TABLE_NAME + " ON " +
+// "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " +
+// Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " +
+// Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" +
+// ") " +
+// " INNER JOIN " + UserIds.TABLE_NAME + " ON " +
+// "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " +
+// UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " +
+// UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ");
+//
+// projectionMap.put(_ID,
+// KeyRings.TABLE_NAME + "." + KeyRings._ID);
+// projectionMap.put(MASTER_KEY_ID,
+// KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID);
+// projectionMap.put(USER_ID,
+// UserIds.TABLE_NAME + "." + UserIds.USER_ID);
+//
+// qb.appendWhere(" AND tmp." + Keys.KEY_ID + " = ");
+// qb.appendWhereEscapeString(uri.getPathSegments().get(3));
+//
+// break;
+// }
+//
+// case SECRET_KEY_RING_BY_EMAILS:
+// case PUBLIC_KEY_RING_BY_EMAILS: {
+// qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " +
+// "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " +
+// Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " +
+// Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" +
+// ") " +
+// " INNER JOIN " + UserIds.TABLE_NAME + " ON " +
+// "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " +
+// UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " +
+// UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ");
+//
+// projectionMap.put(_ID,
+// KeyRings.TABLE_NAME + "." + KeyRings._ID);
+// projectionMap.put(MASTER_KEY_ID,
+// KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID);
+// projectionMap.put(USER_ID,
+// UserIds.TABLE_NAME + "." + UserIds.USER_ID);
+//
+// String emails = uri.getPathSegments().get(3);
+// String chunks[] = emails.split(" *, *");
+// boolean gotCondition = false;
+// String emailWhere = "";
+// for (int i = 0; i < chunks.length; ++i) {
+// if (chunks[i].length() == 0) {
+// continue;
+// }
+// if (i != 0) {
+// emailWhere += " OR ";
+// }
+// emailWhere += "tmp." + UserIds.USER_ID + " LIKE ";
+// // match '*<email>', so it has to be at the *end* of the user id
+// emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
+// gotCondition = true;
+// }
+//
+// if (gotCondition) {
+// qb.appendWhere(" AND EXISTS (SELECT tmp." + UserIds._ID +
+// " FROM " + UserIds.TABLE_NAME +
+// " AS tmp WHERE tmp." + UserIds.KEY_ID + " = " +
+// Keys.TABLE_NAME + "." + Keys._ID +
+// " AND (" + emailWhere + "))");
+// }
+//
+// break;
+// }
+//
+// default: {
+// throw new IllegalArgumentException("Unknown URI " + uri);
+// }
+// }
+//
+// qb.setProjectionMap(projectionMap);
+//
+// // If no sort order is specified use the default
+// String orderBy;
+// if (TextUtils.isEmpty(sortOrder)) {
+// orderBy = null;
+// } else {
+// orderBy = sortOrder;
+// }
+//
+// //System.out.println(qb.buildQuery(projection, selection, selectionArgs, null, null, sortOrder, null).replace("WHERE", "WHERE\n"));
+// Cursor c = qb.query(mDb.db(), projection, selection, selectionArgs, null, null, orderBy);
+//
+// // Tell the cursor what uri to watch, so it knows when its source data changes
+// c.setNotificationUri(getContext().getContentResolver(), uri);
+// return c;
+// }
+//
+// @Override
+// public String getType(Uri uri) {
+// switch (mUriMatcher.match(uri)) {
+// case PUBLIC_KEY_RING:
+// case PUBLIC_KEY_RING_BY_EMAILS:
+// return PUBLIC_KEY_RING_CONTENT_DIR_TYPE;
+//
+// case PUBLIC_KEY_RING_ID:
+// return PUBLIC_KEY_RING_CONTENT_ITEM_TYPE;
+//
+// case PUBLIC_KEY_RING_BY_KEY_ID:
+// return PUBLIC_KEY_RING_CONTENT_ITEM_TYPE;
+//
+// case PUBLIC_KEY_RING_KEY:
+// return PUBLIC_KEY_CONTENT_DIR_TYPE;
+//
+// case PUBLIC_KEY_RING_KEY_RANK:
+// return PUBLIC_KEY_CONTENT_ITEM_TYPE;
+//
+// case PUBLIC_KEY_RING_USER_ID:
+// return USER_ID_CONTENT_DIR_TYPE;
+//
+// case PUBLIC_KEY_RING_USER_ID_RANK:
+// return USER_ID_CONTENT_ITEM_TYPE;
+//
+// case SECRET_KEY_RING:
+// case SECRET_KEY_RING_BY_EMAILS:
+// return SECRET_KEY_RING_CONTENT_DIR_TYPE;
+//
+// case SECRET_KEY_RING_ID:
+// return SECRET_KEY_RING_CONTENT_ITEM_TYPE;
+//
+// case SECRET_KEY_RING_BY_KEY_ID:
+// return SECRET_KEY_RING_CONTENT_ITEM_TYPE;
+//
+// case SECRET_KEY_RING_KEY:
+// return SECRET_KEY_CONTENT_DIR_TYPE;
+//
+// case SECRET_KEY_RING_KEY_RANK:
+// return SECRET_KEY_CONTENT_ITEM_TYPE;
+//
+// case SECRET_KEY_RING_USER_ID:
+// return USER_ID_CONTENT_DIR_TYPE;
+//
+// case SECRET_KEY_RING_USER_ID_RANK:
+// return USER_ID_CONTENT_ITEM_TYPE;
+//
+// default:
+// throw new IllegalArgumentException("Unknown URI " + uri);
+// }
+// }
+//
+// @Override
+// public Uri insert(Uri uri, ContentValues initialValues) {
+// // not supported
+// return null;
+// }
+//
+// @Override
+// public int delete(Uri uri, String where, String[] whereArgs) {
+// // not supported
+// return 0;
+// }
+//
+// @Override
+// public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
+// // not supported
+// return 0;
+// }
+//
+// @Override
+// public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+// int match = mUriMatcher.match(uri);
+// if (match != DATA_STREAM) {
+// throw new FileNotFoundException();
+// }
+// String fileName = uri.getPathSegments().get(1);
+// 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/deprecated/Database.java b/org_apg/src/org/thialfihar/android/apg/deprecated/Database.java
new file mode 100644
index 000000000..92bbaed4f
--- /dev/null
+++ b/org_apg/src/org/thialfihar/android/apg/deprecated/Database.java
@@ -0,0 +1,617 @@
+///*
+// * 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.
+// */
+//
+//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<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);
+// }
+//
+// 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<Integer> seenIds = new Vector<Integer>();
+// int rank = 0;
+// for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(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<Integer> seenIds = new Vector<Integer>();
+// int rank = 0;
+// for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(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<Integer> seenIds = new Vector<Integer>();
+// int userIdRank = 0;
+// for (String userId : new IterableIterator<String>(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<Integer> seenIds = new Vector<Integer>();
+// int userIdRank = 0;
+// for (String userId : new IterableIterator<String>(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 });
+//
+// 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/PGPMain.java b/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java
index 3890de496..8a7ffc538 100644
--- a/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java
+++ b/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java
@@ -72,11 +72,6 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
-import org.thialfihar.android.apg.provider.DataProvider;
-import org.thialfihar.android.apg.provider.Database;
-import org.thialfihar.android.apg.provider.KeyRings;
-import org.thialfihar.android.apg.provider.Keys;
-import org.thialfihar.android.apg.provider.UserIds;
import org.thialfihar.android.apg.service.ApgService;
import org.thialfihar.android.apg.util.HkpKeyServer;
import org.thialfihar.android.apg.util.InputData;
@@ -142,21 +137,21 @@ 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/");
+ // 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 String VERSION = null;
@@ -184,12 +179,12 @@ public class PGPMain {
private static String mEditPassPhrase = null;
- private static Database mDatabase = null;
+ // private static Database mDatabase = null;
- public static class GeneralException extends Exception {
+ public static class ApgGeneralException extends Exception {
static final long serialVersionUID = 0xf812773342L;
- public GeneralException(String message) {
+ public ApgGeneralException(String message) {
super(message);
}
}
@@ -202,15 +197,15 @@ 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 initialize(Context context) {
+ // if (mDatabase == null) {
+ // mDatabase = new Database(context);
+ // }
+ // }
+ //
+ // public static Database getDatabase() {
+ // return mDatabase;
+ // }
public static void setEditPassPhrase(String passPhrase) {
mEditPassPhrase = passPhrase;
@@ -248,16 +243,16 @@ public class PGPMain {
* @throws NoSuchAlgorithmException
* @throws PGPException
* @throws NoSuchProviderException
- * @throws GeneralException
+ * @throws ApgGeneralException
* @throws InvalidAlgorithmParameterException
*/
public static PGPSecretKeyRing createKey(Context context, int algorithmChoice, int keySize,
String passPhrase, PGPSecretKey masterSecretKey) throws NoSuchAlgorithmException,
- PGPException, NoSuchProviderException, GeneralException,
+ PGPException, NoSuchProviderException, ApgGeneralException,
InvalidAlgorithmParameterException {
if (keySize < 512) {
- throw new GeneralException(context.getString(R.string.error_keySizeMinimum512bit));
+ throw new ApgGeneralException(context.getString(R.string.error_keySizeMinimum512bit));
}
if (passPhrase == null) {
@@ -277,7 +272,7 @@ public class PGPMain {
case Id.choice.algorithm.elgamal: {
if (masterSecretKey == null) {
- throw new GeneralException(
+ throw new ApgGeneralException(
context.getString(R.string.error_masterKeyMustNotBeElGamal));
}
keyGen = KeyPairGenerator.getInstance("ELGAMAL", BOUNCY_CASTLE_PROVIDER_NAME);
@@ -300,7 +295,7 @@ public class PGPMain {
}
default: {
- throw new GeneralException(context.getString(R.string.error_unknownAlgorithmChoice));
+ throw new ApgGeneralException(context.getString(R.string.error_unknownAlgorithmChoice));
}
}
@@ -345,8 +340,8 @@ public class PGPMain {
public static void buildSecretKey(Context context, ArrayList<String> userIds,
ArrayList<PGPSecretKey> keys, ArrayList<Integer> keysUsages, long masterKeyId,
String oldPassPhrase, String newPassPhrase, ProgressDialogUpdater progress)
- throws PGPMain.GeneralException, NoSuchProviderException, PGPException,
- NoSuchAlgorithmException, SignatureException, IOException, Database.GeneralException {
+ throws ApgGeneralException, NoSuchProviderException, PGPException,
+ NoSuchAlgorithmException, SignatureException, IOException {
updateProgress(progress, R.string.progress_buildingKey, 0, 100);
@@ -526,7 +521,7 @@ public class PGPMain {
}
} catch (IOException e) {
status = Id.return_value.error;
- } catch (Database.GeneralException e) {
+ } catch (ApgGeneralException.GeneralException e) {
status = Id.return_value.error;
}
@@ -558,7 +553,7 @@ public class PGPMain {
}
public static Bundle importKeyRings(Context context, int type, InputData data,
- ProgressDialogUpdater progress) throws GeneralException, FileNotFoundException,
+ ProgressDialogUpdater progress) throws ApgGeneralException, FileNotFoundException,
PGPException, IOException {
Bundle returnData = new Bundle();
@@ -571,7 +566,7 @@ public class PGPMain {
}
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
+ throw new ApgGeneralException(context.getString(R.string.error_externalStorageNotReady));
}
PositionAwareInputStream progressIn = new PositionAwareInputStream(data.getInputStream());
@@ -594,7 +589,7 @@ public class PGPMain {
}
if (status == Id.return_value.error) {
- throw new GeneralException(context.getString(R.string.error_savingKeys));
+ throw new ApgGeneralException(context.getString(R.string.error_savingKeys));
}
// update the counts to display to the user at the end
@@ -627,7 +622,7 @@ public class PGPMain {
}
public static Bundle exportKeyRings(Context context, Vector<Integer> keyRingIds,
- OutputStream outStream, ProgressDialogUpdater progress) throws GeneralException,
+ OutputStream outStream, ProgressDialogUpdater progress) throws ApgGeneralException,
FileNotFoundException, PGPException, IOException {
Bundle returnData = new Bundle();
@@ -638,7 +633,7 @@ public class PGPMain {
}
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
+ throw new ApgGeneralException(context.getString(R.string.error_externalStorageNotReady));
}
ArmoredOutputStream out = new ArmoredOutputStream(outStream);
out.setHeader("Version", getFullVersion(context));
@@ -758,7 +753,7 @@ public class PGPMain {
boolean armored, long encryptionKeyIds[], long signatureKeyId,
String signaturePassPhrase, ProgressDialogUpdater progress, int symmetricAlgorithm,
int hashAlgorithm, int compression, boolean forceV3Signature, String passPhrase)
- throws IOException, GeneralException, PGPException, NoSuchProviderException,
+ throws IOException, ApgGeneralException, PGPException, NoSuchProviderException,
NoSuchAlgorithmException, SignatureException {
if (encryptionKeyIds == null) {
@@ -780,7 +775,7 @@ public class PGPMain {
PGPPrivateKey signaturePrivateKey = null;
if (encryptionKeyIds.length == 0 && passPhrase == null) {
- throw new GeneralException(
+ throw new ApgGeneralException(
context.getString(R.string.error_noEncryptionKeysOrPassPhrase));
}
@@ -788,11 +783,12 @@ public class PGPMain {
signingKeyRing = getSecretKeyRing(signatureKeyId);
signingKey = PGPHelper.getSigningKey(signatureKeyId);
if (signingKey == null) {
- throw new GeneralException(context.getString(R.string.error_signatureFailed));
+ throw new ApgGeneralException(context.getString(R.string.error_signatureFailed));
}
if (signaturePassPhrase == null) {
- throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
+ throw new ApgGeneralException(
+ context.getString(R.string.error_noSignaturePassPhrase));
}
if (progress != null)
progress.setProgress(R.string.progress_extractingSignatureKey, 0, 100);
@@ -800,7 +796,7 @@ public class PGPMain {
BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
- throw new GeneralException(
+ throw new ApgGeneralException(
context.getString(R.string.error_couldNotExtractPrivateKey));
}
}
@@ -922,7 +918,7 @@ public class PGPMain {
public static void signText(Context context, InputData data, OutputStream outStream,
long signatureKeyId, String signaturePassPhrase, int hashAlgorithm,
- boolean forceV3Signature, ProgressDialogUpdater progress) throws GeneralException,
+ boolean forceV3Signature, ProgressDialogUpdater progress) throws ApgGeneralException,
PGPException, IOException, NoSuchAlgorithmException, SignatureException {
ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream);
@@ -934,26 +930,27 @@ public class PGPMain {
if (signatureKeyId == 0) {
armorOut.close();
- throw new GeneralException(context.getString(R.string.error_noSignatureKey));
+ throw new ApgGeneralException(context.getString(R.string.error_noSignatureKey));
}
signingKeyRing = getSecretKeyRing(signatureKeyId);
signingKey = PGPHelper.getSigningKey(signatureKeyId);
if (signingKey == null) {
armorOut.close();
- throw new GeneralException(context.getString(R.string.error_signatureFailed));
+ throw new ApgGeneralException(context.getString(R.string.error_signatureFailed));
}
if (signaturePassPhrase == null) {
armorOut.close();
- throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
+ throw new ApgGeneralException(context.getString(R.string.error_noSignaturePassPhrase));
}
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
armorOut.close();
- throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
+ throw new ApgGeneralException(
+ context.getString(R.string.error_couldNotExtractPrivateKey));
}
updateProgress(progress, R.string.progress_preparingStreams, 0, 100);
@@ -1029,7 +1026,7 @@ public class PGPMain {
public static void generateSignature(Context context, InputData data, OutputStream outStream,
boolean armored, boolean binary, long signatureKeyId, String signaturePassPhrase,
int hashAlgorithm, boolean forceV3Signature, ProgressDialogUpdater progress)
- throws GeneralException, PGPException, IOException, NoSuchAlgorithmException,
+ throws ApgGeneralException, PGPException, IOException, NoSuchAlgorithmException,
SignatureException {
OutputStream out = null;
@@ -1049,24 +1046,25 @@ public class PGPMain {
PGPPrivateKey signaturePrivateKey = null;
if (signatureKeyId == 0) {
- throw new GeneralException(context.getString(R.string.error_noSignatureKey));
+ throw new ApgGeneralException(context.getString(R.string.error_noSignatureKey));
}
signingKeyRing = getSecretKeyRing(signatureKeyId);
signingKey = PGPHelper.getSigningKey(signatureKeyId);
if (signingKey == null) {
- throw new GeneralException(context.getString(R.string.error_signatureFailed));
+ throw new ApgGeneralException(context.getString(R.string.error_signatureFailed));
}
if (signaturePassPhrase == null) {
- throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
+ throw new ApgGeneralException(context.getString(R.string.error_noSignaturePassPhrase));
}
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
- throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
+ throw new ApgGeneralException(
+ context.getString(R.string.error_couldNotExtractPrivateKey));
}
updateProgress(progress, R.string.progress_preparingStreams, 0, 100);
@@ -1146,23 +1144,23 @@ public class PGPMain {
}
public static PGPPublicKeyRing signKey(Context context, long masterKeyId, long pubKeyId,
- String passphrase) throws GeneralException, NoSuchAlgorithmException,
+ String passphrase) throws ApgGeneralException, NoSuchAlgorithmException,
NoSuchProviderException, PGPException, SignatureException {
if (passphrase == null || passphrase.length() <= 0) {
- throw new GeneralException("Unable to obtain passphrase");
+ throw new ApgGeneralException("Unable to obtain passphrase");
} else {
PGPPublicKeyRing pubring = PGPMain.getPublicKeyRing(pubKeyId);
PGPSecretKey signingKey = PGPHelper.getSigningKey(masterKeyId);
if (signingKey == null) {
- throw new GeneralException(context.getString(R.string.error_signatureFailed));
+ throw new ApgGeneralException(context.getString(R.string.error_signatureFailed));
}
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
- throw new GeneralException(
+ throw new ApgGeneralException(
context.getString(R.string.error_couldNotExtractPrivateKey));
}
@@ -1190,7 +1188,7 @@ public class PGPMain {
}
public static long getDecryptionKeyId(Context context, InputStream inputStream)
- throws GeneralException, NoAsymmetricEncryptionException, IOException {
+ throws ApgGeneralException, NoAsymmetricEncryptionException, IOException {
InputStream in = PGPUtil.getDecoderStream(inputStream);
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
@@ -1204,7 +1202,7 @@ public class PGPMain {
}
if (enc == null) {
- throw new GeneralException(context.getString(R.string.error_invalidData));
+ throw new ApgGeneralException(context.getString(R.string.error_invalidData));
}
// TODO: currently we always only look at the first known key
@@ -1236,7 +1234,7 @@ public class PGPMain {
}
public static boolean hasSymmetricEncryption(Context context, InputStream inputStream)
- throws GeneralException, IOException {
+ throws ApgGeneralException, IOException {
InputStream in = PGPUtil.getDecoderStream(inputStream);
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
@@ -1250,7 +1248,7 @@ public class PGPMain {
}
if (enc == null) {
- throw new GeneralException(context.getString(R.string.error_invalidData));
+ throw new ApgGeneralException(context.getString(R.string.error_invalidData));
}
Iterator<?> it = enc.getEncryptedDataObjects();
@@ -1266,7 +1264,7 @@ public class PGPMain {
public static Bundle decrypt(Context context, InputData data, OutputStream outStream,
String passPhrase, ProgressDialogUpdater progress, boolean assumeSymmetric)
- throws IOException, GeneralException, PGPException, SignatureException {
+ throws IOException, ApgGeneralException, PGPException, SignatureException {
if (passPhrase == null) {
passPhrase = "";
}
@@ -1288,7 +1286,7 @@ public class PGPMain {
}
if (enc == null) {
- throw new GeneralException(context.getString(R.string.error_invalidData));
+ throw new ApgGeneralException(context.getString(R.string.error_invalidData));
}
InputStream clear = null;
@@ -1311,7 +1309,7 @@ public class PGPMain {
}
if (pbe == null) {
- throw new GeneralException(
+ throw new ApgGeneralException(
context.getString(R.string.error_noSymmetricEncryptionPacket));
}
@@ -1347,7 +1345,7 @@ public class PGPMain {
}
if (secretKey == null) {
- throw new GeneralException(context.getString(R.string.error_noSecretKeyFound));
+ throw new ApgGeneralException(context.getString(R.string.error_noSecretKeyFound));
}
currentProgress += 5;
@@ -1361,7 +1359,7 @@ public class PGPMain {
throw new PGPException(context.getString(R.string.error_wrongPassPhrase));
}
if (privateKey == null) {
- throw new GeneralException(
+ throw new ApgGeneralException(
context.getString(R.string.error_couldNotExtractPrivateKey));
}
currentProgress += 5;
@@ -1511,7 +1509,7 @@ public class PGPMain {
public static Bundle verifyText(Context context, InputData data, OutputStream outStream,
boolean lookupUnknownKey, ProgressDialogUpdater progress) throws IOException,
- GeneralException, PGPException, SignatureException {
+ ApgGeneralException, PGPException, SignatureException {
Bundle returnData = new Bundle();
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -1547,7 +1545,7 @@ public class PGPMain {
PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
if (sigList == null) {
- throw new GeneralException(context.getString(R.string.error_corruptData));
+ throw new ApgGeneralException(context.getString(R.string.error_corruptData));
}
PGPSignature signature = null;
long signatureKeyId = 0;
diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java b/org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java
new file mode 100644
index 000000000..10f9fa05e
--- /dev/null
+++ b/org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * 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.
+ */
+
+package org.thialfihar.android.apg.provider;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * TODO:
+ *
+ * Breaking compatibility?:
+ *
+ * - change CONTENT_AUTHORITY
+ *
+ * - change type names
+ *
+ */
+public class ApgContract {
+
+ interface KeyRingsColumns {
+ String MASTER_KEY_ID = "master_key_id"; // TODO: clarify
+ String TYPE = "type"; // see KeyTypes
+ String WHO_ID = "who_id";
+ String KEY_RING_DATA = "key_ring_data"; // blob
+ }
+
+ interface KeysColumns {
+ String KEY_ID = "key_id"; // not a database id
+ String TYPE = "type"; // see KeyTypes
+ String IS_MASTER_KEY = "is_master_key";
+ String ALGORITHM = "algorithm";
+ String KEY_SIZE = "key_size";
+ String CAN_SIGN = "can_sign";
+ String CAN_ENCRYPT = "can_encrypt";
+ 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";
+ String RANK = "key_data"; // blob
+ }
+
+ interface UserIdsColumns {
+ String KEY_ROW_ID = "key_id"; // foreign key to keys._ID
+ String USER_ID = "user_id"; // not a database id
+ String RANK = "rank";
+ }
+
+ public static final class KeyTypes {
+ public static final int PUBLIC = 0;
+ public static final int SECRET = 1;
+ }
+
+ public static final String CONTENT_AUTHORITY = "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);
+
+ public static final String BASE_KEY_RINGS = "key_rings";
+ public static final String BASE_DATA = "data";
+
+ public static final String PATH_PUBLIC = "public";
+ public static final String PATH_SECRET = "secret";
+
+ 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";
+
+ public static class PublicKeyRings implements KeyRingsColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
+ .appendPath(BASE_KEY_RINGS).appendPath(PATH_PUBLIC).build();
+
+ /** Use if multiple items get returned */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.public.key_ring";
+
+ /** Use if a single item is returned */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.public.key_ring";
+
+ public static Uri buildPublicKeyRingsUri() {
+ return CONTENT_URI.buildUpon().build();
+ }
+
+ public static Uri buildPublicKeyRingsUri(String keyRingRowId) {
+ 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 buildPublicKeyRingsByEmailsUri(String emails) {
+ return CONTENT_URI.buildUpon().appendPath(PATH_BY_EMAILS).appendPath(emails).build();
+ }
+ }
+
+ public static class SecretKeyRings implements KeyRingsColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
+ .appendPath(BASE_KEY_RINGS).appendPath(PATH_SECRET).build();
+
+ /** Use if multiple items get returned */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.secret.key_ring";
+
+ /** Use if a single item is returned */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.secret.key_ring";
+
+ public static Uri buildSecretKeyRingsUri() {
+ return CONTENT_URI.buildUpon().build();
+ }
+
+ public static Uri buildSecretKeyRingsUri(String keyRingRowId) {
+ 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 buildSecretKeyRingsByEmailsUri(String emails) {
+ return CONTENT_URI.buildUpon().appendPath(PATH_BY_EMAILS).appendPath(emails).build();
+ }
+ }
+
+ public static class PublicKeys implements KeysColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
+ .appendPath(BASE_KEY_RINGS).appendPath(PATH_PUBLIC).build();
+
+ /** Use if multiple items get returned */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.public.key";
+
+ /** Use if a single item is returned */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.public.key";
+
+ public static Uri buildPublicKeysUri(String keyRingRowId) {
+ return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_KEYS).build();
+ }
+
+ public static Uri buildPublicKeysRankUri(String keyRingRowId) {
+ return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_KEYS)
+ .appendPath(PATH_RANK).build();
+ }
+ }
+
+ public static class SecretKeys implements KeysColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
+ .appendPath(BASE_KEY_RINGS).appendPath(PATH_SECRET).build();
+
+ /** Use if multiple items get returned */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.secret.key";
+
+ /** Use if a single item is returned */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.secret.key";
+
+ public static Uri buildSecretKeysUri(String keyRingRowId) {
+ return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_KEYS).build();
+ }
+
+ public static Uri buildSecretKeysRankUri(String keyRingRowId) {
+ return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_KEYS)
+ .appendPath(PATH_RANK).build();
+ }
+ }
+
+ public static class PublicUserIds implements UserIdsColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
+ .appendPath(BASE_KEY_RINGS).appendPath(PATH_PUBLIC).build();
+
+ /** Use if multiple items get returned */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.user_id";
+
+ /** Use if a single item is returned */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.user_id";
+
+ public static Uri buildPublicUserIdsUri(String keyRingRowId) {
+ return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_USER_IDS)
+ .build();
+ }
+
+ public static Uri buildPublicUserIdsRankUri(String keyRingRowId) {
+ return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_USER_IDS)
+ .appendPath(PATH_RANK).build();
+ }
+ }
+
+ public static class SecretUserIds implements UserIdsColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
+ .appendPath(BASE_KEY_RINGS).appendPath(PATH_SECRET).build();
+
+ /** Use if multiple items get returned */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.user_id";
+
+ /** Use if a single item is returned */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.user_id";
+
+ public static Uri buildSecretUserIdsUri(String keyRingRowId) {
+ return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_USER_IDS)
+ .build();
+ }
+
+ public static Uri buildSecretUserIdsRankUri(String keyRingRowId) {
+ return CONTENT_URI.buildUpon().appendPath(keyRingRowId).appendPath(PATH_USER_IDS)
+ .appendPath(PATH_RANK).build();
+ }
+ }
+
+ public static class DataStream {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(BASE_DATA)
+ .build();
+
+ public static Uri buildDataStreamUri(String streamFilename) {
+ return CONTENT_URI.buildUpon().appendPath(streamFilename).build();
+ }
+ }
+
+ private ApgContract() {
+ }
+}
diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java b/org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java
new file mode 100644
index 000000000..fdee2f101
--- /dev/null
+++ b/org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * 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.
+ */
+
+package org.thialfihar.android.apg.provider;
+
+import org.thialfihar.android.apg.Constants;
+import org.thialfihar.android.apg.provider.ApgContract.KeyRingsColumns;
+import org.thialfihar.android.apg.provider.ApgContract.KeysColumns;
+import org.thialfihar.android.apg.provider.ApgContract.UserIdsColumns;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.provider.BaseColumns;
+
+import org.thialfihar.android.apg.util.Log;
+
+public class ApgDatabase extends SQLiteOpenHelper {
+ private static final String DATABASE_NAME = "apg.db";
+ // Last APG 1 db version was 2
+ private static final int DATABASE_VERSION = 3;
+
+ public interface Tables {
+ String KEY_RINGS = "key_rings";
+ String KEYS = "keys";
+ String USER_IDS = "user_ids";
+ }
+
+ private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS
+ + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY, " + KeyRingsColumns.MASTER_KEY_ID
+ + " INT64, " + KeyRingsColumns.TYPE + " INTEGER, " + KeyRingsColumns.WHO_ID
+ + " 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
+ + " 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.USER_IDS
+ + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY, " + UserIdsColumns.KEY_ROW_ID
+ + " INTEGER REFERENCES " + Tables.KEYS + " ON DELETE CASCADE, "
+ + UserIdsColumns.USER_ID + " TEXT, " + UserIdsColumns.RANK + " INTEGER)";
+
+ ApgDatabase(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ //
+ // 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);
+ // }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ Log.w(Constants.TAG, "Creating database...");
+
+ db.execSQL(CREATE_KEY_RINGS);
+ db.execSQL(CREATE_KEYS);
+ db.execSQL(CREATE_USER_IDS);
+ }
+
+ @Override
+ public void onOpen(SQLiteDatabase db) {
+ super.onOpen(db);
+ if (!db.isReadOnly()) {
+ // Enable foreign key constraints
+ db.execSQL("PRAGMA foreign_keys=ON;");
+ }
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.w(Constants.TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
+
+ // Upgrade from oldVersion through all methods to newest one
+ for (int version = oldVersion; version < newVersion; ++version) {
+ Log.w(Constants.TAG, "Upgrading database to version " + version);
+
+ switch (version) {
+ case 1:
+
+ break;
+
+ default:
+ break;
+
+ }
+ }
+ }
+
+}
diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java b/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java
new file mode 100644
index 000000000..e25228434
--- /dev/null
+++ b/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * 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.
+ */
+
+package org.thialfihar.android.apg.provider;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.thialfihar.android.apg.Constants;
+import org.thialfihar.android.apg.provider.ApgContract.KeyRingsColumns;
+import org.thialfihar.android.apg.provider.ApgContract.KeyTypes;
+import org.thialfihar.android.apg.provider.ApgContract.KeysColumns;
+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.provider.ApgContract.UserIdsColumns;
+import org.thialfihar.android.apg.provider.ApgDatabase.Tables;
+import org.thialfihar.android.apg.util.Log;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteConstraintException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.provider.BaseColumns;
+import android.text.TextUtils;
+
+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_ID = 102;
+ private static final int PUBLIC_KEY_RING_BY_KEY_ID = 103;
+ private static final int PUBLIC_KEY_RING_BY_EMAILS = 104;
+ 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_USER_ID = 121;
+ private static final int PUBLIC_KEY_RING_USER_ID_RANK = 122;
+
+ private static final int SECRET_KEY_RING = 201;
+ private static final int SECRET_KEY_RING_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_KEY = 211;
+ private static final int SECRET_KEY_RING_KEY_RANK = 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 DATA_STREAM = 301;
+
+ /**
+ * Build and return a {@link UriMatcher} that catches all {@link Uri} variations supported by
+ * this {@link ContentProvider}.
+ */
+ private static UriMatcher buildUriMatcher() {
+ final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
+ final String authority = ApgContract.CONTENT_AUTHORITY;
+
+ /**
+ * public key rings
+ *
+ * <pre>
+ * key_rings/public
+ * key_rings/public/_
+ * key_rings/public/key_id/_
+ * key_rings/public/emails/_
+ * </pre>
+ */
+ 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_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 + "/"
+ + ApgContract.PATH_BY_EMAILS + "/*", PUBLIC_KEY_RING_BY_EMAILS);
+
+ /**
+ * public keys
+ *
+ * <pre>
+ * key_rings/public/_/keys
+ * key_rings/public/_/keys/#
+ * </pre>
+ */
+ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC
+ + "/*/" + 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);
+
+ /**
+ * public user ids
+ *
+ * <pre>
+ * key_rings/public/_/user_ids
+ * key_rings/public/_/user_ids/#
+ * </pre>
+ */
+ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC
+ + "/*/" + 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);
+
+ /**
+ * secret key rings
+ *
+ * <pre>
+ * key_rings/secret
+ * key_rings/secret/*
+ * key_rings/secret/key_id/*
+ * key_rings/secret/emails/*
+ * </pre>
+ */
+ 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_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 + "/"
+ + ApgContract.PATH_BY_EMAILS + "/*", SECRET_KEY_RING_BY_EMAILS);
+
+ /**
+ * secret keys
+ *
+ * <pre>
+ * key_rings/secret/_/keys
+ * key_rings/secret/_/keys/#
+ * </pre>
+ */
+ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET
+ + "/*/" + 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);
+
+ /**
+ * secret user ids
+ *
+ * <pre>
+ * key_rings/secret/_/user_ids
+ * key_rings/secret/_/user_ids/#
+ * </pre>
+ */
+ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET
+ + "/*/" + 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);
+
+ /**
+ * data stream
+ *
+ * <pre>
+ * data/*
+ * </pre>
+ */
+ matcher.addURI(authority, ApgContract.BASE_DATA + "/*", DATA_STREAM);
+
+ return matcher;
+ }
+
+ private ApgDatabase mApgDatabase;
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean onCreate() {
+ final Context context = getContext();
+ mApgDatabase = new ApgDatabase(context);
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getType(Uri uri) {
+ final int match = sUriMatcher.match(uri);
+ switch (match) {
+ case PUBLIC_KEY_RING:
+ case PUBLIC_KEY_RING_BY_EMAILS:
+ return PublicKeyRings.CONTENT_TYPE;
+
+ case PUBLIC_KEY_RING_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:
+ return PublicKeys.CONTENT_ITEM_TYPE;
+
+ case PUBLIC_KEY_RING_USER_ID:
+ return PublicUserIds.CONTENT_TYPE;
+
+ case PUBLIC_KEY_RING_USER_ID_RANK:
+ return PublicUserIds.CONTENT_ITEM_TYPE;
+
+ case SECRET_KEY_RING:
+ case SECRET_KEY_RING_BY_EMAILS:
+ return SecretKeyRings.CONTENT_TYPE;
+
+ case SECRET_KEY_RING_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:
+ return SecretKeys.CONTENT_ITEM_TYPE;
+
+ case SECRET_KEY_RING_USER_ID:
+ return SecretUserIds.CONTENT_TYPE;
+
+ case SECRET_KEY_RING_USER_ID_RANK:
+ return SecretUserIds.CONTENT_ITEM_TYPE;
+
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+ }
+
+ /**
+ * Returns weather the key is a public or secret one
+ *
+ * @param uri
+ * @return
+ */
+ private int getKeyType(int match) {
+ int type;
+ switch (match) {
+ case PUBLIC_KEY_RING:
+ case PUBLIC_KEY_RING_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_USER_ID:
+ case PUBLIC_KEY_RING_USER_ID_RANK:
+ type = KeyTypes.PUBLIC;
+ break;
+
+ case SECRET_KEY_RING:
+ case SECRET_KEY_RING_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_USER_ID:
+ case SECRET_KEY_RING_USER_ID_RANK:
+ type = KeyTypes.SECRET;
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown match " + match);
+
+ }
+
+ return type;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
+
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+ SQLiteDatabase db = mApgDatabase.getReadableDatabase();
+
+ HashMap<String, String> projectionMap = new HashMap<String, String>();
+
+ int match = sUriMatcher.match(uri);
+
+ qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = " + getKeyType(match));
+
+ switch (match) {
+ case PUBLIC_KEY_RING_ID:
+ case SECRET_KEY_RING_ID:
+ qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = ");
+ qb.appendWhereEscapeString(uri.getPathSegments().get(2));
+
+ // 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_ID + " AND " + Tables.KEYS + "."
+ + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN "
+ + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = "
+ + Tables.USER_IDS + "." + UserIdsColumns.KEY_ID + " AND " + Tables.USER_IDS
+ + "." + UserIdsColumns.RANK + " = '0') ");
+
+ projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._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.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
+ }
+
+ break;
+
+ case SECRET_KEY_RING_BY_KEY_ID:
+ case PUBLIC_KEY_RING_BY_KEY_ID:
+ qb.setTables(Tables.KEYS + " AS tmp INNER JOIN " + Tables.KEY_RINGS + " ON ("
+ + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + "tmp."
+ + KeysColumns.KEY_RING_ID + ")" + " INNER JOIN " + Tables.KEYS + " ON " + "("
+ + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "."
+ + KeysColumns.KEY_RING_ID + " AND " + Tables.KEYS + "."
+ + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN "
+ + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = "
+ + Tables.USER_IDS + "." + UserIdsColumns.KEY_ID + " AND " + Tables.USER_IDS
+ + "." + UserIdsColumns.RANK + " = '0') ");
+
+ projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._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));
+
+ break;
+
+ case SECRET_KEY_RING_BY_EMAILS:
+ case PUBLIC_KEY_RING_BY_EMAILS:
+ qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "("
+ + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "."
+ + KeysColumns.KEY_RING_ID + " AND " + Tables.KEYS + "."
+ + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN "
+ + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = "
+ + Tables.USER_IDS + "." + UserIdsColumns.KEY_ID + " AND " + Tables.USER_IDS
+ + "." + UserIdsColumns.RANK + " = '0') ");
+
+ projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._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 chunks[] = emails.split(" *, *");
+ boolean gotCondition = false;
+ String emailWhere = "";
+ for (int i = 0; i < chunks.length; ++i) {
+ if (chunks[i].length() == 0) {
+ continue;
+ }
+ if (i != 0) {
+ emailWhere += " OR ";
+ }
+ emailWhere += "tmp." + UserIdsColumns.USER_ID + " LIKE ";
+ // match '*<email>', so it has to be at the *end* of the user id
+ emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
+ gotCondition = true;
+ }
+
+ if (gotCondition) {
+ qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM "
+ + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_ID + " = "
+ + Tables.KEYS + "." + BaseColumns._ID + " AND (" + emailWhere + "))");
+ }
+
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+
+ }
+
+ qb.setProjectionMap(projectionMap);
+
+ // If no sort order is specified use the default
+ String orderBy;
+ if (TextUtils.isEmpty(sortOrder)) {
+ orderBy = null;
+ } else {
+ 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
+ c.setNotificationUri(getContext().getContentResolver(), uri);
+ return c;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");
+
+ final SQLiteDatabase db = mApgDatabase.getWritableDatabase();
+
+ Uri rowUri = null;
+ try {
+ final int match = sUriMatcher.match(uri);
+
+ switch (match) {
+ case PUBLIC_KEY_RING:
+ values.put(PublicKeyRings.TYPE, KeyTypes.PUBLIC);
+
+ db.insertOrThrow(Tables.KEY_RINGS, null, values);
+ rowUri = PublicKeyRings.buildPublicKeyRingsUri(values
+ .getAsString(PublicKeyRings._ID));
+
+ break;
+ case PUBLIC_KEY_RING_KEY:
+ values.put(PublicKeys.TYPE, KeyTypes.PUBLIC);
+
+ db.insertOrThrow(Tables.KEYS, null, values);
+ rowUri = PublicKeys.buildPublicKeysUri(values.getAsString(PublicKeys._ID));
+
+ break;
+ case PUBLIC_KEY_RING_USER_ID:
+ db.insertOrThrow(Tables.USER_IDS, null, values);
+ rowUri = PublicUserIds.buildPublicUserIdsUri(values.getAsString(PublicUserIds._ID));
+
+ break;
+ case SECRET_KEY_RING:
+ values.put(SecretKeyRings.TYPE, KeyTypes.SECRET);
+
+ db.insertOrThrow(Tables.KEY_RINGS, null, values);
+ rowUri = SecretKeyRings.buildSecretKeyRingsUri(values
+ .getAsString(SecretKeyRings._ID));
+
+ break;
+ case SECRET_KEY_RING_KEY:
+ values.put(SecretKeys.TYPE, KeyTypes.SECRET);
+
+ db.insertOrThrow(Tables.KEYS, null, values);
+ rowUri = SecretKeys.buildSecretKeysUri(values.getAsString(SecretKeys._ID));
+
+ break;
+ case SECRET_KEY_RING_USER_ID:
+ db.insertOrThrow(Tables.USER_IDS, null, values);
+ rowUri = SecretUserIds.buildSecretUserIdsUri(values.getAsString(SecretUserIds._ID));
+
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+ } catch (SQLiteConstraintException e) {
+ Log.e(Constants.TAG, "Constraint exception on insert! Entry already existing?");
+ }
+
+ // notify of changes in db
+ getContext().getContentResolver().notifyChange(uri, null);
+
+ return rowUri;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ Log.v(Constants.TAG, "delete(uri=" + uri + ")");
+
+ final SQLiteDatabase db = mApgDatabase.getWritableDatabase();
+
+ int count;
+ final int match = sUriMatcher.match(uri);
+
+ switch (match) {
+ case PUBLIC_KEY_RING_ID:
+ // delete corresponding keys and userids
+ // db.delete(Tables.KEYS, whereClause, whereArgs)
+ // TODO
+ count = db.delete(Tables.KEY_RINGS,
+ buildDefaultSelection(uri, KeyTypes.PUBLIC, selection), selectionArgs);
+ break;
+ case SECRET_KEY_RING_ID:
+ // delete corresponding keys and userids
+ // TODO
+ count = db.delete(Tables.KEY_RINGS,
+ buildDefaultSelection(uri, KeyTypes.SECRET, selection), selectionArgs);
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+
+ // notify of changes in db
+ getContext().getContentResolver().notifyChange(uri, null);
+
+ return count;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
+
+ final SQLiteDatabase db = mApgDatabase.getWritableDatabase();
+
+ int count = 0;
+ try {
+ final int match = sUriMatcher.match(uri);
+ switch (match) {
+ case PUBLIC_KEY_RING_ID:
+ count = db.update(Tables.KEY_RINGS, values,
+ buildDefaultSelection(uri, KeyTypes.PUBLIC, selection), selectionArgs);
+ break;
+ case SECRET_KEY_RING_ID:
+ count = db.update(Tables.KEY_RINGS, values,
+ buildDefaultSelection(uri, KeyTypes.PUBLIC, selection), selectionArgs);
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+ } catch (SQLiteConstraintException e) {
+ Log.e(Constants.TAG, "Constraint exception on update! Entry already existing?");
+ }
+
+ // notify of changes in db
+ getContext().getContentResolver().notifyChange(uri, null);
+
+ return count;
+ }
+
+ /**
+ * Build default selection statement. 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 + ")";
+ }
+
+ String andType = "";
+ if (keyType != null) {
+ andType = " AND " + KeyRingsColumns.TYPE + "=" + keyType;
+ }
+
+ return BaseColumns._ID + "=" + rowId + andType + andWhere;
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ int match = sUriMatcher.match(uri);
+ if (match != DATA_STREAM) {
+ throw new FileNotFoundException();
+ }
+ String fileName = uri.getPathSegments().get(1);
+ 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/DataProvider.java b/org_apg/src/org/thialfihar/android/apg/provider/DataProvider.java
deleted file mode 100644
index 9cf083528..000000000
--- a/org_apg/src/org/thialfihar/android/apg/provider/DataProvider.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * 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.
- */
-
-package org.thialfihar.android.apg.provider;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.HashMap;
-
-import org.thialfihar.android.apg.Id;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
-
-public class DataProvider extends ContentProvider {
- public static final String AUTHORITY = "org.thialfihar.android.apg.provider";
-
- private static final int PUBLIC_KEY_RING = 101;
- private static final int PUBLIC_KEY_RING_ID = 102;
- private static final int PUBLIC_KEY_RING_BY_KEY_ID = 103;
- private static final int PUBLIC_KEY_RING_BY_EMAILS = 104;
- 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_USER_ID = 121;
- private static final int PUBLIC_KEY_RING_USER_ID_RANK = 122;
-
- private static final int SECRET_KEY_RING = 201;
- private static final int SECRET_KEY_RING_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_KEY = 211;
- private static final int SECRET_KEY_RING_KEY_RANK = 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 DATA_STREAM = 301;
-
- private static final String PUBLIC_KEY_RING_CONTENT_DIR_TYPE =
- "vnd.android.cursor.dir/vnd.thialfihar.apg.public.key_ring";
- private static final String PUBLIC_KEY_RING_CONTENT_ITEM_TYPE =
- "vnd.android.cursor.item/vnd.thialfihar.apg.public.key_ring";
-
- private static final String PUBLIC_KEY_CONTENT_DIR_TYPE =
- "vnd.android.cursor.dir/vnd.thialfihar.apg.public.key";
- private static final String PUBLIC_KEY_CONTENT_ITEM_TYPE =
- "vnd.android.cursor.item/vnd.thialfihar.apg.public.key";
-
- private static final String SECRET_KEY_RING_CONTENT_DIR_TYPE =
- "vnd.android.cursor.dir/vnd.thialfihar.apg.secret.key_ring";
- private static final String SECRET_KEY_RING_CONTENT_ITEM_TYPE =
- "vnd.android.cursor.item/vnd.thialfihar.apg.secret.key_ring";
-
- private static final String SECRET_KEY_CONTENT_DIR_TYPE =
- "vnd.android.cursor.dir/vnd.thialfihar.apg.secret.key";
- private static final String SECRET_KEY_CONTENT_ITEM_TYPE =
- "vnd.android.cursor.item/vnd.thialfihar.apg.secret.key";
-
- private static final String USER_ID_CONTENT_DIR_TYPE =
- "vnd.android.cursor.dir/vnd.thialfihar.apg.user_id";
- private static final String USER_ID_CONTENT_ITEM_TYPE =
- "vnd.android.cursor.item/vnd.thialfihar.apg.user_id";
-
- public static final String _ID = "_id";
- public static final String MASTER_KEY_ID = "master_key_id";
- public static final String KEY_ID = "key_id";
- public static final String USER_ID = "user_id";
-
- private static final UriMatcher mUriMatcher;
-
- private Database mDb;
-
- static {
- mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- mUriMatcher.addURI(AUTHORITY, "key_rings/public/key_id/*", PUBLIC_KEY_RING_BY_KEY_ID);
- mUriMatcher.addURI(AUTHORITY, "key_rings/public/emails/*", PUBLIC_KEY_RING_BY_EMAILS);
-
- mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/keys", PUBLIC_KEY_RING_KEY);
- mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/keys/#", PUBLIC_KEY_RING_KEY_RANK);
-
- mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/user_ids", PUBLIC_KEY_RING_USER_ID);
- mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/user_ids/#", PUBLIC_KEY_RING_USER_ID_RANK);
-
- mUriMatcher.addURI(AUTHORITY, "key_rings/public", PUBLIC_KEY_RING);
- mUriMatcher.addURI(AUTHORITY, "key_rings/public/*", PUBLIC_KEY_RING_ID);
-
- mUriMatcher.addURI(AUTHORITY, "key_rings/secret/key_id/*", SECRET_KEY_RING_BY_KEY_ID);
- mUriMatcher.addURI(AUTHORITY, "key_rings/secret/emails/*", SECRET_KEY_RING_BY_EMAILS);
-
- mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/keys", SECRET_KEY_RING_KEY);
- mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/keys/#", SECRET_KEY_RING_KEY_RANK);
-
- mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/user_ids", SECRET_KEY_RING_USER_ID);
- mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/user_ids/#", SECRET_KEY_RING_USER_ID_RANK);
-
- mUriMatcher.addURI(AUTHORITY, "key_rings/secret", SECRET_KEY_RING);
- mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*", SECRET_KEY_RING_ID);
-
- mUriMatcher.addURI(AUTHORITY, "data/*", DATA_STREAM);
- }
-
- @Override
- public boolean onCreate() {
- mDb = new Database(getContext());
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- // TODO: implement the others, then use them for the lists
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
- HashMap<String, String> projectionMap = new HashMap<String, String>();
-
- int match = mUriMatcher.match(uri);
- int type;
- switch (match) {
- case PUBLIC_KEY_RING:
- case PUBLIC_KEY_RING_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_USER_ID:
- case PUBLIC_KEY_RING_USER_ID_RANK:
- type = Id.database.type_public;
- break;
-
- case SECRET_KEY_RING:
- case SECRET_KEY_RING_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_USER_ID:
- case SECRET_KEY_RING_USER_ID_RANK:
- type = Id.database.type_secret;
- break;
-
- default: {
- throw new IllegalArgumentException("Unknown URI " + uri);
- }
- }
-
- qb.appendWhere(KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = " + type);
-
- switch (match) {
- case PUBLIC_KEY_RING_ID:
- case SECRET_KEY_RING_ID: {
- qb.appendWhere(" AND " +
- KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(2));
-
- // break omitted intentionally
- }
-
- case PUBLIC_KEY_RING:
- case SECRET_KEY_RING: {
- qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " +
- "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " +
- Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " +
- Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" +
- ") " +
- " INNER JOIN " + UserIds.TABLE_NAME + " ON " +
- "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " +
- UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " +
- UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ");
-
- projectionMap.put(_ID,
- KeyRings.TABLE_NAME + "." + KeyRings._ID);
- projectionMap.put(MASTER_KEY_ID,
- KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID);
- projectionMap.put(USER_ID,
- UserIds.TABLE_NAME + "." + UserIds.USER_ID);
-
- if (TextUtils.isEmpty(sortOrder)) {
- sortOrder = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC";
- }
-
- break;
- }
-
- case SECRET_KEY_RING_BY_KEY_ID:
- case PUBLIC_KEY_RING_BY_KEY_ID: {
- qb.setTables(Keys.TABLE_NAME + " AS tmp INNER JOIN " +
- KeyRings.TABLE_NAME + " ON (" +
- KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " +
- "tmp." + Keys.KEY_RING_ID + ")" +
- " INNER JOIN " + Keys.TABLE_NAME + " ON " +
- "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " +
- Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " +
- Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" +
- ") " +
- " INNER JOIN " + UserIds.TABLE_NAME + " ON " +
- "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " +
- UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " +
- UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ");
-
- projectionMap.put(_ID,
- KeyRings.TABLE_NAME + "." + KeyRings._ID);
- projectionMap.put(MASTER_KEY_ID,
- KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID);
- projectionMap.put(USER_ID,
- UserIds.TABLE_NAME + "." + UserIds.USER_ID);
-
- qb.appendWhere(" AND tmp." + Keys.KEY_ID + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(3));
-
- break;
- }
-
- case SECRET_KEY_RING_BY_EMAILS:
- case PUBLIC_KEY_RING_BY_EMAILS: {
- qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " +
- "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " +
- Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " +
- Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" +
- ") " +
- " INNER JOIN " + UserIds.TABLE_NAME + " ON " +
- "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " +
- UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " +
- UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ");
-
- projectionMap.put(_ID,
- KeyRings.TABLE_NAME + "." + KeyRings._ID);
- projectionMap.put(MASTER_KEY_ID,
- KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID);
- projectionMap.put(USER_ID,
- UserIds.TABLE_NAME + "." + UserIds.USER_ID);
-
- String emails = uri.getPathSegments().get(3);
- String chunks[] = emails.split(" *, *");
- boolean gotCondition = false;
- String emailWhere = "";
- for (int i = 0; i < chunks.length; ++i) {
- if (chunks[i].length() == 0) {
- continue;
- }
- if (i != 0) {
- emailWhere += " OR ";
- }
- emailWhere += "tmp." + UserIds.USER_ID + " LIKE ";
- // match '*<email>', so it has to be at the *end* of the user id
- emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
- gotCondition = true;
- }
-
- if (gotCondition) {
- qb.appendWhere(" AND EXISTS (SELECT tmp." + UserIds._ID +
- " FROM " + UserIds.TABLE_NAME +
- " AS tmp WHERE tmp." + UserIds.KEY_ID + " = " +
- Keys.TABLE_NAME + "." + Keys._ID +
- " AND (" + emailWhere + "))");
- }
-
- break;
- }
-
- default: {
- throw new IllegalArgumentException("Unknown URI " + uri);
- }
- }
-
- qb.setProjectionMap(projectionMap);
-
- // If no sort order is specified use the default
- String orderBy;
- if (TextUtils.isEmpty(sortOrder)) {
- orderBy = null;
- } else {
- orderBy = sortOrder;
- }
-
- //System.out.println(qb.buildQuery(projection, selection, selectionArgs, null, null, sortOrder, null).replace("WHERE", "WHERE\n"));
- Cursor c = qb.query(mDb.db(), projection, selection, selectionArgs, null, null, orderBy);
-
- // Tell the cursor what uri to watch, so it knows when its source data changes
- c.setNotificationUri(getContext().getContentResolver(), uri);
- return c;
- }
-
- @Override
- public String getType(Uri uri) {
- switch (mUriMatcher.match(uri)) {
- case PUBLIC_KEY_RING:
- case PUBLIC_KEY_RING_BY_EMAILS:
- return PUBLIC_KEY_RING_CONTENT_DIR_TYPE;
-
- case PUBLIC_KEY_RING_ID:
- return PUBLIC_KEY_RING_CONTENT_ITEM_TYPE;
-
- case PUBLIC_KEY_RING_BY_KEY_ID:
- return PUBLIC_KEY_RING_CONTENT_ITEM_TYPE;
-
- case PUBLIC_KEY_RING_KEY:
- return PUBLIC_KEY_CONTENT_DIR_TYPE;
-
- case PUBLIC_KEY_RING_KEY_RANK:
- return PUBLIC_KEY_CONTENT_ITEM_TYPE;
-
- case PUBLIC_KEY_RING_USER_ID:
- return USER_ID_CONTENT_DIR_TYPE;
-
- case PUBLIC_KEY_RING_USER_ID_RANK:
- return USER_ID_CONTENT_ITEM_TYPE;
-
- case SECRET_KEY_RING:
- case SECRET_KEY_RING_BY_EMAILS:
- return SECRET_KEY_RING_CONTENT_DIR_TYPE;
-
- case SECRET_KEY_RING_ID:
- return SECRET_KEY_RING_CONTENT_ITEM_TYPE;
-
- case SECRET_KEY_RING_BY_KEY_ID:
- return SECRET_KEY_RING_CONTENT_ITEM_TYPE;
-
- case SECRET_KEY_RING_KEY:
- return SECRET_KEY_CONTENT_DIR_TYPE;
-
- case SECRET_KEY_RING_KEY_RANK:
- return SECRET_KEY_CONTENT_ITEM_TYPE;
-
- case SECRET_KEY_RING_USER_ID:
- return USER_ID_CONTENT_DIR_TYPE;
-
- case SECRET_KEY_RING_USER_ID_RANK:
- return USER_ID_CONTENT_ITEM_TYPE;
-
- default:
- throw new IllegalArgumentException("Unknown URI " + uri);
- }
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues initialValues) {
- // not supported
- return null;
- }
-
- @Override
- public int delete(Uri uri, String where, String[] whereArgs) {
- // not supported
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
- // not supported
- return 0;
- }
-
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- int match = mUriMatcher.match(uri);
- if (match != DATA_STREAM) {
- throw new FileNotFoundException();
- }
- String fileName = uri.getPathSegments().get(1);
- 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/Database.java b/org_apg/src/org/thialfihar/android/apg/provider/Database.java
deleted file mode 100644
index 0c14283c2..000000000
--- a/org_apg/src/org/thialfihar/android/apg/provider/Database.java
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * 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.
- */
-
-package org.thialfihar.android.apg.provider;
-
-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<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);
- }
-
- 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<Integer> seenIds = new Vector<Integer>();
- int rank = 0;
- for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(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<Integer> seenIds = new Vector<Integer>();
- int rank = 0;
- for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(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<Integer> seenIds = new Vector<Integer>();
- int userIdRank = 0;
- for (String userId : new IterableIterator<String>(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<Integer> seenIds = new Vector<Integer>();
- int userIdRank = 0;
- for (String userId : new IterableIterator<String>(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 });
-
- 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/provider/KeyRings.java b/org_apg/src/org/thialfihar/android/apg/provider/KeyRings.java
deleted file mode 100644
index 58e95eba6..000000000
--- a/org_apg/src/org/thialfihar/android/apg/provider/KeyRings.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * 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.
- */
-
-package org.thialfihar.android.apg.provider;
-
-import android.provider.BaseColumns;
-
-public class KeyRings implements BaseColumns {
- public static final String TABLE_NAME = "key_rings";
-
- public static final String _ID_type = "INTEGER PRIMARY KEY";
- public static final String MASTER_KEY_ID = "c_master_key_id";
- public static final String MASTER_KEY_ID_type = "INT64";
- public static final String TYPE = "c_type";
- public static final String TYPE_type = "INTEGER";
- public static final String WHO_ID = "c_who_id";
- public static final String WHO_ID_type = "INTEGER";
- public static final String KEY_RING_DATA = "c_key_ring_data";
- public static final String KEY_RING_DATA_type = "BLOB";
-}
diff --git a/org_apg/src/org/thialfihar/android/apg/provider/Keys.java b/org_apg/src/org/thialfihar/android/apg/provider/Keys.java
deleted file mode 100644
index 618c5e920..000000000
--- a/org_apg/src/org/thialfihar/android/apg/provider/Keys.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * 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.
- */
-
-package org.thialfihar.android.apg.provider;
-
-import android.provider.BaseColumns;
-
-public class Keys implements BaseColumns {
- public static final String TABLE_NAME = "keys";
-
- public static final String _ID_type = "INTEGER PRIMARY KEY";
- public static final String KEY_ID = "c_key_id";
- public static final String KEY_ID_type = "INT64";
- public static final String TYPE = "c_type";
- public static final String TYPE_type = "INTEGER";
- public static final String IS_MASTER_KEY = "c_is_master_key";
- public static final String IS_MASTER_KEY_type = "INTEGER";
- public static final String ALGORITHM = "c_algorithm";
- public static final String ALGORITHM_type = "INTEGER";
- public static final String KEY_SIZE = "c_key_size";
- public static final String KEY_SIZE_type = "INTEGER";
- public static final String CAN_SIGN = "c_can_sign";
- public static final String CAN_SIGN_type = "INTEGER";
- public static final String CAN_ENCRYPT = "c_can_encrypt";
- public static final String CAN_ENCRYPT_type = "INTEGER";
- public static final String IS_REVOKED = "c_is_revoked";
- public static final String IS_REVOKED_type = "INTEGER";
- public static final String CREATION = "c_creation";
- public static final String CREATION_type = "INTEGER";
- public static final String EXPIRY = "c_expiry";
- public static final String EXPIRY_type = "INTEGER";
- public static final String KEY_RING_ID = "c_key_ring_id";
- public static final String KEY_RING_ID_type = "INTEGER";
- public static final String KEY_DATA = "c_key_data";
- public static final String KEY_DATA_type = "BLOB";
- public static final String RANK = "c_key_data";
- public static final String RANK_type = "INTEGER";
-}
diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java b/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java
new file mode 100644
index 000000000..234f96bd0
--- /dev/null
+++ b/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java
@@ -0,0 +1,79 @@
+package org.thialfihar.android.apg.provider;
+
+import java.io.IOException;
+
+import org.spongycastle.openpgp.PGPPublicKey;
+import org.spongycastle.openpgp.PGPPublicKeyRing;
+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.SecretKeys;
+
+import android.content.ContentValues;
+import android.content.Context;
+
+public class ProviderHelper {
+ // public static void insertHostsSource(Context context, String url) {
+ // ContentValues values = new ContentValues();
+ // values.put(HostsSources.URL, url);
+ // values.put(HostsSources.ENABLED, true); // default is enabled
+ // values.put(HostsSources.LAST_MODIFIED_LOCAL, 0); // last_modified_local starts at 0
+ // values.put(HostsSources.LAST_MODIFIED_ONLINE, 0); // last_modified_onlinestarts at 0
+ // context.getContentResolver().insert(HostsSources.CONTENT_URI, values);
+ // }
+
+ // public int saveKeyRing(Context context, PGPPublicKeyRing keyRing) throws IOException,
+ // ApgGeneralException {
+ // // mDb.beginTransaction();
+ // ContentValues values = new ContentValues();
+ // PGPPublicKey masterKey = keyRing.getPublicKey();
+ // long masterKeyId = masterKey.getKeyID();
+ //
+ // values.put(PublicKeyRings.MASTER_KEY_ID, masterKeyId);
+ // // values.put(KeyRings.TYPE, Id.database.type_public);
+ // values.put(PublicKeyRings.KEY_RING_DATA, keyRing.getEncoded());
+ //
+ // context.getContentResolver().insert(PublicKeyRings.CONTENT_URI, values);
+ //
+ // long rowId = insertOrUpdateKeyRing(values);
+ // int returnValue = mStatus;
+ //
+ // if (rowId == -1) {
+ // throw new ApgGeneralException("saving public key ring " + masterKeyId + " failed");
+ // }
+ //
+ // Vector<Integer> seenIds = new Vector<Integer>();
+ // int rank = 0;
+ // for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(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;
+ // }
+
+ /**
+ * Deletes public and secret keys
+ *
+ * @param context
+ * @param rowId
+ */
+ public static void deleteKey(Context context, long rowId) {
+ context.getContentResolver().delete(PublicKeys.buildPublicKeysUri(Long.toString(rowId)),
+ null, null);
+ context.getContentResolver().delete(SecretKeys.buildSecretKeysUri(Long.toString(rowId)),
+ null, null);
+ }
+}
diff --git a/org_apg/src/org/thialfihar/android/apg/provider/UserIds.java b/org_apg/src/org/thialfihar/android/apg/provider/UserIds.java
deleted file mode 100644
index 2050ccf9c..000000000
--- a/org_apg/src/org/thialfihar/android/apg/provider/UserIds.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * 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.
- */
-
-package org.thialfihar.android.apg.provider;
-
-import android.provider.BaseColumns;
-
-public class UserIds implements BaseColumns {
- public static final String TABLE_NAME = "user_ids";
-
- public static final String _ID_type = "INTEGER PRIMARY KEY";
- public static final String KEY_ID = "c_key_id";
- public static final String KEY_ID_type = "INTEGER";
- public static final String USER_ID = "c_user_id";
- public static final String USER_ID_type = "TEXT";
- public static final String RANK = "c_rank";
- public static final String RANK_type = "INTEGER";
-}
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 dbb0900e3..c324c4c62 100644
--- a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java
+++ b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java
@@ -35,13 +35,15 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
+import org.thialfihar.android.apg.deprecated.DataProvider;
import org.thialfihar.android.apg.helper.FileHelper;
import org.thialfihar.android.apg.helper.OtherHelper;
import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences;
-import org.thialfihar.android.apg.helper.PGPMain.GeneralException;
+import org.thialfihar.android.apg.helper.PGPMain.ApgGeneralException;
import org.thialfihar.android.apg.helper.PGPConversionHelper;
-import org.thialfihar.android.apg.provider.DataProvider;
+import org.thialfihar.android.apg.provider.ApgContract.DataStream;
+import org.thialfihar.android.apg.provider.ApgProvider;
import org.thialfihar.android.apg.util.HkpKeyServer;
import org.thialfihar.android.apg.util.InputData;
import org.thialfihar.android.apg.util.KeyServer.KeyInfo;
@@ -271,7 +273,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// check if storage is ready
if (!FileHelper.isStorageMounted(inputFile)
|| !FileHelper.isStorageMounted(outputFile)) {
- sendErrorToHandler(new GeneralException(
+ sendErrorToHandler(new ApgGeneralException(
getString(R.string.error_externalStorageNotReady)));
return;
}
@@ -298,7 +300,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
while (true) {
streamFilename = PGPMain.generateRandomString(32);
if (streamFilename == null) {
- throw new PGPMain.GeneralException(
+ throw new PGPMain.ApgGeneralException(
"couldn't generate random file name");
}
openFileInput(streamFilename).close();
@@ -311,7 +313,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
break;
default:
- throw new PGPMain.GeneralException("No target choosen!");
+ throw new PGPMain.ApgGeneralException("No target choosen!");
}
@@ -372,7 +374,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
break;
case TARGET_STREAM:
- String uri = "content://" + DataProvider.AUTHORITY + "/data/" + streamFilename;
+ String uri = DataStream.buildDataStreamUri(streamFilename).toString();
resultData.putString(RESULT_URI, uri);
break;
@@ -422,7 +424,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// check if storage is ready
if (!FileHelper.isStorageMounted(inputFile)
|| !FileHelper.isStorageMounted(outputFile)) {
- sendErrorToHandler(new GeneralException(
+ sendErrorToHandler(new ApgGeneralException(
getString(R.string.error_externalStorageNotReady)));
return;
}
@@ -452,7 +454,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
while (true) {
streamFilename = PGPMain.generateRandomString(32);
if (streamFilename == null) {
- throw new PGPMain.GeneralException(
+ throw new PGPMain.ApgGeneralException(
"couldn't generate random file name");
}
openFileInput(streamFilename).close();
@@ -465,7 +467,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
break;
default:
- throw new PGPMain.GeneralException("No target choosen!");
+ throw new PGPMain.ApgGeneralException("No target choosen!");
}
@@ -505,7 +507,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
break;
case TARGET_STREAM:
- String uri = "content://" + DataProvider.AUTHORITY + "/data/" + streamFilename;
+ String uri = DataStream.buildDataStreamUri(streamFilename).toString();
resultData.putString(RESULT_URI, uri);
break;
@@ -617,10 +619,10 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
try {
PGPMain.deleteFileSecurely(this, new File(deleteFile), this);
} catch (FileNotFoundException e) {
- throw new PGPMain.GeneralException(getString(R.string.error_fileNotFound,
+ throw new PGPMain.ApgGeneralException(getString(R.string.error_fileNotFound,
deleteFile));
} catch (IOException e) {
- throw new PGPMain.GeneralException(getString(R.string.error_fileDeleteFailed,
+ throw new PGPMain.ApgGeneralException(getString(R.string.error_fileDeleteFailed,
deleteFile));
}
@@ -703,7 +705,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// check if storage is ready
if (!FileHelper.isStorageMounted(outputFile)) {
- sendErrorToHandler(new GeneralException(
+ sendErrorToHandler(new ApgGeneralException(
getString(R.string.error_externalStorageNotReady)));
return;
}
@@ -745,7 +747,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
boolean uploaded = PGPMain.uploadKeyRingToServer(server,
(PGPPublicKeyRing) keyring);
if (!uploaded) {
- sendErrorToHandler(new GeneralException(
+ sendErrorToHandler(new ApgGeneralException(
"Unable to export key to selected server"));
return;
}
@@ -806,7 +808,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// store the signed key in our local cache
int retval = PGPMain.storeKeyRingInCache(signedPubKeyRing);
if (retval != Id.return_value.ok && retval != Id.return_value.updated) {
- throw new GeneralException("Failed to store signed key in local cache");
+ throw new ApgGeneralException("Failed to store signed key in local cache");
}
sendMessageToHandler(ApgServiceHandler.MESSAGE_OKAY);
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 c41400f5a..7e7344c4e 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -607,7 +608,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
messenger, mSecretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
- } catch (PGPMain.GeneralException e) {
+ } catch (PGPMain.ApgGeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
// send message to handler to start encryption directly
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
@@ -654,13 +655,13 @@ public class DecryptActivity extends SherlockFragmentActivity {
try {
setSecretKeyId(PGPMain.getDecryptionKeyId(this, inStream));
if (getSecretKeyId() == Id.key.none) {
- throw new PGPMain.GeneralException(getString(R.string.error_noSecretKeyFound));
+ throw new PGPMain.ApgGeneralException(getString(R.string.error_noSecretKeyFound));
}
mAssumeSymmetricEncryption = false;
} catch (PGPMain.NoAsymmetricEncryptionException e) {
setSecretKeyId(Id.key.symmetric);
if (!PGPMain.hasSymmetricEncryption(this, inStream)) {
- throw new PGPMain.GeneralException(
+ throw new PGPMain.ApgGeneralException(
getString(R.string.error_noKnownEncryptionFound));
}
mAssumeSymmetricEncryption = true;
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 60b108541..0d15014b7 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java
@@ -407,7 +407,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
private void saveClicked() {
try {
if (!isPassphraseSet()) {
- throw new PGPMain.GeneralException(this.getString(R.string.setAPassPhrase));
+ throw new PGPMain.ApgGeneralException(this.getString(R.string.setAPassPhrase));
}
// Send all information needed to service to edit key in other thread
@@ -448,7 +448,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
// start service with intent
startService(intent);
- } catch (PGPMain.GeneralException e) {
+ } catch (PGPMain.ApgGeneralException e) {
Toast.makeText(this, getString(R.string.errorMessage, e.getMessage()),
Toast.LENGTH_SHORT).show();
}
@@ -460,7 +460,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param userIdsView
* @return
*/
- private ArrayList<String> getUserIds(SectionView userIdsView) throws PGPMain.GeneralException {
+ private ArrayList<String> getUserIds(SectionView userIdsView) throws PGPMain.ApgGeneralException {
ArrayList<String> userIds = new ArrayList<String>();
ViewGroup userIdEditors = userIdsView.getEditors();
@@ -472,12 +472,12 @@ public class EditKeyActivity extends SherlockFragmentActivity {
try {
userId = editor.getValue();
} catch (UserIdEditor.NoNameException e) {
- throw new PGPMain.GeneralException(this.getString(R.string.error_userIdNeedsAName));
+ throw new PGPMain.ApgGeneralException(this.getString(R.string.error_userIdNeedsAName));
} catch (UserIdEditor.NoEmailException e) {
- throw new PGPMain.GeneralException(
+ throw new PGPMain.ApgGeneralException(
this.getString(R.string.error_userIdNeedsAnEmailAddress));
} catch (UserIdEditor.InvalidEmailException e) {
- throw new PGPMain.GeneralException(e.getMessage());
+ throw new PGPMain.ApgGeneralException(e.getMessage());
}
if (userId.equals("")) {
@@ -493,11 +493,11 @@ public class EditKeyActivity extends SherlockFragmentActivity {
}
if (userIds.size() == 0) {
- throw new PGPMain.GeneralException(getString(R.string.error_keyNeedsAUserId));
+ throw new PGPMain.ApgGeneralException(getString(R.string.error_keyNeedsAUserId));
}
if (!gotMainUserId) {
- throw new PGPMain.GeneralException(getString(R.string.error_mainUserIdMustNotBeEmpty));
+ throw new PGPMain.ApgGeneralException(getString(R.string.error_mainUserIdMustNotBeEmpty));
}
return userIds;
@@ -509,13 +509,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param keysView
* @return
*/
- private ArrayList<PGPSecretKey> getKeys(SectionView keysView) throws PGPMain.GeneralException {
+ private ArrayList<PGPSecretKey> getKeys(SectionView keysView) throws PGPMain.ApgGeneralException {
ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
- throw new PGPMain.GeneralException(getString(R.string.error_keyNeedsMasterKey));
+ throw new PGPMain.ApgGeneralException(getString(R.string.error_keyNeedsMasterKey));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
@@ -532,13 +532,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param keysView
* @return
*/
- private ArrayList<Integer> getKeysUsages(SectionView keysView) throws PGPMain.GeneralException {
+ private ArrayList<Integer> getKeysUsages(SectionView keysView) throws PGPMain.ApgGeneralException {
ArrayList<Integer> getKeysUsages = new ArrayList<Integer>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
- throw new PGPMain.GeneralException(getString(R.string.error_keyNeedsMasterKey));
+ throw new PGPMain.ApgGeneralException(getString(R.string.error_keyNeedsMasterKey));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
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 0ed45d7f4..dfdfe4d5c 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java
@@ -732,7 +732,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
EncryptActivity.this, messenger, mSecretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
- } catch (PGPMain.GeneralException e) {
+ } catch (PGPMain.ApgGeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
// send message to handler to start encryption directly
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java
index de799e2ac..c06c68943 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java
@@ -169,7 +169,7 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
SecretKeyListActivity.this, messenger, secretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
- } catch (PGPMain.GeneralException e) {
+ } catch (PGPMain.ApgGeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
// send message to handler to start encryption directly
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
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 2fa0e9c96..3311c320e 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java
@@ -143,7 +143,7 @@ public class SignKeyActivity extends SherlockFragmentActivity {
messenger, secretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
- } catch (PGPMain.GeneralException e) {
+ } catch (PGPMain.ApgGeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
// send message to handler to start encryption directly
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
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 e8ef76e50..230423715 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
@@ -23,7 +23,7 @@ import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.thialfihar.android.apg.helper.PGPHelper;
import org.thialfihar.android.apg.helper.PGPMain;
-import org.thialfihar.android.apg.helper.PGPMain.GeneralException;
+import org.thialfihar.android.apg.helper.PGPMain.ApgGeneralException;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
@@ -73,14 +73,14 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
* @param messenger
* to communicate back after caching the passphrase
* @return
- * @throws GeneralException
+ * @throws ApgGeneralException
*/
public static PassphraseDialogFragment newInstance(Context context, Messenger messenger,
- long secretKeyId) throws GeneralException {
+ long secretKeyId) throws ApgGeneralException {
// check if secret key has a passphrase
if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) {
if (!hasPassphrase(context, secretKeyId)) {
- throw new PGPMain.GeneralException("No passphrase! No passphrase dialog needed!");
+ throw new PGPMain.ApgGeneralException("No passphrase! No passphrase dialog needed!");
}
}
diff --git a/org_apg/src/org/thialfihar/android/apg/util/Compatibility.java b/org_apg/src/org/thialfihar/android/apg/util/Compatibility.java
index e984362c3..1597a01f4 100644
--- a/org_apg/src/org/thialfihar/android/apg/util/Compatibility.java
+++ b/org_apg/src/org/thialfihar/android/apg/util/Compatibility.java
@@ -26,8 +26,7 @@ public class Compatibility {
private static final String clipboardLabel = "APG";
/**
- * Wrapper around ClipboardManager based on Android version using Reflection API, from
- * http://www.projectsexception.com/blog/?p=87
+ * Wrapper around ClipboardManager based on Android version using Reflection API
*
* @param context
* @param text