mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-12-24 07:58:50 -05:00
started restructuring APGs Provider and Database
This commit is contained in:
parent
a507204b9e
commit
fb49f9e9c8
@ -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" />
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
// }
|
||||
//}
|
617
org_apg/src/org/thialfihar/android/apg/deprecated/Database.java
Normal file
617
org_apg/src/org/thialfihar/android/apg/deprecated/Database.java
Normal file
@ -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;
|
||||
// }
|
||||
//}
|
@ -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 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 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;
|
||||
|
235
org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java
Normal file
235
org_apg/src/org/thialfihar/android/apg/provider/ApgContract.java
Normal file
@ -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() {
|
||||
}
|
||||
}
|
143
org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java
Normal file
143
org_apg/src/org/thialfihar/android/apg/provider/ApgDatabase.java
Normal file
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
589
org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java
Normal file
589
org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
@ -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";
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user