From 6fd44a0ec5fcf7d45042ca0eaaed4906ccfcdf12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 8 Jan 2013 17:48:56 +0100 Subject: [PATCH] When exporting secret keyrings, also export public part --- APG/res/values/strings.xml | 4 +- .../android/apg/helper/PGPMain.java | 84 ++++++++----------- .../android/apg/provider/ProviderHelper.java | 22 ++--- .../android/apg/service/ApgIntentService.java | 17 ++-- .../android/apg/ui/ImportKeysActivity.java | 1 + .../android/apg/ui/KeyListActivity.java | 21 +++-- .../android/apg/ui/KeyListFragment.java | 8 +- 7 files changed, 73 insertions(+), 84 deletions(-) diff --git a/APG/res/values/strings.xml b/APG/res/values/strings.xml index b5f55cdd3..0b4f3c029 100644 --- a/APG/res/values/strings.xml +++ b/APG/res/values/strings.xml @@ -345,8 +345,8 @@ Version: - Import keyring (only locally) - Import, Sign, and upload keyring + Import keyring(s) (only locally) + Import, Sign, and upload keyring(s) Finish diff --git a/APG/src/org/thialfihar/android/apg/helper/PGPMain.java b/APG/src/org/thialfihar/android/apg/helper/PGPMain.java index a8203d568..1e97b7ba4 100644 --- a/APG/src/org/thialfihar/android/apg/helper/PGPMain.java +++ b/APG/src/org/thialfihar/android/apg/helper/PGPMain.java @@ -74,7 +74,6 @@ import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactory import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; import org.thialfihar.android.apg.provider.ProviderHelper; import org.thialfihar.android.apg.service.ApgIntentService; -import org.thialfihar.android.apg.ui.dialog.SetPassphraseDialogFragment; import org.thialfihar.android.apg.util.HkpKeyServer; import org.thialfihar.android.apg.util.InputData; import org.thialfihar.android.apg.util.PositionAwareInputStream; @@ -607,12 +606,12 @@ public class PGPMain { return returnData; } - public static Bundle exportKeyRings(Context context, ArrayList keyRingRowIds, - OutputStream outStream, ProgressDialogUpdater progress) throws ApgGeneralException, - FileNotFoundException, PGPException, IOException { + public static Bundle exportKeyRings(Context context, ArrayList keyRingMasterKeyIds, + int keyType, OutputStream outStream, ProgressDialogUpdater progress) + throws ApgGeneralException, FileNotFoundException, PGPException, IOException { Bundle returnData = new Bundle(); - if (keyRingRowIds.size() == 1) { + if (keyRingMasterKeyIds.size() == 1) { updateProgress(progress, R.string.progress_exportingKey, 0, 100); } else { updateProgress(progress, R.string.progress_exportingKeys, 0, 100); @@ -621,66 +620,49 @@ public class PGPMain { if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { throw new ApgGeneralException(context.getString(R.string.error_externalStorageNotReady)); } - ArmoredOutputStream out = new ArmoredOutputStream(outStream); - out.setHeader("Version", getFullVersion(context)); + + // export public keyrings... + ArmoredOutputStream outPub = new ArmoredOutputStream(outStream); + outPub.setHeader("Version", getFullVersion(context)); int numKeys = 0; - for (int i = 0; i < keyRingRowIds.size(); ++i) { - updateProgress(progress, i * 100 / keyRingRowIds.size(), 100); - - // try to get it as a PGPPublicKeyRing, if that fails try to get it as a SecretKeyRing - PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(context, - keyRingRowIds.get(i)); - if (publicKeyRing != null) { - publicKeyRing.encode(out); + for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) { + // double the needed time if exporting both public and secret parts + if (keyType == Id.type.secret_key) { + updateProgress(progress, i * 100 / keyRingMasterKeyIds.size() / 2, 100); } else { - PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByRowId(context, - keyRingRowIds.get(i)); - if (secretKeyRing != null) { - secretKeyRing.encode(out); - } else { - continue; - } + updateProgress(progress, i * 100 / keyRingMasterKeyIds.size(), 100); + } + + PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId( + context, keyRingMasterKeyIds.get(i)); + + if (publicKeyRing != null) { + publicKeyRing.encode(outPub); } ++numKeys; } - out.close(); - returnData.putInt(ApgIntentService.RESULT_EXPORT, numKeys); + outPub.close(); - updateProgress(progress, R.string.progress_done, 100, 100); + // if we export secret keyrings, append all secret parts after the public parts + if (keyType == Id.type.secret_key) { + ArmoredOutputStream outSec = new ArmoredOutputStream(outStream); + outSec.setHeader("Version", getFullVersion(context)); - return returnData; - } + for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) { + updateProgress(progress, i * 100 / keyRingMasterKeyIds.size() / 2, 100); - public static Bundle getKeyRings(Context context, long[] masterKeyIds, OutputStream outStream, - ProgressDialogUpdater progress) throws ApgGeneralException, FileNotFoundException, - PGPException, IOException { - Bundle returnData = new Bundle(); + PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId( + context, keyRingMasterKeyIds.get(i)); - ArmoredOutputStream out = new ArmoredOutputStream(outStream); - out.setHeader("Version", getFullVersion(context)); - - int numKeys = 0; - for (int i = 0; i < masterKeyIds.length; ++i) { - updateProgress(progress, i * 100 / masterKeyIds.length, 100); - - // try to get it as a PGPPublicKeyRing, if that fails try to get it as a SecretKeyRing - PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(context, - masterKeyIds[i]); - if (publicKeyRing != null) { - publicKeyRing.encode(out); - } else { - PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByRowId(context, - masterKeyIds[i]); if (secretKeyRing != null) { - secretKeyRing.encode(out); - } else { - continue; + secretKeyRing.encode(outSec); } + ++numKeys; } - ++numKeys; + outSec.close(); } - out.close(); + returnData.putInt(ApgIntentService.RESULT_EXPORT, numKeys); updateProgress(progress, R.string.progress_done, 100, 100); diff --git a/APG/src/org/thialfihar/android/apg/provider/ProviderHelper.java b/APG/src/org/thialfihar/android/apg/provider/ProviderHelper.java index 7d715b78b..2a7ed2d19 100644 --- a/APG/src/org/thialfihar/android/apg/provider/ProviderHelper.java +++ b/APG/src/org/thialfihar/android/apg/provider/ProviderHelper.java @@ -420,16 +420,16 @@ public class ProviderHelper { * @param queryUri * @return */ - private static ArrayList getKeyRingsRowIds(Context context, Uri queryUri) { - Cursor cursor = context.getContentResolver().query(queryUri, new String[] { KeyRings._ID }, - null, null, null); + private static ArrayList getKeyRingsMasterKeyIds(Context context, Uri queryUri) { + Cursor cursor = context.getContentResolver().query(queryUri, + new String[] { KeyRings.MASTER_KEY_ID }, null, null, null); - ArrayList keyIds = new ArrayList(); + ArrayList masterKeyIds = new ArrayList(); if (cursor != null) { - int idCol = cursor.getColumnIndex(KeyRings._ID); + int masterKeyIdCol = cursor.getColumnIndex(KeyRings.MASTER_KEY_ID); if (cursor.moveToFirst()) { do { - keyIds.add(cursor.getLong(idCol)); + masterKeyIds.add(cursor.getLong(masterKeyIdCol)); } while (cursor.moveToNext()); } } @@ -438,7 +438,7 @@ public class ProviderHelper { cursor.close(); } - return keyIds; + return masterKeyIds; } /** @@ -447,9 +447,9 @@ public class ProviderHelper { * @param context * @return */ - public static ArrayList getSecretKeyRingsRowIds(Context context) { + public static ArrayList getSecretKeyRingsMasterKeyIds(Context context) { Uri queryUri = KeyRings.buildSecretKeyRingsUri(); - return getKeyRingsRowIds(context, queryUri); + return getKeyRingsMasterKeyIds(context, queryUri); } /** @@ -458,9 +458,9 @@ public class ProviderHelper { * @param context * @return */ - public static ArrayList getPublicKeyRingsRowIds(Context context) { + public static ArrayList getPublicKeyRingsMasterKeyIds(Context context) { Uri queryUri = KeyRings.buildPublicKeyRingsUri(); - return getKeyRingsRowIds(context, queryUri); + return getKeyRingsMasterKeyIds(context, queryUri); } public static void deletePublicKeyRing(Context context, long rowId) { diff --git a/APG/src/org/thialfihar/android/apg/service/ApgIntentService.java b/APG/src/org/thialfihar/android/apg/service/ApgIntentService.java index 58afa9fa8..11460c7d8 100644 --- a/APG/src/org/thialfihar/android/apg/service/ApgIntentService.java +++ b/APG/src/org/thialfihar/android/apg/service/ApgIntentService.java @@ -144,7 +144,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd public static final String EXPORT_FILENAME = "exportFilename"; public static final String EXPORT_KEY_TYPE = "exportKeyType"; public static final String EXPORT_ALL = "exportAll"; - public static final String EXPORT_KEY_RING_ROW_ID = "exportKeyRingId"; + public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "exportKeyRingId"; // upload key public static final String UPLOAD_KEY_SERVER = "uploadKeyServer"; @@ -691,9 +691,9 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd String outputFile = data.getString(EXPORT_FILENAME); boolean exportAll = data.getBoolean(EXPORT_ALL); - long keyRingRowId = -1; + long keyRingMasterKeyId = -1; if (!exportAll) { - keyRingRowId = data.getLong(EXPORT_KEY_RING_ROW_ID); + keyRingMasterKeyId = data.getLong(EXPORT_KEY_RING_MASTER_KEY_ID); } /* Operation */ @@ -706,21 +706,22 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd // OutputStream FileOutputStream outStream = new FileOutputStream(outputFile); - ArrayList keyRingRowIds = new ArrayList(); + ArrayList keyRingMasterKeyIds = new ArrayList(); if (exportAll) { // get all key ring row ids based on export type if (keyType == Id.type.public_key) { - keyRingRowIds = ProviderHelper.getPublicKeyRingsRowIds(this); + keyRingMasterKeyIds = ProviderHelper.getPublicKeyRingsMasterKeyIds(this); } else { - keyRingRowIds = ProviderHelper.getSecretKeyRingsRowIds(this); + keyRingMasterKeyIds = ProviderHelper.getSecretKeyRingsMasterKeyIds(this); } } else { - keyRingRowIds.add(keyRingRowId); + keyRingMasterKeyIds.add(keyRingMasterKeyId); } Bundle resultData = new Bundle(); - resultData = PGPMain.exportKeyRings(this, keyRingRowIds, outStream, this); + resultData = PGPMain.exportKeyRings(this, keyRingMasterKeyIds, keyType, outStream, + this); sendMessageToHandler(ApgIntentServiceHandler.MESSAGE_OKAY, resultData); } catch (Exception e) { diff --git a/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java b/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java index 355214ab5..84359f1da 100644 --- a/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java +++ b/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java @@ -441,6 +441,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity { // mScannedContent = scanResult.getContents(); mImportData = scanResult.getContents().getBytes(); + mImportFilename = null; // mContentView.setText(mScannedContent); // String[] bits = scanResult.getContents().split(","); diff --git a/APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java b/APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java index ac4798f7c..4b4a5daac 100644 --- a/APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java +++ b/APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java @@ -87,7 +87,6 @@ public class KeyListActivity extends SherlockFragmentActivity { } } - // if (searchString == null) { // mFilterLayout.setVisibility(View.GONE); // } else { @@ -134,8 +133,8 @@ public class KeyListActivity extends SherlockFragmentActivity { // TODO: reimplement! // menu.add(3, Id.menu.option.search, 0, R.string.menu_search) // .setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - menu.add(0, Id.menu.option.import_from_file, 5, R.string.menu_importFromFile).setShowAsAction( - MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + menu.add(0, Id.menu.option.import_from_file, 5, R.string.menu_importFromFile) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); menu.add(0, Id.menu.option.export_keys, 6, R.string.menu_exportKeys).setShowAsAction( MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); @@ -178,10 +177,10 @@ public class KeyListActivity extends SherlockFragmentActivity { /** * Show dialog where to export keys * - * @param keyRingRowId + * @param keyRingMasterKeyId * if -1 export all keys */ - public void showExportKeysDialog(final long keyRingRowId) { + public void showExportKeysDialog(final long keyRingMasterKeyId) { // Message is received after file is selected Handler returnHandler = new Handler() { @Override @@ -190,7 +189,7 @@ public class KeyListActivity extends SherlockFragmentActivity { Bundle data = message.getData(); mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - exportKeys(keyRingRowId); + exportKeys(keyRingMasterKeyId); } } }; @@ -201,7 +200,7 @@ public class KeyListActivity extends SherlockFragmentActivity { DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { public void run() { String title = null; - if (keyRingRowId != -1) { + if (keyRingMasterKeyId != -1) { // single key export title = getString(R.string.title_exportKey); } else { @@ -251,10 +250,10 @@ public class KeyListActivity extends SherlockFragmentActivity { /** * Export keys * - * @param keyRingRowId + * @param keyRingMasterKeyId * if -1 export all keys */ - public void exportKeys(long keyRingRowId) { + public void exportKeys(long keyRingMasterKeyId) { Log.d(Constants.TAG, "exportKeys started"); // Send all information needed to service to export key in other thread @@ -268,10 +267,10 @@ public class KeyListActivity extends SherlockFragmentActivity { data.putString(ApgIntentService.EXPORT_FILENAME, mExportFilename); data.putInt(ApgIntentService.EXPORT_KEY_TYPE, mKeyType); - if (keyRingRowId == -1) { + if (keyRingMasterKeyId == -1) { data.putBoolean(ApgIntentService.EXPORT_ALL, true); } else { - data.putLong(ApgIntentService.EXPORT_KEY_RING_ROW_ID, keyRingRowId); + data.putLong(ApgIntentService.EXPORT_KEY_RING_MASTER_KEY_ID, keyRingMasterKeyId); } intent.putExtra(ApgIntentService.EXTRA_DATA, data); diff --git a/APG/src/org/thialfihar/android/apg/ui/KeyListFragment.java b/APG/src/org/thialfihar/android/apg/ui/KeyListFragment.java index f8f62287c..dc50c2dd6 100644 --- a/APG/src/org/thialfihar/android/apg/ui/KeyListFragment.java +++ b/APG/src/org/thialfihar/android/apg/ui/KeyListFragment.java @@ -19,6 +19,7 @@ package org.thialfihar.android.apg.ui; import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.provider.ProviderHelper; import org.thialfihar.android.apg.ui.widget.ExpandableListFragment; import android.os.Bundle; @@ -66,7 +67,12 @@ public class KeyListFragment extends ExpandableListFragment { switch (item.getItemId()) { case Id.menu.export: - mKeyListActivity.showExportKeysDialog(keyRingRowId); + long masterKeyId = ProviderHelper.getPublicMasterKeyId(mKeyListActivity, keyRingRowId); + if (masterKeyId == -1) { + masterKeyId = ProviderHelper.getSecretMasterKeyId(mKeyListActivity, keyRingRowId); + } + + mKeyListActivity.showExportKeysDialog(masterKeyId); return true; case Id.menu.delete: