aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThialfihar <thialfihar@gmail.com>2010-07-24 14:24:42 +0000
committerThialfihar <thialfihar@gmail.com>2010-07-24 14:24:42 +0000
commitb650b30a115131c070d925d4237871f73a4ebc15 (patch)
tree9cecd9e1c7e86917cd719ee706d2b4a5b18a8b60 /src
parent2407f3b9892ddb0d34cfc5c674b6d4e3a6d06b51 (diff)
downloadopen-keychain-b650b30a115131c070d925d4237871f73a4ebc15.tar.gz
open-keychain-b650b30a115131c070d925d4237871f73a4ebc15.tar.bz2
open-keychain-b650b30a115131c070d925d4237871f73a4ebc15.zip
added secure file deletion, overwriting the file with random data before actual deletion
Update issue 56 Added a method for secure file deletion. We'll possibly have to test this a bit and make sure it actually *is* secure on the filesystems used (vfat for SD card, yaffs2 for phone flash memory by default). This sort of overwrite might be absolutely useless on some filesystems. I also wanted to add an option at first, but this seems reasonably fast and in general it should be what the user wants, so for now it will ALWAYS securely delete. If there is a demand for plain deletion, then options can be added. Update issue 39 A new string: <string name="progress_deletingSecurely">deleting \'%s\' securely...</string>
Diffstat (limited to 'src')
-rw-r--r--src/org/thialfihar/android/apg/Apg.java22
-rw-r--r--src/org/thialfihar/android/apg/BaseActivity.java71
-rw-r--r--src/org/thialfihar/android/apg/DecryptActivity.java3
-rw-r--r--src/org/thialfihar/android/apg/EncryptActivity.java3
-rw-r--r--src/org/thialfihar/android/apg/Id.java2
5 files changed, 82 insertions, 19 deletions
diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java
index 5983bef1b..725136ef2 100644
--- a/src/org/thialfihar/android/apg/Apg.java
+++ b/src/org/thialfihar/android/apg/Apg.java
@@ -20,10 +20,12 @@ import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
+import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.RandomAccessFile;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPairGenerator;
@@ -1895,4 +1897,24 @@ public class Apg {
}
return size;
}
+
+ static void deleteFileSecurely(Context context, File file, ProgressDialogUpdater progress)
+ throws FileNotFoundException, IOException {
+ long length = file.length();
+ SecureRandom random = new SecureRandom();
+ RandomAccessFile raf = new RandomAccessFile(file, "rws");
+ raf.seek(0);
+ raf.getFilePointer();
+ byte[] data = new byte[1 << 16];
+ int pos = 0;
+ String msg = context.getString(R.string.progress_deletingSecurely, file.getName());
+ while (pos < length) {
+ progress.setProgress(msg, (int)(100 * pos / length), 100);
+ random.nextBytes(data);
+ raf.write(data);
+ pos += data.length;
+ }
+ raf.close();
+ file.delete();
+ }
}
diff --git a/src/org/thialfihar/android/apg/BaseActivity.java b/src/org/thialfihar/android/apg/BaseActivity.java
index 4a0360b25..bea8f1caf 100644
--- a/src/org/thialfihar/android/apg/BaseActivity.java
+++ b/src/org/thialfihar/android/apg/BaseActivity.java
@@ -17,6 +17,8 @@
package org.thialfihar.android.apg;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.Locale;
import android.app.Activity;
@@ -44,6 +46,7 @@ public class BaseActivity extends Activity
private ProgressDialog mProgressDialog = null;
private Thread mRunningThread = null;
+ private Thread mDeletingThread = null;
private long mSecretKeyId = 0;
private String mDeleteFile = null;
@@ -149,6 +152,11 @@ public class BaseActivity extends Activity
return mProgressDialog;
}
+ case Id.dialog.deleting: {
+ mProgressDialog.setMessage(this.getString(R.string.progress_initializing));
+ return mProgressDialog;
+ }
+
default: {
break;
}
@@ -235,19 +243,30 @@ public class BaseActivity extends Activity
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
removeDialog(Id.dialog.delete_file);
- File file = new File(getDeleteFile());
- String msg = "";
- if (file.delete()) {
- msg = BaseActivity.this.getString(
- R.string.fileDeleteSuccessful);
- } else {
- msg = BaseActivity.this.getString(
- R.string.errorMessage,
- BaseActivity.this.getString(
- R.string.error_fileDeleteFailed, file));
- }
- Toast.makeText(BaseActivity.this,
- msg, Toast.LENGTH_SHORT).show();
+ final File file = new File(getDeleteFile());
+ showDialog(Id.dialog.deleting);
+ mDeletingThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Bundle data = new Bundle();
+ data.putInt(Apg.EXTRA_STATUS, Id.message.delete_done);
+ try {
+ Apg.deleteFileSecurely(BaseActivity.this, file, BaseActivity.this);
+ } catch (FileNotFoundException e) {
+ data.putString(Apg.EXTRA_ERROR,
+ BaseActivity.this.getString(
+ R.string.error_fileNotFound, file));
+ } catch (IOException e) {
+ data.putString(Apg.EXTRA_ERROR,
+ BaseActivity.this.getString(
+ R.string.error_fileDeleteFailed, file));
+ }
+ Message msg = new Message();
+ msg.setData(data);
+ sendMessage(msg);
+ }
+ });
+ mDeletingThread.start();
}
});
alert.setNegativeButton(android.R.string.cancel,
@@ -335,8 +354,14 @@ public class BaseActivity extends Activity
break;
}
- case Id.message.import_done: // intentionall no break
- case Id.message.export_done: // intentionall no break
+ case Id.message.delete_done: {
+ mProgressDialog = null;
+ deleteDoneCallback(msg);
+ break;
+ }
+
+ case Id.message.import_done: // intentionally no break
+ case Id.message.export_done: // intentionally no break
case Id.message.done: {
mProgressDialog = null;
doneCallback(msg);
@@ -349,6 +374,22 @@ public class BaseActivity extends Activity
}
+ public void deleteDoneCallback(Message msg) {
+ removeDialog(Id.dialog.deleting);
+ mDeletingThread = null;
+
+ Bundle data = msg.getData();
+ String error = data.getString(Apg.EXTRA_ERROR);
+ String message;
+ if (error != null) {
+ message = getString(R.string.errorMessage, error);
+ } else {
+ message = getString(R.string.fileDeleteSuccessful);
+ }
+
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ }
+
public void passPhraseCallback(long keyId, String passPhrase) {
Apg.setCachedPassPhrase(keyId, passPhrase);
}
diff --git a/src/org/thialfihar/android/apg/DecryptActivity.java b/src/org/thialfihar/android/apg/DecryptActivity.java
index d8b7ccd9c..f5e35c584 100644
--- a/src/org/thialfihar/android/apg/DecryptActivity.java
+++ b/src/org/thialfihar/android/apg/DecryptActivity.java
@@ -545,8 +545,7 @@ public class DecryptActivity extends BaseActivity {
String error = data.getString(Apg.EXTRA_ERROR);
if (error != null) {
- Toast.makeText(DecryptActivity.this,
- getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
return;
}
diff --git a/src/org/thialfihar/android/apg/EncryptActivity.java b/src/org/thialfihar/android/apg/EncryptActivity.java
index 4854f355c..5d69d8563 100644
--- a/src/org/thialfihar/android/apg/EncryptActivity.java
+++ b/src/org/thialfihar/android/apg/EncryptActivity.java
@@ -779,8 +779,7 @@ public class EncryptActivity extends BaseActivity {
Bundle data = msg.getData();
String error = data.getString(Apg.EXTRA_ERROR);
if (error != null) {
- Toast.makeText(EncryptActivity.this,
- getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
return;
}
switch (mEncryptTarget) {
diff --git a/src/org/thialfihar/android/apg/Id.java b/src/org/thialfihar/android/apg/Id.java
index 9ff484271..73ac39218 100644
--- a/src/org/thialfihar/android/apg/Id.java
+++ b/src/org/thialfihar/android/apg/Id.java
@@ -46,6 +46,7 @@ public final class Id {
public static final int export_done = 0x21070006;
public static final int create_key = 0x21070007;
public static final int edit_key = 0x21070008;
+ public static final int delete_done = 0x21070009;
}
public static final class request {
@@ -74,6 +75,7 @@ public final class Id {
public static final int change_log = 0x21070010;
public static final int output_filename = 0x21070011;
public static final int delete_file = 0x21070012;
+ public static final int deleting = 0x21070013;
}
public static final class task {