Merge pull request #2167 from open-keychain/ditch-consolidate

Ditch "consolidate" mechanism
This commit is contained in:
Vincent Breitmoser
2017-10-02 16:46:12 +02:00
committed by GitHub
59 changed files with 379 additions and 798 deletions

View File

@@ -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()) {

View File

@@ -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() {

View File

@@ -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" />

View File

@@ -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";

View File

@@ -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) {

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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];
}
};
}

View File

@@ -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);

View File

@@ -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;
}
}
/**

View File

@@ -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()

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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());

View File

@@ -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));

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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(

View File

@@ -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);
}

View File

@@ -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));

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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!");

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;

View File

@@ -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"

View File

@@ -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>

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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()) {

View File

@@ -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());

View File

@@ -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 {

View File

@@ -68,7 +68,7 @@ public class EddsaTest {
@Before
public void setUp() throws Exception {
context = RuntimeEnvironment.application;
keyRepository = KeyWritableRepository.createDatabaseReadWriteInteractor(context);
keyRepository = KeyWritableRepository.create(context);
}

View File

@@ -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());

View File

@@ -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;

View File

@@ -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);