consolidate: working implementation, lacking ui

This commit is contained in:
Vincent Breitmoser
2014-08-17 03:29:03 +02:00
parent aa625d4fbf
commit 14290c3ce9
9 changed files with 302 additions and 15 deletions

View File

@@ -349,7 +349,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
copy(in, out);
}
// for test cases ONLY!!
// DANGEROUS
public void clearDatabase() {
getWritableDatabase().execSQL("delete from " + Tables.KEY_RINGS_PUBLIC);
}

View File

@@ -28,12 +28,14 @@ import android.os.RemoteException;
import android.support.v4.util.LongSparseArray;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.NullProgressable;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpImportExport;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
@@ -51,9 +53,12 @@ import org.sufficientlysecure.keychain.remote.AppSettings;
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel;
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType;
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult;
import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult;
import org.sufficientlysecure.keychain.util.FileImportCache;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -63,6 +68,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -97,14 +103,6 @@ public class ProviderHelper {
mIndent = indent;
}
public void resetLog() {
if(mLog != null) {
// Start a new log (leaving the old one intact)
mLog = new OperationLog();
mIndent = 0;
}
}
public OperationLog getLog() {
return mLog;
}
@@ -825,6 +823,173 @@ public class ProviderHelper {
}
public ConsolidateResult consolidateDatabase(Progressable progress) {
// 1a. fetch all secret keyrings into a cache file
int numSecrets, numPublics;
log(LogLevel.START, LogType.MSG_CON, mIndent);
mIndent += 1;
try {
log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_SECRET, mIndent);
mIndent += 1;
final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[] {
KeyRings.PRIVKEY_DATA, KeyRings.FINGERPRINT, KeyRings.HAS_ANY_SECRET
}, KeyRings.HAS_ANY_SECRET + " = 1", null, null);
if (cursor == null || !cursor.moveToFirst()) {
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog);
}
numSecrets = cursor.getCount();
FileImportCache<ParcelableKeyRing> cache =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
cache.writeCache(new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring;
@Override
public boolean hasNext() {
if (ring != null) {
return true;
}
if (cursor.isAfterLast()) {
return false;
}
ring = new ParcelableKeyRing(cursor.getBlob(0),
PgpKeyHelper.convertFingerprintToHex(cursor.getBlob(1)));
cursor.moveToNext();
return true;
}
@Override
public ParcelableKeyRing next() {
try {
return ring;
} finally {
ring = null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
});
} catch (IOException e) {
Log.e(Constants.TAG, "error saving secret");
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog);
} finally {
mIndent -= 1;
}
// 1b. fetch all public keyrings into a cache file
try {
log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_PUBLIC, mIndent);
mIndent += 1;
final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[] {
KeyRings.PUBKEY_DATA, KeyRings.FINGERPRINT
}, null, null, null);
if (cursor == null || !cursor.moveToFirst()) {
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog);
}
numPublics = cursor.getCount();
FileImportCache<ParcelableKeyRing> cache =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl");
cache.writeCache(new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring;
@Override
public boolean hasNext() {
if (ring != null) {
return true;
}
if (cursor.isAfterLast()) {
return false;
}
ring = new ParcelableKeyRing(cursor.getBlob(0),
PgpKeyHelper.convertFingerprintToHex(cursor.getBlob(1)));
cursor.moveToNext();
return true;
}
@Override
public ParcelableKeyRing next() {
try {
return ring;
} finally {
ring = null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
});
} catch (IOException e) {
Log.e(Constants.TAG, "error saving public");
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog);
} finally {
mIndent -= 1;
}
// 2. wipe database (IT'S DANGEROUS)
log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR, mIndent);
new KeychainDatabase(mContext).clearDatabase();
// 3. Re-Import secret keyrings from cache
try {
log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET, mIndent, numSecrets);
mIndent += 1;
FileImportCache<ParcelableKeyRing> cache =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
new PgpImportExport(mContext, this, new ProgressScaler(progress, 10, 25, 100))
.importKeyRings(cache.readCache(), numSecrets);
} catch (IOException e) {
Log.e(Constants.TAG, "error importing secret");
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog);
} finally {
mIndent -= 1;
}
// 3. Re-Import public keyrings from cache
try {
log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC, mIndent, numPublics);
mIndent += 1;
FileImportCache<ParcelableKeyRing> cache =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl");
new PgpImportExport(mContext, this, new ProgressScaler(progress, 25, 99, 100))
.importKeyRings(cache.readCache(), numPublics);
} catch (IOException e) {
Log.e(Constants.TAG, "error importing public");
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog);
} finally {
mIndent -= 1;
}
progress.setProgress(100, 100);
log(LogLevel.OK, LogType.MSG_CON_SUCCESS, mIndent);
mIndent -= 1;
return new ConsolidateResult(ConsolidateResult.RESULT_OK, mLog);
}
/**
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
*/