Merge pull request #2167 from open-keychain/ditch-consolidate
Ditch "consolidate" mechanism
This commit is contained in:
@@ -96,7 +96,7 @@ public class TestHelpers {
|
||||
IteratorWithIOThrow<UncachedKeyRing> stream = UncachedKeyRing.fromStream(
|
||||
getInstrumentation().getContext().getAssets().open(name));
|
||||
|
||||
KeyWritableRepository helper = KeyWritableRepository.createDatabaseReadWriteInteractor(context);
|
||||
KeyWritableRepository helper = KeyWritableRepository.create(context);
|
||||
while(stream.hasNext()) {
|
||||
UncachedKeyRing ring = stream.next();
|
||||
if (ring.isSecret()) {
|
||||
|
||||
@@ -37,7 +37,7 @@ public abstract class CustomActions {
|
||||
|
||||
public static ViewAction tokenEncryptViewAddToken(long keyId) throws Exception {
|
||||
CanonicalizedPublicKeyRing ring =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(getTargetContext()).getCanonicalizedPublicKeyRing(keyId);
|
||||
KeyWritableRepository.create(getTargetContext()).getCanonicalizedPublicKeyRing(keyId);
|
||||
final Object item = new KeyAdapter.KeyItem(ring);
|
||||
|
||||
return new ViewAction() {
|
||||
|
||||
@@ -772,9 +772,6 @@
|
||||
android:name=".ui.LogDisplayActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||
android:label="@string/title_log_display" />
|
||||
<activity
|
||||
android:name=".ui.ConsolidateDialogActivity"
|
||||
android:theme="@style/Theme.Keychain.Transparent" />
|
||||
<activity
|
||||
android:name=".ui.PassphraseDialogActivity"
|
||||
android:theme="@style/Theme.Keychain.Transparent" />
|
||||
|
||||
@@ -146,6 +146,8 @@ public final class Constants {
|
||||
public static final String EXPERIMENTAL_SMARTPGP_VERIFY_AUTHORITY = "smartpgp_authorities_pref";
|
||||
public static final String EXPERIMENTAL_SMARTPGP_AUTHORITIES = "smartpgp_authorities";
|
||||
|
||||
public static final String KEY_SIGNATURES_TABLE_INITIALIZED = "key_signatures_table_initialized";
|
||||
|
||||
public static final class Theme {
|
||||
public static final String LIGHT = "light";
|
||||
public static final String DARK = "dark";
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
|
||||
package org.sufficientlysecure.keychain;
|
||||
|
||||
|
||||
import java.security.Security;
|
||||
import java.util.HashMap;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -31,19 +34,15 @@ import android.support.annotation.Nullable;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.sufficientlysecure.keychain.network.TlsCertificatePinning;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
||||
import org.sufficientlysecure.keychain.provider.TemporaryFileProvider;
|
||||
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
|
||||
import org.sufficientlysecure.keychain.service.KeyserverSyncAdapterService;
|
||||
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
|
||||
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.PRNGFixes;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
import org.sufficientlysecure.keychain.network.TlsCertificatePinning;
|
||||
|
||||
import java.security.Security;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class KeychainApplication extends Application {
|
||||
@@ -119,11 +118,6 @@ public class KeychainApplication extends Application {
|
||||
TlsCertificatePinning.addPinnedCertificate("api.keybase.io", getAssets(), "api.keybase.io.CA.cer");
|
||||
|
||||
TemporaryFileProvider.cleanUp(this);
|
||||
|
||||
if (!checkConsolidateRecovery()) {
|
||||
// force DB upgrade, https://github.com/open-keychain/open-keychain/issues/1334
|
||||
new KeychainDatabase(this).getReadableDatabase().close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,21 +158,6 @@ public class KeychainApplication extends Application {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart consolidate process if it has been interrupted before
|
||||
*/
|
||||
public boolean checkConsolidateRecovery() {
|
||||
if (Preferences.getPreferences(this).getCachedConsolidate()) {
|
||||
Intent consolidateIntent = new Intent(this, ConsolidateDialogActivity.class);
|
||||
consolidateIntent.putExtra(ConsolidateDialogActivity.EXTRA_CONSOLIDATE_RECOVERY, true);
|
||||
consolidateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(consolidateIntent);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void brandGlowEffect(Context context, int brandColor) {
|
||||
// no hack on Android 5
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
|
||||
* Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.operations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
|
||||
import org.sufficientlysecure.keychain.service.ConsolidateInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
|
||||
public class ConsolidateOperation extends BaseReadWriteOperation<ConsolidateInputParcel> {
|
||||
|
||||
public ConsolidateOperation(Context context, KeyWritableRepository databaseInteractor, Progressable
|
||||
progressable) {
|
||||
super(context, databaseInteractor, progressable);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ConsolidateResult execute(ConsolidateInputParcel consolidateInputParcel,
|
||||
CryptoInputParcel cryptoInputParcel) {
|
||||
if (consolidateInputParcel.isStartFromRecovery()) {
|
||||
return mKeyWritableRepository.consolidateDatabaseStep2(mProgressable);
|
||||
} else {
|
||||
return mKeyWritableRepository.consolidateDatabaseStep1(mProgressable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,15 +18,17 @@
|
||||
package org.sufficientlysecure.keychain.operations;
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.sufficientlysecure.keychain.BuildConfig;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.DeleteResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.operations.results.UpdateTrustResult;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
|
||||
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
|
||||
@@ -92,10 +94,10 @@ public class DeleteOperation extends BaseReadWriteOperation<DeleteKeyringParcel>
|
||||
}
|
||||
}
|
||||
|
||||
if (!BuildConfig.DEBUG && isSecret && success > 0) {
|
||||
log.add(LogType.MSG_DEL_CONSOLIDATE, 1);
|
||||
ConsolidateResult sub = mKeyWritableRepository.consolidateDatabaseStep1(mProgressable);
|
||||
log.add(sub, 2);
|
||||
if (isSecret && success > 0) {
|
||||
UpdateTrustResult sub = mKeyWritableRepository.updateTrustDb(
|
||||
Collections.singletonList(masterKeyIds[0]), mProgressable);
|
||||
log.add(sub, 1);
|
||||
}
|
||||
|
||||
int result = DeleteResult.RESULT_OK;
|
||||
|
||||
@@ -39,19 +39,19 @@ import android.support.annotation.Nullable;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.FacebookKeyserverClient;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverClient;
|
||||
import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserverClient;
|
||||
import org.sufficientlysecure.keychain.keyimport.KeyserverClient;
|
||||
import org.sufficientlysecure.keychain.keyimport.KeyserverClient.QueryNotFoundException;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.network.orbot.OrbotHelper;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.UpdateTrustResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
@@ -155,7 +155,8 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
|
||||
return new ImportKeyResult(ImportKeyResult.RESULT_FAIL_NOTHING, log);
|
||||
}
|
||||
|
||||
int newKeys = 0, updatedKeys = 0, missingKeys = 0, badKeys = 0, secret = 0;
|
||||
int newKeys = 0, updatedKeys = 0, missingKeys = 0, badKeys = 0;
|
||||
ArrayList<Long> secretMasterKeyIds = new ArrayList<>();
|
||||
ArrayList<Long> importedMasterKeyIds = new ArrayList<>();
|
||||
|
||||
ArrayList<CanonicalizedKeyRing> canKeyRings = new ArrayList<>();
|
||||
@@ -223,7 +224,8 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
|
||||
if (key.isSecret()) {
|
||||
result = mKeyWritableRepository.saveSecretKeyRing(key, canKeyRings, skipSave);
|
||||
} else {
|
||||
result = mKeyWritableRepository.savePublicKeyRing(key, entry.getExpectedFingerprint(), canKeyRings, skipSave);
|
||||
result = mKeyWritableRepository.savePublicKeyRing(key, entry.getExpectedFingerprint(), canKeyRings,
|
||||
false, skipSave);
|
||||
}
|
||||
}
|
||||
if (!result.success()) {
|
||||
@@ -235,7 +237,7 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
|
||||
} else {
|
||||
newKeys += 1;
|
||||
if (key.isSecret()) {
|
||||
secret += 1;
|
||||
secretMasterKeyIds.add(key.getMasterKeyId());
|
||||
}
|
||||
importedMasterKeyIds.add(key.getMasterKeyId());
|
||||
}
|
||||
@@ -260,13 +262,12 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
|
||||
// synchronized on mProviderHelper to prevent
|
||||
// https://github.com/open-keychain/open-keychain/issues/1221 since a consolidate deletes
|
||||
// and re-inserts keys, which could conflict with a parallel db key update
|
||||
if (!skipSave && (secret > 0)) {
|
||||
if (!skipSave && !secretMasterKeyIds.isEmpty()) {
|
||||
setPreventCancel();
|
||||
ConsolidateResult result;
|
||||
synchronized (mKeyRepository) {
|
||||
result = mKeyWritableRepository.consolidateDatabaseStep1(progressable);
|
||||
UpdateTrustResult result = mKeyWritableRepository.updateTrustDb(secretMasterKeyIds, progressable);
|
||||
log.add(result, 1);
|
||||
}
|
||||
log.add(result, 1);
|
||||
}
|
||||
|
||||
// Special: make sure new data is synced into contacts
|
||||
@@ -320,7 +321,8 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
|
||||
}
|
||||
|
||||
ImportKeyResult result = new ImportKeyResult(
|
||||
resultType, log, newKeys, updatedKeys, missingKeys, badKeys, secret, importedMasterKeyIdsArray);
|
||||
resultType, log, newKeys, updatedKeys, missingKeys, badKeys, secretMasterKeyIds.size(),
|
||||
importedMasterKeyIdsArray);
|
||||
|
||||
result.setCanonicalizedKeyRings(canKeyRings);
|
||||
return result;
|
||||
|
||||
@@ -598,32 +598,6 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_MF_UNLOCK_ERROR (LogLevel.ERROR, R.string.msg_mf_unlock_error),
|
||||
MSG_MF_UNLOCK (LogLevel.DEBUG, R.string.msg_mf_unlock),
|
||||
|
||||
// consolidate
|
||||
MSG_CON_CRITICAL_IN (LogLevel.DEBUG, R.string.msg_con_critical_in),
|
||||
MSG_CON_CRITICAL_OUT (LogLevel.DEBUG, R.string.msg_con_critical_out),
|
||||
MSG_CON_DB_CLEAR (LogLevel.DEBUG, R.string.msg_con_db_clear),
|
||||
MSG_CON_DELETE_PUBLIC (LogLevel.DEBUG, R.string.msg_con_delete_public),
|
||||
MSG_CON_DELETE_SECRET (LogLevel.DEBUG, R.string.msg_con_delete_secret),
|
||||
MSG_CON_ERROR_BAD_STATE (LogLevel.ERROR, R.string.msg_con_error_bad_state),
|
||||
MSG_CON_ERROR_CONCURRENT(LogLevel.ERROR, R.string.msg_con_error_concurrent),
|
||||
MSG_CON_ERROR_DB (LogLevel.ERROR, R.string.msg_con_error_db),
|
||||
MSG_CON_ERROR_IO_PUBLIC (LogLevel.ERROR, R.string.msg_con_error_io_public),
|
||||
MSG_CON_ERROR_IO_SECRET (LogLevel.ERROR, R.string.msg_con_error_io_secret),
|
||||
MSG_CON_ERROR_PUBLIC (LogLevel.ERROR, R.string.msg_con_error_public),
|
||||
MSG_CON_ERROR_SECRET (LogLevel.ERROR, R.string.msg_con_error_secret),
|
||||
MSG_CON_RECOVER (LogLevel.DEBUG, R.string.msg_con_recover),
|
||||
MSG_CON_RECURSIVE (LogLevel.OK, R.string.msg_con_recursive),
|
||||
MSG_CON_REIMPORT_PUBLIC (LogLevel.DEBUG, R.plurals.msg_con_reimport_public),
|
||||
MSG_CON_REIMPORT_PUBLIC_SKIP (LogLevel.DEBUG, R.string.msg_con_reimport_public_skip),
|
||||
MSG_CON_REIMPORT_SECRET (LogLevel.DEBUG, R.plurals.msg_con_reimport_secret),
|
||||
MSG_CON_REIMPORT_SECRET_SKIP (LogLevel.DEBUG, R.string.msg_con_reimport_secret_skip),
|
||||
MSG_CON (LogLevel.START, R.string.msg_con),
|
||||
MSG_CON_SAVE_PUBLIC (LogLevel.DEBUG, R.string.msg_con_save_public),
|
||||
MSG_CON_SAVE_SECRET (LogLevel.DEBUG, R.string.msg_con_save_secret),
|
||||
MSG_CON_SUCCESS (LogLevel.OK, R.string.msg_con_success),
|
||||
MSG_CON_WARN_DELETE_PUBLIC (LogLevel.WARN, R.string.msg_con_warn_delete_public),
|
||||
MSG_CON_WARN_DELETE_SECRET (LogLevel.WARN, R.string.msg_con_warn_delete_secret),
|
||||
|
||||
// edit key (higher level operation than modify)
|
||||
MSG_ED (LogLevel.START, R.string.msg_ed),
|
||||
MSG_ED_CACHING_NEW (LogLevel.DEBUG, R.string.msg_ed_caching_new),
|
||||
@@ -824,9 +798,8 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_DEL_ERROR_EMPTY (LogLevel.ERROR, R.string.msg_del_error_empty),
|
||||
MSG_DEL_ERROR_MULTI_SECRET (LogLevel.ERROR, R.string.msg_del_error_multi_secret),
|
||||
MSG_DEL (LogLevel.START, R.plurals.msg_del),
|
||||
MSG_DEL_KEY (LogLevel.DEBUG, R.string.msg_del_key),
|
||||
MSG_DEL_KEY (LogLevel.INFO, R.string.msg_del_key),
|
||||
MSG_DEL_KEY_FAIL (LogLevel.WARN, R.string.msg_del_key_fail),
|
||||
MSG_DEL_CONSOLIDATE (LogLevel.DEBUG, R.string.msg_del_consolidate),
|
||||
MSG_DEL_OK (LogLevel.OK, R.plurals.msg_del_ok),
|
||||
MSG_DEL_FAIL (LogLevel.WARN, R.plurals.msg_del_fail),
|
||||
|
||||
@@ -936,6 +909,12 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_RET_URI_NULL (LogLevel.ERROR, R.string.msg_ret_uri_null),
|
||||
MSG_RET_URI_TEST (LogLevel.DEBUG, R.string.msg_ret_uri_test),
|
||||
|
||||
MSG_TRUST (LogLevel.START, R.string.msg_trust),
|
||||
MSG_TRUST_OK (LogLevel.OK, R.string.msg_trust_ok),
|
||||
MSG_TRUST_KEY (LogLevel.INFO, R.string.msg_trust_key),
|
||||
MSG_TRUST_INITIALIZE (LogLevel.INFO, R.string.msg_trust_initialize),
|
||||
MSG_TRUST_COUNT_NONE (LogLevel.DEBUG, R.string.msg_trust_count_none),
|
||||
MSG_TRUST_COUNT (LogLevel.DEBUG, R.plurals.msg_trust_count);
|
||||
;
|
||||
|
||||
public final int mMsgId;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.operations.results;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
|
||||
public class UpdateTrustResult extends OperationResult {
|
||||
|
||||
public UpdateTrustResult(int result, OperationLog log) {
|
||||
super(result, log);
|
||||
}
|
||||
|
||||
/** Construct from a parcel - trivial because we have no extra data. */
|
||||
public UpdateTrustResult(Parcel source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
}
|
||||
|
||||
public static Creator<UpdateTrustResult> CREATOR = new Creator<UpdateTrustResult>() {
|
||||
public UpdateTrustResult createFromParcel(final Parcel source) {
|
||||
return new UpdateTrustResult(source);
|
||||
}
|
||||
|
||||
public UpdateTrustResult[] newArray(final int size) {
|
||||
return new UpdateTrustResult[size];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public class KeyRepository {
|
||||
OperationLog mLog;
|
||||
int mIndent;
|
||||
|
||||
public static KeyRepository createDatabaseInteractor(Context context) {
|
||||
public static KeyRepository create(Context context) {
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
LocalPublicKeyStorage localPublicKeyStorage = LocalPublicKeyStorage.getInstance(context);
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.ContentProviderOperation;
|
||||
@@ -42,13 +41,10 @@ import android.support.v4.util.LongSparseArray;
|
||||
import org.openintents.openpgp.util.OpenPgpUtils;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.ImportOperation;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.UpdateTrustResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
@@ -66,16 +62,14 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAutocryptPee
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeySignatures;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||
import org.sufficientlysecure.keychain.util.IteratorWithSize;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
|
||||
import org.sufficientlysecure.keychain.util.Utf8Util;
|
||||
|
||||
/**
|
||||
@@ -93,7 +87,7 @@ public class KeyWritableRepository extends KeyRepository {
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
public static KeyWritableRepository createDatabaseReadWriteInteractor(Context context) {
|
||||
public static KeyWritableRepository create(Context context) {
|
||||
LocalPublicKeyStorage localPublicKeyStorage = LocalPublicKeyStorage.getInstance(context);
|
||||
|
||||
return new KeyWritableRepository(context, localPublicKeyStorage);
|
||||
@@ -279,6 +273,8 @@ public class KeyWritableRepository extends KeyRepository {
|
||||
// otherwise the order in the keyfile is preserved.
|
||||
List<UserPacketItem> uids = new ArrayList<>();
|
||||
|
||||
List<Long> signerKeyIds = new ArrayList<>();
|
||||
|
||||
if (trustedKeys.size() == 0) {
|
||||
log(LogType.MSG_IP_UID_CLASSIFYING_ZERO);
|
||||
} else {
|
||||
@@ -320,6 +316,13 @@ public class KeyWritableRepository extends KeyRepository {
|
||||
|
||||
// do we have a trusted key for this?
|
||||
if (trustedKeys.indexOfKey(certId) < 0) {
|
||||
if (!signerKeyIds.contains(certId)) {
|
||||
operations.add(ContentProviderOperation.newInsert(KeySignatures.CONTENT_URI)
|
||||
.withValue(KeySignatures.MASTER_KEY_ID, masterKeyId)
|
||||
.withValue(KeySignatures.SIGNER_KEY_ID, certId)
|
||||
.build());
|
||||
signerKeyIds.add(certId);
|
||||
}
|
||||
unknownCerts += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -744,9 +747,10 @@ public class KeyWritableRepository extends KeyRepository {
|
||||
* If you want to merge keys in-memory only and not save in database set skipSave=true.
|
||||
*/
|
||||
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing publicRing,
|
||||
byte[] expectedFingerprint,
|
||||
ArrayList<CanonicalizedKeyRing> canKeyRings,
|
||||
boolean skipSave) {
|
||||
byte[] expectedFingerprint,
|
||||
ArrayList<CanonicalizedKeyRing> canKeyRings,
|
||||
boolean forceRefresh,
|
||||
boolean skipSave) {
|
||||
|
||||
try {
|
||||
long masterKeyId = publicRing.getMasterKeyId();
|
||||
@@ -783,7 +787,7 @@ public class KeyWritableRepository extends KeyRepository {
|
||||
if (canKeyRings != null) canKeyRings.add(canPublicRing);
|
||||
|
||||
// Early breakout if nothing changed
|
||||
if (Arrays.hashCode(publicRing.getEncoded())
|
||||
if (!forceRefresh && Arrays.hashCode(publicRing.getEncoded())
|
||||
== Arrays.hashCode(oldPublicRing.getEncoded())) {
|
||||
log(LogType.MSG_IP_SUCCESS_IDENTICAL);
|
||||
return new SaveKeyringResult(SaveKeyringResult.UPDATED, mLog, null);
|
||||
@@ -867,11 +871,20 @@ public class KeyWritableRepository extends KeyRepository {
|
||||
}
|
||||
|
||||
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing publicRing, byte[] expectedFingerprint) {
|
||||
return savePublicKeyRing(publicRing, expectedFingerprint, null, false);
|
||||
return savePublicKeyRing(publicRing, expectedFingerprint, null, false, false);
|
||||
}
|
||||
|
||||
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing publicRing, byte[] expectedFingerprint,
|
||||
boolean forceRefresh) {
|
||||
return savePublicKeyRing(publicRing, expectedFingerprint, null, forceRefresh, false);
|
||||
}
|
||||
|
||||
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing keyRing) {
|
||||
return savePublicKeyRing(keyRing, null);
|
||||
return savePublicKeyRing(keyRing, null, false);
|
||||
}
|
||||
|
||||
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing keyRing, boolean forceRefresh) {
|
||||
return savePublicKeyRing(keyRing, null, forceRefresh);
|
||||
}
|
||||
|
||||
public SaveKeyringResult saveSecretKeyRing(UncachedKeyRing secretRing,
|
||||
@@ -1004,332 +1017,72 @@ public class KeyWritableRepository extends KeyRepository {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ConsolidateResult consolidateDatabaseStep1(Progressable progress) {
|
||||
|
||||
public UpdateTrustResult updateTrustDb(List<Long> signerMasterKeyIds, Progressable progress) {
|
||||
OperationLog log = new OperationLog();
|
||||
int indent = 0;
|
||||
|
||||
// 1a. fetch all secret keyrings into a cache file
|
||||
log.add(LogType.MSG_CON, indent);
|
||||
indent += 1;
|
||||
log.add(LogType.MSG_TRUST, 0);
|
||||
|
||||
if (mConsolidateCritical) {
|
||||
log.add(LogType.MSG_CON_RECURSIVE, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_OK, log);
|
||||
}
|
||||
|
||||
progress.setProgress(R.string.progress_con_saving, 0, 100);
|
||||
|
||||
// The consolidate operation can never be cancelled!
|
||||
progress.setPreventCancel();
|
||||
|
||||
try {
|
||||
|
||||
log.add(LogType.MSG_CON_SAVE_SECRET, indent);
|
||||
indent += 1;
|
||||
|
||||
final Cursor cursor = mContentResolver.query(KeyRingData.buildSecretKeyRingUri(),
|
||||
new String[]{KeyRingData.KEY_RING_DATA}, null, null, null);
|
||||
|
||||
if (cursor == null) {
|
||||
log.add(LogType.MSG_CON_ERROR_DB, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
|
||||
Cursor cursor;
|
||||
Preferences preferences = Preferences.getPreferences(mContext);
|
||||
boolean isTrustDbInitialized = preferences.isKeySignaturesTableInitialized();
|
||||
if (!isTrustDbInitialized) {
|
||||
log.add(LogType.MSG_TRUST_INITIALIZE, 1);
|
||||
cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(),
|
||||
new String[] { KeyRings.MASTER_KEY_ID }, null, null, null);
|
||||
} else {
|
||||
String[] signerMasterKeyIdStrings = new String[signerMasterKeyIds.size()];
|
||||
int i = 0;
|
||||
for (Long masterKeyId : signerMasterKeyIds) {
|
||||
log.add(LogType.MSG_TRUST_KEY, 1, KeyFormattingUtils.beautifyKeyId(masterKeyId));
|
||||
signerMasterKeyIdStrings[i++] = Long.toString(masterKeyId);
|
||||
}
|
||||
|
||||
// No keys existing might be a legitimate option, we write an empty file in that case
|
||||
cursor.moveToFirst();
|
||||
ParcelableFileCache<ParcelableKeyRing> cache =
|
||||
new ParcelableFileCache<>(mContext, "consolidate_secret.pcl");
|
||||
cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() {
|
||||
ParcelableKeyRing ring;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (ring != null) {
|
||||
return true;
|
||||
}
|
||||
if (cursor.isAfterLast()) {
|
||||
return false;
|
||||
}
|
||||
ring = ParcelableKeyRing.createFromEncodedBytes(cursor.getBlob(0));
|
||||
cursor.moveToNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableKeyRing next() {
|
||||
try {
|
||||
return ring;
|
||||
} finally {
|
||||
ring = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
});
|
||||
cursor.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "error saving secret", e);
|
||||
log.add(LogType.MSG_CON_ERROR_IO_SECRET, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
|
||||
} finally {
|
||||
indent -= 1;
|
||||
cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsFilterBySigner(),
|
||||
new String[] { KeyRings.MASTER_KEY_ID }, null, signerMasterKeyIdStrings, null);
|
||||
}
|
||||
|
||||
progress.setProgress(R.string.progress_con_saving, 3, 100);
|
||||
if (cursor == null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
int totalKeys = cursor.getCount();
|
||||
int processedKeys = 0;
|
||||
|
||||
if (totalKeys == 0) {
|
||||
log.add(LogType.MSG_TRUST_COUNT_NONE, 1);
|
||||
} else {
|
||||
progress.setProgress(R.string.progress_update_trust, 0, totalKeys);
|
||||
log.add(LogType.MSG_TRUST_COUNT, 1, totalKeys);
|
||||
}
|
||||
|
||||
// 1b. fetch all public keyrings into a cache file
|
||||
try {
|
||||
|
||||
log.add(LogType.MSG_CON_SAVE_PUBLIC, indent);
|
||||
indent += 1;
|
||||
|
||||
final Cursor cursor = mContentResolver.query(
|
||||
KeyRingData.buildPublicKeyRingUri(),
|
||||
new String[]{KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA}, null, null, null);
|
||||
|
||||
if (cursor == null) {
|
||||
log.add(LogType.MSG_CON_ERROR_DB, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
|
||||
}
|
||||
|
||||
// No keys existing might be a legitimate option, we write an empty file in that case
|
||||
cursor.moveToFirst();
|
||||
ParcelableFileCache<ParcelableKeyRing> cache =
|
||||
new ParcelableFileCache<>(mContext, "consolidate_public.pcl");
|
||||
cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() {
|
||||
ParcelableKeyRing ring;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (ring != null) {
|
||||
return true;
|
||||
}
|
||||
if (cursor.isAfterLast()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
long masterKeyId = cursor.getLong(0);
|
||||
byte[] keyBytes = cursor.getBlob(1);
|
||||
if (keyBytes == null) {
|
||||
try {
|
||||
keyBytes = mLocalPublicKeyStorage.readPublicKey(masterKeyId);
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "Failed reading key data!", e);
|
||||
}
|
||||
}
|
||||
if (keyBytes == null) {
|
||||
throw new IllegalStateException("Lost a key! This should never happen!");
|
||||
}
|
||||
|
||||
ring = ParcelableKeyRing.createFromEncodedBytes(keyBytes);
|
||||
cursor.moveToNext();
|
||||
return true;
|
||||
byte[] pubKeyData = loadPublicKeyRingData(masterKeyId);
|
||||
UncachedKeyRing uncachedKeyRing = UncachedKeyRing.decodeFromData(pubKeyData);
|
||||
|
||||
clearLog();
|
||||
SaveKeyringResult result = savePublicKeyRing(uncachedKeyRing, true);
|
||||
|
||||
log.add(result, 1);
|
||||
progress.setProgress(processedKeys++, totalKeys);
|
||||
} catch (NotFoundException | PgpGeneralException | IOException e) {
|
||||
Log.e(Constants.TAG, "Error updating trust database", e);
|
||||
return new UpdateTrustResult(UpdateTrustResult.RESULT_ERROR, log);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableKeyRing next() {
|
||||
try {
|
||||
return ring;
|
||||
} finally {
|
||||
ring = null;
|
||||
}
|
||||
}
|
||||
if (!isTrustDbInitialized) {
|
||||
preferences.setKeySignaturesTableInitialized();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
});
|
||||
log.add(LogType.MSG_TRUST_OK, 1);
|
||||
return new UpdateTrustResult(UpdateTrustResult.RESULT_OK, log);
|
||||
} finally {
|
||||
cursor.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "error saving public", e);
|
||||
log.add(LogType.MSG_CON_ERROR_IO_PUBLIC, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
|
||||
} finally {
|
||||
indent -= 1;
|
||||
}
|
||||
|
||||
log.add(LogType.MSG_CON_CRITICAL_IN, indent);
|
||||
Preferences.getPreferences(mContext).setCachedConsolidate(true);
|
||||
|
||||
return consolidateDatabaseStep2(log, indent, progress, false);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ConsolidateResult consolidateDatabaseStep2(Progressable progress) {
|
||||
return consolidateDatabaseStep2(new OperationLog(), 0, progress, true);
|
||||
}
|
||||
|
||||
private static boolean mConsolidateCritical = false;
|
||||
|
||||
@NonNull
|
||||
private ConsolidateResult consolidateDatabaseStep2(
|
||||
OperationLog log, int indent, Progressable progress, boolean recovery) {
|
||||
|
||||
synchronized (KeyWritableRepository.class) {
|
||||
if (mConsolidateCritical) {
|
||||
log.add(LogType.MSG_CON_ERROR_CONCURRENT, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
|
||||
}
|
||||
mConsolidateCritical = true;
|
||||
}
|
||||
|
||||
try {
|
||||
Preferences prefs = Preferences.getPreferences(mContext);
|
||||
|
||||
if (recovery) {
|
||||
log.add(LogType.MSG_CON_RECOVER, indent);
|
||||
indent += 1;
|
||||
}
|
||||
|
||||
if (!prefs.getCachedConsolidate()) {
|
||||
log.add(LogType.MSG_CON_ERROR_BAD_STATE, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
|
||||
}
|
||||
|
||||
// 2. wipe database (IT'S DANGEROUS)
|
||||
|
||||
// first, backup our list of updated key times
|
||||
ArrayList<ContentValues> updatedKeysValues = new ArrayList<>();
|
||||
final int INDEX_MASTER_KEY_ID = 0;
|
||||
final int INDEX_LAST_UPDATED = 1;
|
||||
final int INDEX_SEEN_ON_KEYSERVERS = 2;
|
||||
Cursor lastUpdatedCursor = mContentResolver.query(
|
||||
UpdatedKeys.CONTENT_URI,
|
||||
new String[]{
|
||||
UpdatedKeys.MASTER_KEY_ID,
|
||||
UpdatedKeys.LAST_UPDATED,
|
||||
UpdatedKeys.SEEN_ON_KEYSERVERS
|
||||
},
|
||||
null, null, null);
|
||||
while (lastUpdatedCursor.moveToNext()) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(UpdatedKeys.MASTER_KEY_ID,
|
||||
lastUpdatedCursor.getLong(INDEX_MASTER_KEY_ID));
|
||||
if (!lastUpdatedCursor.isNull(INDEX_LAST_UPDATED)) {
|
||||
values.put(UpdatedKeys.LAST_UPDATED, lastUpdatedCursor.getLong(INDEX_LAST_UPDATED));
|
||||
} else {
|
||||
values.putNull(UpdatedKeys.LAST_UPDATED);
|
||||
}
|
||||
if (!lastUpdatedCursor.isNull(INDEX_SEEN_ON_KEYSERVERS)) {
|
||||
values.put(UpdatedKeys.SEEN_ON_KEYSERVERS, lastUpdatedCursor.getInt(INDEX_SEEN_ON_KEYSERVERS));
|
||||
} else {
|
||||
values.putNull(UpdatedKeys.SEEN_ON_KEYSERVERS);
|
||||
}
|
||||
updatedKeysValues.add(values);
|
||||
}
|
||||
lastUpdatedCursor.close();
|
||||
|
||||
log.add(LogType.MSG_CON_DB_CLEAR, indent);
|
||||
mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null);
|
||||
|
||||
ParcelableFileCache<ParcelableKeyRing> cacheSecret, cachePublic;
|
||||
|
||||
// Set flag that we have a cached consolidation here
|
||||
try {
|
||||
cacheSecret = new ParcelableFileCache<>(mContext, "consolidate_secret.pcl");
|
||||
IteratorWithSize<ParcelableKeyRing> itSecrets = cacheSecret.readCache(false);
|
||||
int numSecrets = itSecrets.getSize();
|
||||
|
||||
log.add(LogType.MSG_CON_REIMPORT_SECRET, indent, numSecrets);
|
||||
indent += 1;
|
||||
|
||||
// 3. Re-Import secret keyrings from cache
|
||||
if (numSecrets > 0) {
|
||||
|
||||
ImportKeyResult result = new ImportOperation(mContext, this,
|
||||
new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport))
|
||||
.serialKeyRingImport(itSecrets, numSecrets, null, null, false);
|
||||
log.add(result, indent);
|
||||
} else {
|
||||
log.add(LogType.MSG_CON_REIMPORT_SECRET_SKIP, indent);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "error importing secret", e);
|
||||
log.add(LogType.MSG_CON_ERROR_SECRET, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
|
||||
} finally {
|
||||
indent -= 1;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
cachePublic = new ParcelableFileCache<>(mContext, "consolidate_public.pcl");
|
||||
IteratorWithSize<ParcelableKeyRing> itPublics = cachePublic.readCache();
|
||||
int numPublics = itPublics.getSize();
|
||||
|
||||
log.add(LogType.MSG_CON_REIMPORT_PUBLIC, indent, numPublics);
|
||||
indent += 1;
|
||||
|
||||
// 4. Re-Import public keyrings from cache
|
||||
if (numPublics > 0) {
|
||||
|
||||
ImportKeyResult result = new ImportOperation(mContext, this,
|
||||
new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport))
|
||||
.serialKeyRingImport(itPublics, numPublics, null, null, false);
|
||||
log.add(result, indent);
|
||||
// re-insert our backed up list of updated key times
|
||||
// TODO: can this cause issues in case a public key re-import failed?
|
||||
mContentResolver.bulkInsert(UpdatedKeys.CONTENT_URI,
|
||||
updatedKeysValues.toArray(new ContentValues[updatedKeysValues.size()]));
|
||||
} else {
|
||||
log.add(LogType.MSG_CON_REIMPORT_PUBLIC_SKIP, indent);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "error importing public", e);
|
||||
log.add(LogType.MSG_CON_ERROR_PUBLIC, indent);
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
|
||||
} finally {
|
||||
indent -= 1;
|
||||
}
|
||||
|
||||
log.add(LogType.MSG_CON_CRITICAL_OUT, indent);
|
||||
Preferences.getPreferences(mContext).setCachedConsolidate(false);
|
||||
|
||||
// 5. Delete caches
|
||||
try {
|
||||
log.add(LogType.MSG_CON_DELETE_SECRET, indent);
|
||||
indent += 1;
|
||||
cacheSecret.delete();
|
||||
} catch (IOException e) {
|
||||
// doesn't /really/ matter
|
||||
Log.e(Constants.TAG, "IOException during delete of secret cache", e);
|
||||
log.add(LogType.MSG_CON_WARN_DELETE_SECRET, indent);
|
||||
} finally {
|
||||
indent -= 1;
|
||||
}
|
||||
|
||||
try {
|
||||
log.add(LogType.MSG_CON_DELETE_PUBLIC, indent);
|
||||
indent += 1;
|
||||
cachePublic.delete();
|
||||
} catch (IOException e) {
|
||||
// doesn't /really/ matter
|
||||
Log.e(Constants.TAG, "IOException during deletion of public cache", e);
|
||||
log.add(LogType.MSG_CON_WARN_DELETE_PUBLIC, indent);
|
||||
} finally {
|
||||
indent -= 1;
|
||||
}
|
||||
|
||||
progress.setProgress(100, 100);
|
||||
log.add(LogType.MSG_CON_SUCCESS, indent);
|
||||
|
||||
return new ConsolidateResult(ConsolidateResult.RESULT_OK, log);
|
||||
|
||||
} finally {
|
||||
mConsolidateCritical = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,6 +58,11 @@ public class KeychainContract {
|
||||
String SEEN_ON_KEYSERVERS = "seen_on_keyservers";
|
||||
}
|
||||
|
||||
interface KeySignaturesColumns {
|
||||
String MASTER_KEY_ID = "master_key_id"; // not a database id
|
||||
String SIGNER_KEY_ID = "signer_key_id";
|
||||
}
|
||||
|
||||
interface UserPacketsColumns {
|
||||
String MASTER_KEY_ID = "master_key_id"; // foreign key to key_rings._ID
|
||||
String TYPE = "type"; // not a database id
|
||||
@@ -113,6 +118,8 @@ public class KeychainContract {
|
||||
|
||||
public static final String BASE_UPDATED_KEYS = "updated_keys";
|
||||
|
||||
public static final String BASE_KEY_SIGNATURES = "key_signatures";
|
||||
|
||||
public static final String PATH_UNIFIED = "unified";
|
||||
|
||||
public static final String PATH_FIND = "find";
|
||||
@@ -120,6 +127,9 @@ public class KeychainContract {
|
||||
public static final String PATH_BY_SUBKEY = "subkey";
|
||||
public static final String PATH_BY_USER_ID = "user_id";
|
||||
|
||||
public static final String PATH_FILTER = "filter";
|
||||
public static final String PATH_BY_SIGNER = "signer";
|
||||
|
||||
public static final String PATH_PUBLIC = "public";
|
||||
public static final String PATH_SECRET = "secret";
|
||||
public static final String PATH_USER_IDS = "user_ids";
|
||||
@@ -198,6 +208,9 @@ public class KeychainContract {
|
||||
.appendPath(PATH_BY_SUBKEY).appendPath(Long.toString(subkey)).build();
|
||||
}
|
||||
|
||||
public static Uri buildUnifiedKeyRingsFilterBySigner() {
|
||||
return CONTENT_URI.buildUpon().appendPath(PATH_FILTER).appendPath(PATH_BY_SIGNER).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class KeyRingData implements KeyRingsColumns, BaseColumns {
|
||||
@@ -271,6 +284,14 @@ public class KeychainContract {
|
||||
= "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.provider.updated_keys";
|
||||
}
|
||||
|
||||
public static class KeySignatures implements KeySignaturesColumns, BaseColumns {
|
||||
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
|
||||
.appendPath(BASE_KEY_SIGNATURES).build();
|
||||
|
||||
public static final String CONTENT_TYPE
|
||||
= "vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.key_signatures";
|
||||
}
|
||||
|
||||
public static class UserPackets implements UserPacketsColumns, BaseColumns {
|
||||
public static final String VERIFIED = "verified";
|
||||
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
@@ -37,12 +36,14 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAutocryptPeerColumns;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.CertsColumns;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeySignaturesColumns;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.OverriddenWarnings;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeysColumns;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPacketsColumns;
|
||||
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
|
||||
/**
|
||||
* SQLite Datatypes (from http://www.sqlite.org/datatype3.html)
|
||||
@@ -54,7 +55,7 @@ import org.sufficientlysecure.keychain.util.Log;
|
||||
*/
|
||||
public class KeychainDatabase extends SQLiteOpenHelper {
|
||||
private static final String DATABASE_NAME = "openkeychain.db";
|
||||
private static final int DATABASE_VERSION = 23;
|
||||
private static final int DATABASE_VERSION = 24;
|
||||
private Context mContext;
|
||||
|
||||
public interface Tables {
|
||||
@@ -62,6 +63,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
||||
String KEY_RINGS_SECRET = "keyrings_secret";
|
||||
String KEYS = "keys";
|
||||
String UPDATED_KEYS = "updated_keys";
|
||||
String KEY_SIGNATURES = "key_signatures";
|
||||
String USER_PACKETS = "user_packets";
|
||||
String CERTS = "certs";
|
||||
String API_APPS = "api_apps";
|
||||
@@ -159,6 +161,15 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
||||
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
|
||||
+ ")";
|
||||
|
||||
private static final String CREATE_KEY_SIGNATURES =
|
||||
"CREATE TABLE IF NOT EXISTS " + Tables.KEY_SIGNATURES + " ("
|
||||
+ KeySignaturesColumns.MASTER_KEY_ID + " INTEGER NOT NULL, "
|
||||
+ KeySignaturesColumns.SIGNER_KEY_ID + " INTEGER NOT NULL, "
|
||||
+ "PRIMARY KEY(" + KeySignaturesColumns.MASTER_KEY_ID + ", " + KeySignaturesColumns.SIGNER_KEY_ID + "), "
|
||||
+ "FOREIGN KEY(" + KeySignaturesColumns.MASTER_KEY_ID + ") REFERENCES "
|
||||
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
|
||||
+ ")";
|
||||
|
||||
private static final String CREATE_API_AUTOCRYPT_PEERS =
|
||||
"CREATE TABLE IF NOT EXISTS " + Tables.API_AUTOCRYPT_PEERS + " ("
|
||||
+ ApiAutocryptPeerColumns.PACKAGE_NAME + " TEXT NOT NULL, "
|
||||
@@ -213,6 +224,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
||||
db.execSQL(CREATE_USER_PACKETS);
|
||||
db.execSQL(CREATE_CERTS);
|
||||
db.execSQL(CREATE_UPDATE_KEYS);
|
||||
db.execSQL(CREATE_KEY_SIGNATURES);
|
||||
db.execSQL(CREATE_API_APPS);
|
||||
db.execSQL(CREATE_API_APPS_ALLOWED_KEYS);
|
||||
db.execSQL(CREATE_OVERRIDDEN_WARNINGS);
|
||||
@@ -224,6 +236,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
||||
db.execSQL("CREATE INDEX verified_certs ON certs ("
|
||||
+ CertsColumns.VERIFIED + ", " + CertsColumns.MASTER_KEY_ID + ");");
|
||||
|
||||
Preferences.getPreferences(mContext).setKeySignaturesTableInitialized();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -387,17 +400,14 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
||||
+ "FOREIGN KEY(package_name) REFERENCES api_apps(package_name) ON DELETE CASCADE"
|
||||
+ ")");
|
||||
|
||||
if (oldVersion == 18 || oldVersion == 19 || oldVersion == 20 || oldVersion == 21 || oldVersion == 22) {
|
||||
return;
|
||||
}
|
||||
case 23:
|
||||
db.execSQL("CREATE TABLE IF NOT EXISTS key_signatures ("
|
||||
+ "master_key_id INTEGER NOT NULL, "
|
||||
+ "signer_key_id INTEGER NOT NULL, "
|
||||
+ "PRIMARY KEY(master_key_id, signer_key_id), "
|
||||
+ "FOREIGN KEY(master_key_id) REFERENCES keyrings_public(master_key_id) ON DELETE CASCADE"
|
||||
+ ")");
|
||||
}
|
||||
|
||||
// TODO: don't depend on consolidate! make migrations inline!
|
||||
// consolidate after upgrade
|
||||
Intent consolidateIntent = new Intent(mContext.getApplicationContext(), ConsolidateDialogActivity.class);
|
||||
consolidateIntent.putExtra(ConsolidateDialogActivity.EXTRA_CONSOLIDATE_RECOVERY, false);
|
||||
consolidateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mContext.getApplicationContext().startActivity(consolidateIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAutocryptPee
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeySignatures;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
@@ -77,6 +78,7 @@ public class KeychainProvider extends ContentProvider {
|
||||
private static final int KEY_RINGS_FIND_BY_EMAIL = 400;
|
||||
private static final int KEY_RINGS_FIND_BY_SUBKEY = 401;
|
||||
private static final int KEY_RINGS_FIND_BY_USER_ID = 402;
|
||||
private static final int KEY_RINGS_FILTER_BY_SIGNER = 403;
|
||||
|
||||
private static final int UPDATED_KEYS = 500;
|
||||
private static final int UPDATED_KEYS_SPECIFIC = 501;
|
||||
@@ -85,6 +87,8 @@ public class KeychainProvider extends ContentProvider {
|
||||
private static final int AUTOCRYPT_PEERS_BY_PACKAGE_NAME = 602;
|
||||
private static final int AUTOCRYPT_PEERS_BY_PACKAGE_NAME_AND_TRUST_ID = 603;
|
||||
|
||||
private static final int KEY_SIGNATURES = 700;
|
||||
|
||||
protected UriMatcher mUriMatcher;
|
||||
|
||||
/**
|
||||
@@ -135,6 +139,9 @@ public class KeychainProvider extends ContentProvider {
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_FIND + "/" + KeychainContract.PATH_BY_USER_ID + "/*",
|
||||
KEY_RINGS_FIND_BY_USER_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_FILTER + "/" + KeychainContract.PATH_BY_SIGNER,
|
||||
KEY_RINGS_FILTER_BY_SIGNER);
|
||||
|
||||
/**
|
||||
* list key_ring specifics
|
||||
@@ -219,6 +226,10 @@ public class KeychainProvider extends ContentProvider {
|
||||
matcher.addURI(authority, KeychainContract.BASE_UPDATED_KEYS, UPDATED_KEYS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_UPDATED_KEYS + "/*", UPDATED_KEYS_SPECIFIC);
|
||||
|
||||
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_SIGNATURES, KEY_SIGNATURES);
|
||||
|
||||
|
||||
return matcher;
|
||||
}
|
||||
|
||||
@@ -260,9 +271,13 @@ public class KeychainProvider extends ContentProvider {
|
||||
|
||||
case UPDATED_KEYS:
|
||||
return UpdatedKeys.CONTENT_TYPE;
|
||||
|
||||
case UPDATED_KEYS_SPECIFIC:
|
||||
return UpdatedKeys.CONTENT_ITEM_TYPE;
|
||||
|
||||
case KEY_SIGNATURES:
|
||||
return KeySignatures.CONTENT_TYPE;
|
||||
|
||||
case API_APPS:
|
||||
return ApiApps.CONTENT_TYPE;
|
||||
|
||||
@@ -297,7 +312,8 @@ public class KeychainProvider extends ContentProvider {
|
||||
case KEY_RINGS_UNIFIED:
|
||||
case KEY_RINGS_FIND_BY_EMAIL:
|
||||
case KEY_RINGS_FIND_BY_SUBKEY:
|
||||
case KEY_RINGS_FIND_BY_USER_ID: {
|
||||
case KEY_RINGS_FIND_BY_USER_ID:
|
||||
case KEY_RINGS_FILTER_BY_SIGNER: {
|
||||
HashMap<String, String> projectionMap = new HashMap<>();
|
||||
projectionMap.put(KeyRings._ID, Tables.KEYS + ".oid AS _id");
|
||||
projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
|
||||
@@ -446,6 +462,23 @@ public class KeychainProvider extends ContentProvider {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEY_RINGS_FILTER_BY_SIGNER: {
|
||||
StringBuilder signerKeyIds = new StringBuilder();
|
||||
signerKeyIds.append(selectionArgs[0]);
|
||||
for (int i = 1; i < selectionArgs.length; i++) {
|
||||
signerKeyIds.append(',').append(selectionArgs[i]);
|
||||
}
|
||||
|
||||
qb.appendWhere(" AND EXISTS (SELECT 1 FROM " + Tables.KEY_SIGNATURES + " WHERE " +
|
||||
Tables.KEY_SIGNATURES + "." + KeySignatures.MASTER_KEY_ID + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID +
|
||||
" AND " +
|
||||
Tables.KEY_SIGNATURES + "." + KeySignatures.SIGNER_KEY_ID + " IN (" + signerKeyIds + ")" +
|
||||
")");
|
||||
|
||||
selection = null;
|
||||
selectionArgs = null;
|
||||
break;
|
||||
}
|
||||
case KEY_RINGS_FIND_BY_EMAIL:
|
||||
case KEY_RINGS_FIND_BY_USER_ID: {
|
||||
String chunks[] = uri.getLastPathSegment().split(" *, *");
|
||||
@@ -860,6 +893,11 @@ public class KeychainProvider extends ContentProvider {
|
||||
rowUri = UpdatedKeys.CONTENT_URI;
|
||||
break;
|
||||
}
|
||||
case KEY_SIGNATURES: {
|
||||
db.insert(Tables.KEY_SIGNATURES, null, values);
|
||||
rowUri = KeySignatures.CONTENT_URI;
|
||||
break;
|
||||
}
|
||||
case API_APPS: {
|
||||
db.insertOrThrow(Tables.API_APPS, null, values);
|
||||
break;
|
||||
|
||||
@@ -104,7 +104,7 @@ public class OpenPgpService extends Service {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
mKeyRepository = KeyRepository.createDatabaseInteractor(this);
|
||||
mKeyRepository = KeyRepository.create(this);
|
||||
mApiDao = new ApiDataAccessObject(this);
|
||||
mApiPermissionHelper = new ApiPermissionHelper(this, mApiDao);
|
||||
mApiPendingIntentFactory = new ApiPendingIntentFactory(getBaseContext());
|
||||
@@ -491,7 +491,7 @@ public class OpenPgpService extends Service {
|
||||
return null;
|
||||
}
|
||||
// this will merge if the key already exists - no worries!
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(this).savePublicKeyRing(uncachedKeyRing);
|
||||
KeyWritableRepository.create(this).savePublicKeyRing(uncachedKeyRing);
|
||||
newMasterKeyId = uncachedKeyRing.getMasterKeyId();
|
||||
} else {
|
||||
newMasterKeyId = null;
|
||||
|
||||
@@ -41,7 +41,7 @@ class RequestKeyPermissionPresenter {
|
||||
ApiDataAccessObject apiDataAccessObject = new ApiDataAccessObject(context);
|
||||
ApiPermissionHelper apiPermissionHelper = new ApiPermissionHelper(context, apiDataAccessObject);
|
||||
KeyRepository keyRepository =
|
||||
KeyRepository.createDatabaseInteractor(context);
|
||||
KeyRepository.create(context);
|
||||
|
||||
return new RequestKeyPermissionPresenter(context, apiDataAccessObject, apiPermissionHelper, packageManager,
|
||||
keyRepository);
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
|
||||
* Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.service;
|
||||
|
||||
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
|
||||
|
||||
@AutoValue
|
||||
public abstract class ConsolidateInputParcel implements Parcelable {
|
||||
public abstract boolean isStartFromRecovery();
|
||||
|
||||
public static ConsolidateInputParcel createConsolidateInputParcel(boolean consolidateRecovery) {
|
||||
return new AutoValue_ConsolidateInputParcel(consolidateRecovery);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.service;
|
||||
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -28,24 +31,23 @@ import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.operations.BackupOperation;
|
||||
import org.sufficientlysecure.keychain.operations.BaseOperation;
|
||||
import org.sufficientlysecure.keychain.operations.BenchmarkOperation;
|
||||
import org.sufficientlysecure.keychain.operations.CertifyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.ConsolidateOperation;
|
||||
import org.sufficientlysecure.keychain.operations.ChangeUnlockOperation;
|
||||
import org.sufficientlysecure.keychain.operations.DeleteOperation;
|
||||
import org.sufficientlysecure.keychain.operations.EditKeyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.BackupOperation;
|
||||
import org.sufficientlysecure.keychain.operations.ImportOperation;
|
||||
import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation;
|
||||
import org.sufficientlysecure.keychain.operations.InputDataOperation;
|
||||
import org.sufficientlysecure.keychain.operations.ChangeUnlockOperation;
|
||||
import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation;
|
||||
import org.sufficientlysecure.keychain.operations.PromoteKeyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.RevokeOperation;
|
||||
import org.sufficientlysecure.keychain.operations.SignEncryptOperation;
|
||||
import org.sufficientlysecure.keychain.operations.UploadOperation;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
|
||||
@@ -53,8 +55,6 @@ import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageSta
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* This Service contains all important long lasting operations for OpenKeychain. It receives Intents with
|
||||
* data from the activities or other apps, executes them, and stops itself after doing them.
|
||||
@@ -112,7 +112,7 @@ public class KeychainService extends Service implements Progressable {
|
||||
// just for brevity
|
||||
KeychainService outerThis = KeychainService.this;
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(outerThis);
|
||||
KeyWritableRepository.create(outerThis);
|
||||
if (inputParcel instanceof SignEncryptParcel) {
|
||||
op = new SignEncryptOperation(outerThis, databaseInteractor, outerThis, mActionCanceled);
|
||||
} else if (inputParcel instanceof PgpDecryptVerifyInputParcel) {
|
||||
@@ -135,8 +135,6 @@ public class KeychainService extends Service implements Progressable {
|
||||
op = new BackupOperation(outerThis, databaseInteractor, outerThis, mActionCanceled);
|
||||
} else if (inputParcel instanceof UploadKeyringParcel) {
|
||||
op = new UploadOperation(outerThis, databaseInteractor, outerThis, mActionCanceled);
|
||||
} else if (inputParcel instanceof ConsolidateInputParcel) {
|
||||
op = new ConsolidateOperation(outerThis, databaseInteractor, outerThis);
|
||||
} else if (inputParcel instanceof KeybaseVerificationParcel) {
|
||||
op = new KeybaseVerificationOperation(outerThis, databaseInteractor, outerThis);
|
||||
} else if (inputParcel instanceof InputDataParcel) {
|
||||
|
||||
@@ -322,7 +322,7 @@ public class KeyserverSyncAdapterService extends Service {
|
||||
CryptoInputParcel cryptoInputParcel) {
|
||||
Log.d(Constants.TAG, "Starting normal update");
|
||||
ImportOperation importOp = new ImportOperation(context,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(context), null);
|
||||
KeyWritableRepository.create(context), null);
|
||||
return importOp.execute(
|
||||
ImportKeyringParcel.createImportKeyringParcel(keyList,
|
||||
Preferences.getPreferences(context).getPreferredKeyserver()),
|
||||
@@ -381,7 +381,7 @@ public class KeyserverSyncAdapterService extends Service {
|
||||
new OperationResult.OperationLog());
|
||||
}
|
||||
ImportKeyResult result =
|
||||
new ImportOperation(context, KeyWritableRepository.createDatabaseReadWriteInteractor(context), null, mCancelled)
|
||||
new ImportOperation(context, KeyWritableRepository.create(context), null, mCancelled)
|
||||
.execute(
|
||||
ImportKeyringParcel.createImportKeyringParcel(
|
||||
keyWrapper,
|
||||
|
||||
@@ -245,7 +245,7 @@ public class PassphraseCacheService extends Service {
|
||||
+ masterKeyId + ", subKeyId " + subKeyId);
|
||||
|
||||
// get the type of key (from the database)
|
||||
CachedPublicKeyRing keyRing = KeyRepository.createDatabaseInteractor(this).getCachedPublicKeyRing(masterKeyId);
|
||||
CachedPublicKeyRing keyRing = KeyRepository.create(this).getCachedPublicKeyRing(masterKeyId);
|
||||
SecretKeyType keyType = keyRing.getSecretKeyType(subKeyId);
|
||||
|
||||
switch (keyType) {
|
||||
|
||||
@@ -214,7 +214,7 @@ public class CertifyFingerprintFragment extends LoaderFragment implements
|
||||
private void certify(Uri dataUri) {
|
||||
long keyId = 0;
|
||||
try {
|
||||
keyId = KeyRepository.createDatabaseInteractor(getContext())
|
||||
keyId = KeyRepository.create(getContext())
|
||||
.getCachedPublicKeyRing(dataUri)
|
||||
.extractOrGetMasterKeyId();
|
||||
} catch (PgpKeyNotFoundException e) {
|
||||
|
||||
@@ -70,7 +70,7 @@ public class CertifyKeyFragment
|
||||
if (certifyKeyId != Constants.key.none) {
|
||||
try {
|
||||
CachedPublicKeyRing key = (KeyRepository
|
||||
.createDatabaseInteractor(getContext()))
|
||||
.create(getContext()))
|
||||
.getCachedPublicKeyRing(certifyKeyId);
|
||||
if (key.canCertify()) {
|
||||
mCertifyKeySpinner.setPreSelectedKeyId(certifyKeyId);
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.service.ConsolidateInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
|
||||
|
||||
/**
|
||||
* We can not directly create a dialog on the application context.
|
||||
* This activity encapsulates a DialogFragment to emulate a dialog.
|
||||
*/
|
||||
public class ConsolidateDialogActivity extends FragmentActivity
|
||||
implements CryptoOperationHelper.Callback<ConsolidateInputParcel, ConsolidateResult> {
|
||||
|
||||
public static final String EXTRA_CONSOLIDATE_RECOVERY = "consolidate_recovery";
|
||||
|
||||
private CryptoOperationHelper<ConsolidateInputParcel, ConsolidateResult> mConsolidateOpHelper;
|
||||
private boolean mRecovery;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// this activity itself has no content view (see manifest)
|
||||
|
||||
boolean recovery = getIntent().getBooleanExtra(EXTRA_CONSOLIDATE_RECOVERY, false);
|
||||
|
||||
consolidateRecovery(recovery);
|
||||
}
|
||||
|
||||
private void consolidateRecovery(boolean recovery) {
|
||||
|
||||
mRecovery = recovery;
|
||||
|
||||
mConsolidateOpHelper = new CryptoOperationHelper<>(1, this, this, R.string.progress_importing);
|
||||
mConsolidateOpHelper.cryptoOperation();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (mConsolidateOpHelper != null) {
|
||||
mConsolidateOpHelper.handleActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsolidateInputParcel createOperationInput() {
|
||||
return ConsolidateInputParcel.createConsolidateInputParcel(mRecovery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationSuccess(ConsolidateResult result) {
|
||||
// don't care about result (for now?)
|
||||
ConsolidateDialogActivity.this.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationCancelled() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationError(ConsolidateResult result) {
|
||||
// don't care about result (for now?)
|
||||
ConsolidateDialogActivity.this.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCryptoSetProgress(String msg, int progress, int max) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -430,7 +430,7 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||
CreateKeyActivity activity = (CreateKeyActivity) getActivity();
|
||||
|
||||
SaveKeyringParcel.Builder builder;
|
||||
CachedPublicKeyRing key = (KeyRepository.createDatabaseInteractor(getContext()))
|
||||
CachedPublicKeyRing key = (KeyRepository.create(getContext()))
|
||||
.getCachedPublicKeyRing(saveKeyResult.mMasterKeyId);
|
||||
try {
|
||||
builder = SaveKeyringParcel.buildChangeKeyringParcel(key.getMasterKeyId(), key.getFingerprint());
|
||||
|
||||
@@ -194,7 +194,7 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
||||
try {
|
||||
|
||||
Intent viewKeyIntent = new Intent(getActivity(), ViewKeyActivity.class);
|
||||
long masterKeyId = KeyRepository.createDatabaseInteractor(getContext()).getCachedPublicKeyRing(
|
||||
long masterKeyId = KeyRepository.create(getContext()).getCachedPublicKeyRing(
|
||||
KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(keyId)
|
||||
).getMasterKeyId();
|
||||
viewKeyIntent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
||||
|
||||
@@ -89,7 +89,7 @@ public class DeleteKeyDialogActivity extends FragmentActivity {
|
||||
if (mMasterKeyIds.length == 1 && mHasSecret) {
|
||||
// if mMasterKeyIds.length == 0 we let the DeleteOperation respond
|
||||
try {
|
||||
HashMap<String, Object> data = KeyRepository.createDatabaseInteractor(this).getUnifiedData(
|
||||
HashMap<String, Object> data = KeyRepository.create(this).getUnifiedData(
|
||||
mMasterKeyIds[0], new String[]{
|
||||
KeychainContract.KeyRings.NAME,
|
||||
KeychainContract.KeyRings.IS_REVOKED
|
||||
@@ -272,7 +272,7 @@ public class DeleteKeyDialogActivity extends FragmentActivity {
|
||||
long masterKeyId = masterKeyIds[0];
|
||||
|
||||
try {
|
||||
HashMap<String, Object> data = KeyRepository.createDatabaseInteractor(getContext())
|
||||
HashMap<String, Object> data = KeyRepository.create(getContext())
|
||||
.getUnifiedData(
|
||||
masterKeyId, new String[]{
|
||||
KeychainContract.KeyRings.NAME,
|
||||
|
||||
@@ -170,7 +170,7 @@ public class EditIdentitiesFragment extends Fragment
|
||||
try {
|
||||
Uri secretUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
|
||||
CachedPublicKeyRing keyRing =
|
||||
KeyRepository.createDatabaseInteractor(getContext()).getCachedPublicKeyRing(secretUri);
|
||||
KeyRepository.create(getContext()).getCachedPublicKeyRing(secretUri);
|
||||
long masterKeyId = keyRing.getMasterKeyId();
|
||||
|
||||
// check if this is a master secret key we can work with
|
||||
|
||||
@@ -201,7 +201,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
|
||||
try {
|
||||
Uri secretUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
|
||||
CachedPublicKeyRing keyRing =
|
||||
KeyRepository.createDatabaseInteractor(getContext()).getCachedPublicKeyRing(secretUri);
|
||||
KeyRepository.create(getContext()).getCachedPublicKeyRing(secretUri);
|
||||
long masterKeyId = keyRing.getMasterKeyId();
|
||||
|
||||
// check if this is a master secret key we can work with
|
||||
|
||||
@@ -118,7 +118,7 @@ public class EncryptModeAsymmetricFragment extends EncryptModeFragment {
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mKeyRepository = KeyRepository.createDatabaseInteractor(getContext());
|
||||
mKeyRepository = KeyRepository.create(getContext());
|
||||
|
||||
// preselect keys given, from state or arguments
|
||||
if (savedInstanceState == null) {
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
@@ -47,34 +51,28 @@ import com.futuremind.recyclerviewfastscroll.FastScroller;
|
||||
import com.getbase.floatingactionbutton.FloatingActionButton;
|
||||
import com.getbase.floatingactionbutton.FloatingActionsMenu;
|
||||
import com.tonicartos.superslim.LayoutManager;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.results.BenchmarkResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
||||
import org.sufficientlysecure.keychain.service.BenchmarkInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.ConsolidateInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.KeySectionedListAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
|
||||
import org.sufficientlysecure.keychain.ui.base.RecyclerFragment;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.ViewKeyActivity;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.ui.base.RecyclerFragment;
|
||||
import org.sufficientlysecure.keychain.util.FabContainer;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
||||
implements SearchView.OnQueryTextListener,
|
||||
LoaderManager.LoaderCallbacks<Cursor>, FabContainer {
|
||||
@@ -97,9 +95,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
||||
private HkpKeyserverAddress mKeyserver;
|
||||
private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mImportOpHelper;
|
||||
|
||||
// for ConsolidateOperation
|
||||
private CryptoOperationHelper<ConsolidateInputParcel, ConsolidateResult> mConsolidateOpHelper;
|
||||
|
||||
// Callbacks related to listview and menu events
|
||||
private final ActionMode.Callback mActionCallback
|
||||
= new ActionMode.Callback() {
|
||||
@@ -334,7 +329,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
||||
inflater.inflate(R.menu.key_list, menu);
|
||||
|
||||
if (Constants.DEBUG) {
|
||||
menu.findItem(R.id.menu_key_list_debug_cons).setVisible(true);
|
||||
menu.findItem(R.id.menu_key_list_debug_bench).setVisible(true);
|
||||
menu.findItem(R.id.menu_key_list_debug_read).setVisible(true);
|
||||
menu.findItem(R.id.menu_key_list_debug_write).setVisible(true);
|
||||
@@ -413,10 +407,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
||||
getActivity().finish();
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_key_list_debug_cons: {
|
||||
consolidate();
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_key_list_debug_bench: {
|
||||
benchmark();
|
||||
return true;
|
||||
@@ -487,7 +477,7 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
||||
}
|
||||
|
||||
KeyRepository keyRepository =
|
||||
KeyRepository.createDatabaseInteractor(getContext());
|
||||
KeyRepository.create(getContext());
|
||||
Cursor cursor = keyRepository.getContentResolver().query(
|
||||
KeyRings.buildUnifiedKeyRingsUri(), new String[]{
|
||||
KeyRings.FINGERPRINT
|
||||
@@ -547,39 +537,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
||||
mImportOpHelper.cryptoOperation();
|
||||
}
|
||||
|
||||
private void consolidate() {
|
||||
CryptoOperationHelper.Callback<ConsolidateInputParcel, ConsolidateResult> callback
|
||||
= new CryptoOperationHelper.Callback<ConsolidateInputParcel, ConsolidateResult>() {
|
||||
|
||||
@Override
|
||||
public ConsolidateInputParcel createOperationInput() {
|
||||
return ConsolidateInputParcel.createConsolidateInputParcel(false); // we want to perform a full consolidate
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationSuccess(ConsolidateResult result) {
|
||||
result.createNotify(getActivity()).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationCancelled() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationError(ConsolidateResult result) {
|
||||
result.createNotify(getActivity()).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCryptoSetProgress(String msg, int progress, int max) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
mConsolidateOpHelper = new CryptoOperationHelper<>(2, this, callback, R.string.progress_importing);
|
||||
mConsolidateOpHelper.cryptoOperation();
|
||||
}
|
||||
|
||||
private void benchmark() {
|
||||
CryptoOperationHelper.Callback<BenchmarkInputParcel, BenchmarkResult> callback
|
||||
= new CryptoOperationHelper.Callback<BenchmarkInputParcel, BenchmarkResult>() {
|
||||
@@ -619,10 +576,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
||||
mImportOpHelper.handleActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
if (mConsolidateOpHelper != null) {
|
||||
mConsolidateOpHelper.handleActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case REQUEST_DELETE: {
|
||||
if (mActionMode != null) {
|
||||
|
||||
@@ -112,7 +112,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
||||
// handle empty passphrases by directly returning an empty crypto input parcel
|
||||
try {
|
||||
CachedPublicKeyRing pubRing =
|
||||
KeyRepository.createDatabaseInteractor(this).getCachedPublicKeyRing(requiredInput.getMasterKeyId());
|
||||
KeyRepository.create(this).getCachedPublicKeyRing(requiredInput.getMasterKeyId());
|
||||
// use empty passphrase for empty passphrase
|
||||
if (pubRing.getSecretKeyType(requiredInput.getSubKeyId()) == SecretKeyType.PASSPHRASE_EMPTY) {
|
||||
// also return passphrase back to activity
|
||||
@@ -234,7 +234,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
||||
long subKeyId = mRequiredInput.getSubKeyId();
|
||||
|
||||
KeyRepository helper =
|
||||
KeyRepository.createDatabaseInteractor(getContext());
|
||||
KeyRepository.create(getContext());
|
||||
CachedPublicKeyRing cachedPublicKeyRing = helper.getCachedPublicKeyRing(
|
||||
KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(subKeyId));
|
||||
// yes the inner try/catch block is necessary, otherwise the final variable
|
||||
@@ -454,7 +454,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
||||
|
||||
Long subKeyId = mRequiredInput.getSubKeyId();
|
||||
CanonicalizedSecretKeyRing secretKeyRing =
|
||||
KeyRepository.createDatabaseInteractor(getContext()).getCanonicalizedSecretKeyRing(
|
||||
KeyRepository.create(getContext()).getCanonicalizedSecretKeyRing(
|
||||
KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(subKeyId));
|
||||
CanonicalizedSecretKey secretKeyToUnlock =
|
||||
secretKeyRing.getSecretKey(subKeyId);
|
||||
|
||||
@@ -74,7 +74,7 @@ public class QrCodeViewActivity extends BaseActivity {
|
||||
}
|
||||
});
|
||||
|
||||
KeyRepository keyRepository = KeyRepository.createDatabaseInteractor(this);
|
||||
KeyRepository keyRepository = KeyRepository.create(this);
|
||||
try {
|
||||
byte[] blob = keyRepository.getCachedPublicKeyRing(dataUri).getFingerprint();
|
||||
if (blob == null) {
|
||||
|
||||
@@ -106,7 +106,7 @@ public class SafeSlingerActivity extends BaseActivity
|
||||
// retrieve public key blob and start SafeSlinger
|
||||
Uri uri = KeychainContract.KeyRingData.buildPublicKeyRingUri(masterKeyId);
|
||||
try {
|
||||
byte[] keyBlob = KeyRepository.createDatabaseInteractor(this).getCachedPublicKeyRing(uri).getEncoded();
|
||||
byte[] keyBlob = KeyRepository.create(this).getCachedPublicKeyRing(uri).getEncoded();
|
||||
|
||||
Intent slingerIntent = new Intent(this, ExchangeActivity.class);
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
|
||||
}
|
||||
|
||||
KeyRepository keyRepository =
|
||||
KeyRepository.createDatabaseInteractor(this);
|
||||
KeyRepository.create(this);
|
||||
CanonicalizedPublicKeyRing publicKeyRing;
|
||||
try {
|
||||
publicKeyRing = keyRepository.getCanonicalizedPublicKeyRing(
|
||||
@@ -237,7 +237,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
|
||||
mSecurityTokenHelper.setAdminPin(new Passphrase("12345678"));
|
||||
|
||||
KeyRepository keyRepository =
|
||||
KeyRepository.createDatabaseInteractor(this);
|
||||
KeyRepository.create(this);
|
||||
CanonicalizedSecretKeyRing secretKeyRing;
|
||||
try {
|
||||
secretKeyRing = keyRepository.getCanonicalizedSecretKeyRing(
|
||||
|
||||
@@ -79,7 +79,7 @@ public class SettingsKeyserverFragment extends Fragment implements RecyclerItemC
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
|
||||
savedInstanceState) {
|
||||
databaseReadWriteInteractor = KeyWritableRepository.createDatabaseReadWriteInteractor(getContext());
|
||||
databaseReadWriteInteractor = KeyWritableRepository.create(getContext());
|
||||
|
||||
return inflater.inflate(R.layout.settings_keyserver_fragment, null);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ public class ViewCertActivity extends BaseActivity
|
||||
|
||||
try {
|
||||
KeyRepository keyRepository =
|
||||
KeyRepository.createDatabaseInteractor(ViewCertActivity.this);
|
||||
KeyRepository.create(ViewCertActivity.this);
|
||||
long signerMasterKeyId = keyRepository.getCachedPublicKeyRing(
|
||||
KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(mCertifierKeyId)).getMasterKeyId();
|
||||
viewIntent.setData(KeyRings.buildGenericKeyRingUri(signerMasterKeyId));
|
||||
|
||||
@@ -88,7 +88,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
|
||||
}
|
||||
});
|
||||
|
||||
mKeyRepository = KeyRepository.createDatabaseInteractor(this);
|
||||
mKeyRepository = KeyRepository.create(this);
|
||||
|
||||
mViewPager = (ViewPager) findViewById(R.id.pager);
|
||||
mSlidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tab_layout);
|
||||
|
||||
@@ -181,7 +181,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
|
||||
private void startSafeSlinger(Uri dataUri) {
|
||||
long keyId = 0;
|
||||
try {
|
||||
keyId = KeyRepository.createDatabaseInteractor(getContext())
|
||||
keyId = KeyRepository.create(getContext())
|
||||
.getCachedPublicKeyRing(dataUri)
|
||||
.extractOrGetMasterKeyId();
|
||||
} catch (PgpKeyNotFoundException e) {
|
||||
@@ -198,7 +198,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
|
||||
return;
|
||||
}
|
||||
KeyRepository keyRepository =
|
||||
KeyRepository.createDatabaseInteractor(getContext());
|
||||
KeyRepository.create(getContext());
|
||||
|
||||
try {
|
||||
long masterKeyId = keyRepository.getCachedPublicKeyRing(mDataUri).extractOrGetMasterKeyId();
|
||||
@@ -436,7 +436,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
|
||||
private void uploadToKeyserver() {
|
||||
long keyId;
|
||||
try {
|
||||
keyId = KeyRepository.createDatabaseInteractor(getContext())
|
||||
keyId = KeyRepository.create(getContext())
|
||||
.getCachedPublicKeyRing(mDataUri)
|
||||
.extractOrGetMasterKeyId();
|
||||
} catch (PgpKeyNotFoundException e) {
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ImportKeysAdapter extends RecyclerView.Adapter<ImportKeysAdapter.Vi
|
||||
mListener = listener;
|
||||
mNonInteractive = nonInteractive;
|
||||
|
||||
mKeyRepository = KeyRepository.createDatabaseInteractor(activity);
|
||||
mKeyRepository = KeyRepository.create(activity);
|
||||
}
|
||||
|
||||
public void setData(List<ImportKeysListEntry> data) {
|
||||
|
||||
@@ -467,7 +467,7 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
||||
|
||||
byte[] fingerprint;
|
||||
try {
|
||||
fingerprint = KeyRepository.createDatabaseInteractor(activity).getCachedPublicKeyRing(
|
||||
fingerprint = KeyRepository.create(activity).getCachedPublicKeyRing(
|
||||
mMasterKeyId).getFingerprint();
|
||||
} catch (PgpKeyNotFoundException e) {
|
||||
throw new IllegalStateException("Key to verify linked id for must exist in db!");
|
||||
|
||||
@@ -175,7 +175,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mKeyRepository = KeyRepository.createDatabaseInteractor(this);
|
||||
mKeyRepository = KeyRepository.create(this);
|
||||
mImportOpHelper = new CryptoOperationHelper<>(1, this, this, null);
|
||||
|
||||
setTitle(null);
|
||||
@@ -656,7 +656,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
|
||||
return;
|
||||
}
|
||||
try {
|
||||
long keyId = KeyRepository.createDatabaseInteractor(this)
|
||||
long keyId = KeyRepository.create(this)
|
||||
.getCachedPublicKeyRing(dataUri)
|
||||
.extractOrGetMasterKeyId();
|
||||
long[] encryptionKeyIds = new long[]{keyId};
|
||||
@@ -680,7 +680,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
|
||||
private void startSafeSlinger(Uri dataUri) {
|
||||
long keyId = 0;
|
||||
try {
|
||||
keyId = KeyRepository.createDatabaseInteractor(this)
|
||||
keyId = KeyRepository.create(this)
|
||||
.getCachedPublicKeyRing(dataUri)
|
||||
.extractOrGetMasterKeyId();
|
||||
} catch (PgpKeyNotFoundException e) {
|
||||
|
||||
@@ -58,7 +58,7 @@ public class LinkedIdWizard extends BaseActivity {
|
||||
try {
|
||||
Uri uri = getIntent().getData();
|
||||
uri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(uri);
|
||||
CachedPublicKeyRing ring = KeyRepository.createDatabaseInteractor(this).getCachedPublicKeyRing(uri);
|
||||
CachedPublicKeyRing ring = KeyRepository.create(this).getCachedPublicKeyRing(uri);
|
||||
if (!ring.hasAnySecret()) {
|
||||
Log.e(Constants.TAG, "Linked Identities can only be added to secret keys!");
|
||||
finish();
|
||||
|
||||
@@ -98,7 +98,7 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
|
||||
LocalKeyLookupLoader(Context context, List<byte[]> fingerprints) {
|
||||
super(context, fingerprints);
|
||||
|
||||
this.keyRepository = KeyRepository.createDatabaseInteractor(context);
|
||||
this.keyRepository = KeyRepository.create(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -96,7 +96,7 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
||||
this.view = view;
|
||||
this.loaderManager = loaderManager;
|
||||
this.loaderId = loaderId;
|
||||
this.databaseInteractor = KeyRepository.createDatabaseInteractor(context);
|
||||
this.databaseInteractor = KeyRepository.create(context);
|
||||
|
||||
secretKeyAdapter = new TransferKeyAdapter(context, LayoutInflater.from(context), this);
|
||||
view.setSecretKeyAdapter(secretKeyAdapter);
|
||||
|
||||
@@ -52,10 +52,6 @@ public class ParcelableFileCache<E extends Parcelable> {
|
||||
mFilename = filename;
|
||||
}
|
||||
|
||||
public static boolean cacheFileExists(Context context, String filename) {
|
||||
return new File(context.getCacheDir(), filename).exists();
|
||||
}
|
||||
|
||||
public void writeCache(int numEntries, Iterator<E> it) throws IOException {
|
||||
DataOutputStream oos = getOutputStream();
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.annotation.SuppressLint;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -318,6 +319,16 @@ public class Preferences {
|
||||
getPreferredKeyserver());
|
||||
}
|
||||
|
||||
public boolean isKeySignaturesTableInitialized() {
|
||||
return mSharedPreferences.getBoolean(Pref.KEY_SIGNATURES_TABLE_INITIALIZED, false);
|
||||
}
|
||||
|
||||
public void setKeySignaturesTableInitialized() {
|
||||
Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.KEY_SIGNATURES_TABLE_INITIALIZED, true);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static class CloudSearchPrefs implements Parcelable {
|
||||
public final boolean searchKeyserver;
|
||||
public final boolean searchKeybase;
|
||||
|
||||
@@ -19,12 +19,6 @@
|
||||
android:title="@string/menu_update_all_keys"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_key_list_debug_cons"
|
||||
android:title="Debug / Consolidate"
|
||||
android:visible="false"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_key_list_debug_bench"
|
||||
android:title="Debug / Benchmark"
|
||||
|
||||
@@ -493,9 +493,7 @@
|
||||
<string name="progress_verifying_integrity">"verifying integrity…"</string>
|
||||
<string name="progress_deleting_securely">"deleting '%s' securely…"</string>
|
||||
<string name="progress_deleting">"deleting keys…"</string>
|
||||
|
||||
<string name="progress_con_saving">"consolidate: saving to cache…"</string>
|
||||
<string name="progress_con_reimport">"consolidate: reimporting…"</string>
|
||||
<string name="progress_update_trust">"updating trust info…"</string>
|
||||
|
||||
<string name="progress_verifying_keyserver_connection">"verifying connection…"</string>
|
||||
|
||||
@@ -1146,39 +1144,6 @@
|
||||
<string name="msg_mf_unlock_error">"Error unlocking keyring!"</string>
|
||||
<string name="msg_mf_unlock">"Unlocking keyring"</string>
|
||||
|
||||
<!-- Consolidate -->
|
||||
<string name="msg_con">"Consolidating database"</string>
|
||||
<string name="msg_con_error_bad_state">"Consolidation was started while no database was cached! This is probably a programming error, please file a bug report."</string>
|
||||
<string name="msg_con_error_concurrent">"Consolidation aborted, already running on other thread!"</string>
|
||||
<string name="msg_con_save_secret">"Saving secret keyrings"</string>
|
||||
<string name="msg_con_save_public">"Saving public keyrings"</string>
|
||||
<string name="msg_con_db_clear">"Clearing database"</string>
|
||||
<string name="msg_con_success">"Successfully consolidated database"</string>
|
||||
<string name="msg_con_critical_in">"Entering critical phase"</string>
|
||||
<string name="msg_con_critical_out">"Leaving critical phase"</string>
|
||||
<string name="msg_con_delete_public">"Deleting public keyring cache file"</string>
|
||||
<string name="msg_con_delete_secret">"Deleting secret keyring cache file"</string>
|
||||
<string name="msg_con_error_db">"Error opening database!"</string>
|
||||
<string name="msg_con_error_io_public">"IO error writing public keys to cache!"</string>
|
||||
<string name="msg_con_error_io_secret">"IO error writing secret keys to cache!"</string>
|
||||
<string name="msg_con_error_public">"Error reimporting public keys!"</string>
|
||||
<string name="msg_con_error_secret">"Error reimporting secret keys!"</string>
|
||||
<string name="msg_con_recover">"Resuming consolidation process"</string>
|
||||
<string name="msg_con_recursive">"Skipping recursive consolidation"</string>
|
||||
<string name="msg_con_recover_unknown">"Resuming consolidation process from unknown state"</string>
|
||||
<plurals name="msg_con_reimport_public">
|
||||
<item quantity="one">"Reimporting one public key"</item>
|
||||
<item quantity="other">"Reimporting %d public keys"</item>
|
||||
</plurals>
|
||||
<string name="msg_con_reimport_public_skip">"No public keys to reimport, skipping…"</string>
|
||||
<plurals name="msg_con_reimport_secret">
|
||||
<item quantity="one">"Reimporting one secret key"</item>
|
||||
<item quantity="other">"Reimporting %d secret keys"</item>
|
||||
</plurals>
|
||||
<string name="msg_con_reimport_secret_skip">"No secret keys to reimport, skipping…"</string>
|
||||
<string name="msg_con_warn_delete_public">"Exception deleting public cache file"</string>
|
||||
<string name="msg_con_warn_delete_secret">"Exception deleting secret cache file"</string>
|
||||
|
||||
<!-- Edit Key (higher level than modify) -->
|
||||
<string name="msg_ed">"Performing key operation"</string>
|
||||
<string name="msg_ed_caching_new">"Caching new password"</string>
|
||||
@@ -1384,7 +1349,6 @@
|
||||
</plurals>
|
||||
<string name="msg_del_key">"Deleting key %s"</string>
|
||||
<string name="msg_del_key_fail">"Failed deleting key %s"</string>
|
||||
<string name="msg_del_consolidate">"Consolidating database after deletion of secret key"</string>
|
||||
<plurals name="msg_del_ok">
|
||||
<item quantity="one">"Successfully deleted key"</item>
|
||||
<item quantity="other">"Successfully deleted %d keys"</item>
|
||||
@@ -1987,4 +1951,14 @@
|
||||
<string name="msg_ret_uri_null">"No Uri saved on Security Token"</string>
|
||||
<string name="msg_ret_uri_test">"Checking if found key matches: %s"</string>
|
||||
|
||||
<string name="msg_trust">"Updating trust information…"</string>
|
||||
<string name="msg_trust_ok">"Update operation successful!"</string>
|
||||
<string name="msg_trust_initialize">"Initializing key signature cache"</string>
|
||||
<string name="msg_trust_key">"Updating keys signed by %s"</string>
|
||||
<string name="msg_trust_count_none">"No keys to update"</string>
|
||||
<plurals name="msg_trust_count">
|
||||
<item quantity="one">"Updating 1 key"</item>
|
||||
<item quantity="other">"Updating %d keys"</item>
|
||||
</plurals>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -136,7 +136,7 @@ public class BackupOperationTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
|
||||
// don't log verbosely here, we're not here to test imports
|
||||
ShadowLog.stream = oldShadowStream;
|
||||
@@ -151,7 +151,7 @@ public class BackupOperationTest {
|
||||
@Test
|
||||
public void testExportAllLocalStripped() throws Exception {
|
||||
BackupOperation op = new BackupOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
// make sure there is a local cert (so the later checks that there are none are meaningful)
|
||||
assertTrue("second keyring has local certification", checkForLocal(mStaticRing2));
|
||||
@@ -250,7 +250,7 @@ public class BackupOperationTest {
|
||||
when(spyApplication.getContentResolver()).thenReturn(mockResolver);
|
||||
|
||||
BackupOperation op = new BackupOperation(spyApplication,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
BackupKeyringParcel parcel = BackupKeyringParcel.createBackupKeyringParcel(
|
||||
new long[] { mStaticRing1.getMasterKeyId() }, false, false, true, fakeOutputUri);
|
||||
@@ -307,7 +307,7 @@ public class BackupOperationTest {
|
||||
|
||||
{ // export encrypted
|
||||
BackupOperation op = new BackupOperation(spyApplication,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
BackupKeyringParcel parcel = BackupKeyringParcel.createBackupKeyringParcel(
|
||||
new long[] { mStaticRing1.getMasterKeyId() }, false, true, true, fakeOutputUri);
|
||||
@@ -325,7 +325,7 @@ public class BackupOperationTest {
|
||||
|
||||
{
|
||||
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder()
|
||||
.setAllowSymmetricDecryption(true)
|
||||
|
||||
@@ -47,7 +47,7 @@ public class BenchmarkOperationTest {
|
||||
@Test
|
||||
public void testBenchmark() throws Exception {
|
||||
BenchmarkOperation op = new BenchmarkOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
op.execute(BenchmarkInputParcel.newInstance(), null);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ public class CertifyOperationTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
|
||||
// don't log verbosely here, we're not here to test imports
|
||||
ShadowLog.stream = oldShadowStream;
|
||||
@@ -133,7 +133,7 @@ public class CertifyOperationTest {
|
||||
@Test
|
||||
public void testSelfCertifyFlag() throws Exception {
|
||||
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.getCanonicalizedPublicKeyRing(mStaticRing1.getMasterKeyId());
|
||||
Assert.assertEquals("secret key must be marked self-certified in database",
|
||||
// TODO this should be more correctly be VERIFIED_SELF at some point!
|
||||
@@ -144,10 +144,10 @@ public class CertifyOperationTest {
|
||||
@Test
|
||||
public void testCertifyId() throws Exception {
|
||||
CertifyOperation op = new CertifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
|
||||
|
||||
{
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
|
||||
Assert.assertEquals("public key must not be marked verified prior to certification",
|
||||
Certs.UNVERIFIED, ring.getVerified());
|
||||
@@ -161,7 +161,7 @@ public class CertifyOperationTest {
|
||||
Assert.assertTrue("certification must succeed", result.success());
|
||||
|
||||
{
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
|
||||
Assert.assertEquals("new key must be verified now",
|
||||
Certs.VERIFIED_SECRET, ring.getVerified());
|
||||
@@ -172,10 +172,10 @@ public class CertifyOperationTest {
|
||||
@Test
|
||||
public void testCertifyAttribute() throws Exception {
|
||||
CertifyOperation op = new CertifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
|
||||
|
||||
{
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
|
||||
Assert.assertEquals("public key must not be marked verified prior to certification",
|
||||
Certs.UNVERIFIED, ring.getVerified());
|
||||
@@ -189,7 +189,7 @@ public class CertifyOperationTest {
|
||||
Assert.assertTrue("certification must succeed", result.success());
|
||||
|
||||
{
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
|
||||
Assert.assertEquals("new key must be verified now",
|
||||
Certs.VERIFIED_SECRET, ring.getVerified());
|
||||
@@ -201,7 +201,7 @@ public class CertifyOperationTest {
|
||||
@Test
|
||||
public void testCertifySelf() throws Exception {
|
||||
CertifyOperation op = new CertifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
|
||||
|
||||
CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId());
|
||||
actions.addAction(CertifyAction.createForUserIds(mStaticRing1.getMasterKeyId(),
|
||||
@@ -218,7 +218,7 @@ public class CertifyOperationTest {
|
||||
public void testCertifyNonexistent() throws Exception {
|
||||
|
||||
CertifyOperation op = new CertifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
|
||||
|
||||
{
|
||||
CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId());
|
||||
|
||||
@@ -92,7 +92,7 @@ public class PromoteKeyOperationTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
|
||||
// don't log verbosely here, we're not here to test imports
|
||||
ShadowLog.stream = oldShadowStream;
|
||||
@@ -106,7 +106,7 @@ public class PromoteKeyOperationTest {
|
||||
@Test
|
||||
public void testPromote() throws Exception {
|
||||
PromoteKeyOperation op = new PromoteKeyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
|
||||
|
||||
PromoteKeyResult result = op.execute(
|
||||
PromoteKeyringParcel.createPromoteKeyringParcel(mStaticRing.getMasterKeyId(), null, null), null);
|
||||
@@ -114,7 +114,7 @@ public class PromoteKeyOperationTest {
|
||||
Assert.assertTrue("promotion must succeed", result.success());
|
||||
|
||||
{
|
||||
CachedPublicKeyRing ring = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
CachedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.getCachedPublicKeyRing(mStaticRing.getMasterKeyId());
|
||||
Assert.assertTrue("key must have a secret now", ring.hasAnySecret());
|
||||
|
||||
@@ -131,7 +131,7 @@ public class PromoteKeyOperationTest {
|
||||
@Test
|
||||
public void testPromoteDivert() throws Exception {
|
||||
PromoteKeyOperation op = new PromoteKeyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
|
||||
|
||||
byte[] aid = Hex.decode("D2760001240102000000012345670000");
|
||||
|
||||
@@ -141,7 +141,7 @@ public class PromoteKeyOperationTest {
|
||||
Assert.assertTrue("promotion must succeed", result.success());
|
||||
|
||||
{
|
||||
CanonicalizedSecretKeyRing ring = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
CanonicalizedSecretKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.getCanonicalizedSecretKeyRing(mStaticRing.getMasterKeyId());
|
||||
|
||||
for (CanonicalizedSecretKey key : ring.secretKeyIterator()) {
|
||||
@@ -157,7 +157,7 @@ public class PromoteKeyOperationTest {
|
||||
@Test
|
||||
public void testPromoteDivertSpecific() throws Exception {
|
||||
PromoteKeyOperation op = new PromoteKeyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
|
||||
|
||||
byte[] aid = Hex.decode("D2760001240102000000012345670000");
|
||||
|
||||
@@ -171,7 +171,7 @@ public class PromoteKeyOperationTest {
|
||||
Assert.assertTrue("promotion must succeed", result.success());
|
||||
|
||||
{
|
||||
CanonicalizedSecretKeyRing ring = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
CanonicalizedSecretKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.getCanonicalizedSecretKeyRing(mStaticRing.getMasterKeyId());
|
||||
|
||||
for (CanonicalizedSecretKey key : ring.secretKeyIterator()) {
|
||||
|
||||
@@ -126,7 +126,7 @@ public class InputDataOperationTest {
|
||||
when(spyApplication.getContentResolver()).thenReturn(mockResolver);
|
||||
|
||||
InputDataOperation op = new InputDataOperation(spyApplication,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputDataParcel input = InputDataParcel.createInputDataParcel(fakeInputUri, null);
|
||||
|
||||
@@ -306,7 +306,7 @@ public class InputDataOperationTest {
|
||||
when(spyApplication.getContentResolver()).thenReturn(mockResolver);
|
||||
|
||||
InputDataOperation op = new InputDataOperation(spyApplication,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputDataParcel input = InputDataParcel.createInputDataParcel(FAKE_CONTENT_INPUT_URI_1, null);
|
||||
return op.execute(input, CryptoInputParcel.createCryptoInputParcel());
|
||||
|
||||
@@ -149,7 +149,7 @@ public class PgpEncryptDecryptTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
|
||||
// don't log verbosely here, we're not here to test imports
|
||||
ShadowLog.stream = oldShadowStream;
|
||||
@@ -173,7 +173,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -197,7 +197,7 @@ public class PgpEncryptDecryptTest {
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder()
|
||||
.setAllowSymmetricDecryption(true)
|
||||
.build();
|
||||
@@ -228,7 +228,7 @@ public class PgpEncryptDecryptTest {
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder()
|
||||
.setAllowSymmetricDecryption(true)
|
||||
.build();
|
||||
@@ -251,7 +251,7 @@ public class PgpEncryptDecryptTest {
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder()
|
||||
.setAllowSymmetricDecryption(true)
|
||||
.build();
|
||||
@@ -273,7 +273,7 @@ public class PgpEncryptDecryptTest {
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build();
|
||||
DecryptVerifyResult result = op.execute(input,
|
||||
CryptoInputParcel.createCryptoInputParcel(), data, out);
|
||||
@@ -299,7 +299,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -354,7 +354,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -415,7 +415,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -472,7 +472,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -574,7 +574,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -625,11 +625,11 @@ public class PgpEncryptDecryptTest {
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1));
|
||||
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
databaseInteractor.saveSecretKeyRing(modified);
|
||||
|
||||
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder()
|
||||
.setInputBytes(ciphertext)
|
||||
.build();
|
||||
@@ -650,11 +650,11 @@ public class PgpEncryptDecryptTest {
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1));
|
||||
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
databaseInteractor.saveSecretKeyRing(modified);
|
||||
|
||||
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder()
|
||||
.setInputBytes(ciphertext)
|
||||
.build();
|
||||
@@ -681,7 +681,7 @@ public class PgpEncryptDecryptTest {
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1));
|
||||
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
databaseInteractor.saveSecretKeyRing(modified);
|
||||
}
|
||||
|
||||
@@ -691,7 +691,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -735,7 +735,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -830,7 +830,7 @@ public class PgpEncryptDecryptTest {
|
||||
{ // decryption with passphrase cached should succeed for the other key if first is gone
|
||||
|
||||
// delete first key from database
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application).getContentResolver().delete(
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application).getContentResolver().delete(
|
||||
KeyRingData.buildPublicKeyRingUri(mStaticRing1.getMasterKeyId()), null, null
|
||||
);
|
||||
|
||||
@@ -865,7 +865,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -911,7 +911,7 @@ public class PgpEncryptDecryptTest {
|
||||
{ // decryption with passphrase cached should succeed for the other key if first is gone
|
||||
|
||||
// delete first key from database
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application).getContentResolver().delete(
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application).getContentResolver().delete(
|
||||
KeyRingData.buildPublicKeyRingUri(mStaticRing1.getMasterKeyId()), null, null
|
||||
);
|
||||
|
||||
@@ -950,7 +950,7 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaindata);
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
@@ -1068,7 +1068,7 @@ public class PgpEncryptDecryptTest {
|
||||
final Passphrase passphrase, final Long checkMasterKeyId, final Long checkSubKeyId) {
|
||||
|
||||
return new PgpDecryptVerifyOperation(RuntimeEnvironment.application,
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null) {
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application), null) {
|
||||
@Override
|
||||
public Passphrase getCachedPassphrase(long masterKeyId, long subKeyId)
|
||||
throws NoSecretKeyException {
|
||||
|
||||
@@ -68,7 +68,7 @@ public class EddsaTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
context = RuntimeEnvironment.application;
|
||||
keyRepository = KeyWritableRepository.createDatabaseReadWriteInteractor(context);
|
||||
keyRepository = KeyWritableRepository.create(context);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@@ -44,7 +43,7 @@ import java.util.Iterator;
|
||||
public class KeyRepositorySaveTest {
|
||||
|
||||
KeyWritableRepository mDatabaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpOnce() throws Exception {
|
||||
@@ -62,17 +61,17 @@ public class KeyRepositorySaveTest {
|
||||
SaveKeyringResult result;
|
||||
|
||||
// insert both keys, second should fail
|
||||
result = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application).savePublicKeyRing(first);
|
||||
result = KeyWritableRepository.create(RuntimeEnvironment.application).savePublicKeyRing(first);
|
||||
Assert.assertTrue("first keyring import should succeed", result.success());
|
||||
result = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application).savePublicKeyRing(second);
|
||||
result = KeyWritableRepository.create(RuntimeEnvironment.application).savePublicKeyRing(second);
|
||||
Assert.assertFalse("second keyring import should fail", result.success());
|
||||
|
||||
new KeychainDatabase(RuntimeEnvironment.application).clearDatabase();
|
||||
|
||||
// and the other way around
|
||||
result = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application).savePublicKeyRing(second);
|
||||
result = KeyWritableRepository.create(RuntimeEnvironment.application).savePublicKeyRing(second);
|
||||
Assert.assertTrue("first keyring import should succeed", result.success());
|
||||
result = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application).savePublicKeyRing(first);
|
||||
result = KeyWritableRepository.create(RuntimeEnvironment.application).savePublicKeyRing(first);
|
||||
Assert.assertFalse("second keyring import should fail", result.success());
|
||||
|
||||
}
|
||||
@@ -91,14 +90,14 @@ public class KeyRepositorySaveTest {
|
||||
SaveKeyringResult result;
|
||||
|
||||
// insert secret, this should fail because of missing self-cert
|
||||
result = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
result = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.saveSecretKeyRing(seckey);
|
||||
Assert.assertFalse("secret keyring import before pubring import should fail", result.success());
|
||||
|
||||
// insert pubkey, then seckey - both should succeed
|
||||
result = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application).savePublicKeyRing(pubkey);
|
||||
result = KeyWritableRepository.create(RuntimeEnvironment.application).savePublicKeyRing(pubkey);
|
||||
Assert.assertTrue("public keyring import should succeed", result.success());
|
||||
result = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application)
|
||||
result = KeyWritableRepository.create(RuntimeEnvironment.application)
|
||||
.saveSecretKeyRing(seckey);
|
||||
Assert.assertTrue("secret keyring import after pubring import should succeed", result.success());
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public class KeychainExternalProviderTest {
|
||||
|
||||
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application);
|
||||
KeyWritableRepository.create(RuntimeEnvironment.application);
|
||||
ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver();
|
||||
ApiPermissionHelper apiPermissionHelper;
|
||||
ApiDataAccessObject apiDao;
|
||||
|
||||
@@ -52,7 +52,7 @@ public class KeyringTestingHelper {
|
||||
public boolean addKeyring(Collection<String> blobFiles) throws Exception {
|
||||
|
||||
KeyWritableRepository databaseInteractor =
|
||||
KeyWritableRepository.createDatabaseReadWriteInteractor(context);
|
||||
KeyWritableRepository.create(context);
|
||||
|
||||
byte[] data = TestDataUtil.readAllFully(blobFiles);
|
||||
UncachedKeyRing ring = UncachedKeyRing.decodeFromData(data);
|
||||
|
||||
Reference in New Issue
Block a user