fixes for symmetric encryption check and securely deleting reworked

This commit is contained in:
Dominik 2012-06-19 02:25:03 +03:00
parent 1de42b0bfb
commit 437ec9c49a
5 changed files with 229 additions and 83 deletions

View File

@ -1304,7 +1304,7 @@ public class Apg {
context.getString(R.string.error_noEncryptionKeysOrPassPhrase)); context.getString(R.string.error_noEncryptionKeysOrPassPhrase));
} }
if (signatureKeyId != -1) { if (signatureKeyId != Id.key.none) {
signingKeyRing = getSecretKeyRing(signatureKeyId); signingKeyRing = getSecretKeyRing(signatureKeyId);
signingKey = getSigningKey(signatureKeyId); signingKey = getSigningKey(signatureKeyId);
if (signingKey == null) { if (signingKey == null) {
@ -1347,7 +1347,7 @@ public class Apg {
PGPSignatureGenerator signatureGenerator = null; PGPSignatureGenerator signatureGenerator = null;
PGPV3SignatureGenerator signatureV3Generator = null; PGPV3SignatureGenerator signatureV3Generator = null;
if (signatureKeyId != -1) { if (signatureKeyId != Id.key.none) {
if (progress != null) if (progress != null)
progress.setProgress(R.string.progress_preparingSignature, 10, 100); progress.setProgress(R.string.progress_preparingSignature, 10, 100);
if (forceV3Signature) { if (forceV3Signature) {
@ -1374,7 +1374,7 @@ public class Apg {
compressGen = new PGPCompressedDataGenerator(compression); compressGen = new PGPCompressedDataGenerator(compression);
bcpgOut = new BCPGOutputStream(compressGen.open(encryptOut)); bcpgOut = new BCPGOutputStream(compressGen.open(encryptOut));
} }
if (signatureKeyId != -1) { if (signatureKeyId != Id.key.none) {
if (forceV3Signature) { if (forceV3Signature) {
signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut);
} else { } else {
@ -1395,7 +1395,7 @@ public class Apg {
InputStream in = data.getInputStream(); InputStream in = data.getInputStream();
while ((n = in.read(buffer)) > 0) { while ((n = in.read(buffer)) > 0) {
pOut.write(buffer, 0, n); pOut.write(buffer, 0, n);
if (signatureKeyId != -1) { if (signatureKeyId != Id.key.none) {
if (forceV3Signature) { if (forceV3Signature) {
signatureV3Generator.update(buffer, 0, n); signatureV3Generator.update(buffer, 0, n);
} else { } else {
@ -1411,7 +1411,7 @@ public class Apg {
literalGen.close(); literalGen.close();
if (signatureKeyId != -1) { if (signatureKeyId != Id.key.none) {
if (progress != null) if (progress != null)
progress.setProgress(R.string.progress_generatingSignature, 95, 100); progress.setProgress(R.string.progress_generatingSignature, 95, 100);
if (forceV3Signature) { if (forceV3Signature) {

View File

@ -22,16 +22,14 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Apg; import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.DataDestination;
import org.thialfihar.android.apg.DataSource;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.InputData; import org.thialfihar.android.apg.InputData;
import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.Preferences;
@ -82,10 +80,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// encrypt // encrypt
public static final String SECRET_KEY_ID = "secret_key_id"; public static final String SECRET_KEY_ID = "secret_key_id";
// public static final String DATA_SOURCE = "data_source";
// public static final String DATA_DESTINATION = "data_destination";
public static final String USE_ASCII_AMOR = "use_ascii_amor"; public static final String USE_ASCII_AMOR = "use_ascii_amor";
// public static final String ENCRYPTION_TARGET = "encryption_target";
public static final String ENCRYPTION_KEYS_IDS = "encryption_keys_ids"; public static final String ENCRYPTION_KEYS_IDS = "encryption_keys_ids";
public static final String SIGNATURE_KEY_ID = "signature_key_id"; public static final String SIGNATURE_KEY_ID = "signature_key_id";
public static final String COMPRESSION_ID = "compression_id"; public static final String COMPRESSION_ID = "compression_id";
@ -96,6 +91,9 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
public static final String OUTPUT_FILE = "output_file"; public static final String OUTPUT_FILE = "output_file";
public static final String PROVIDER_URI = "provider_uri"; public static final String PROVIDER_URI = "provider_uri";
// delete file securely
public static final String DELETE_FILE = "delete_file";
// possible ints for EXTRA_ACTION // possible ints for EXTRA_ACTION
public static final int ACTION_SAVE_KEYRING = 1; public static final int ACTION_SAVE_KEYRING = 1;
public static final int ACTION_GENERATE_KEY = 2; public static final int ACTION_GENERATE_KEY = 2;
@ -105,6 +103,8 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
public static final int ACTION_ENCRYPT_SIGN_FILE = 5; public static final int ACTION_ENCRYPT_SIGN_FILE = 5;
public static final int ACTION_ENCRYPT_SIGN_STREAM = 6; public static final int ACTION_ENCRYPT_SIGN_STREAM = 6;
public static final int ACTION_DELETE_FILE_SECURELY = 7;
// possible data keys as result // possible data keys as result
public static final String RESULT_NEW_KEY = "new_key"; public static final String RESULT_NEW_KEY = "new_key";
public static final String RESULT_NEW_KEY2 = "new_key2"; public static final String RESULT_NEW_KEY2 = "new_key2";
@ -446,6 +446,30 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
break; break;
case ACTION_DELETE_FILE_SECURELY:
try {
// Input
String deleteFile = data.getString(DELETE_FILE);
// Operation
try {
Apg.deleteFileSecurely(this, new File(deleteFile), this);
} catch (FileNotFoundException e) {
throw new Apg.GeneralException(getString(R.string.error_fileNotFound,
deleteFile));
} catch (IOException e) {
throw new Apg.GeneralException(getString(R.string.error_fileDeleteFailed,
deleteFile));
}
// Output
sendMessageToHandler(ApgHandler.MESSAGE_OKAY);
} catch (Exception e) {
sendErrorToHandler(e);
}
break;
default: default:
break; break;
} }

View File

@ -218,48 +218,48 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable,
return alert.create(); return alert.create();
} }
case Id.dialog.delete_file: { // case Id.dialog.delete_file: {
AlertDialog.Builder alert = new AlertDialog.Builder(this); // AlertDialog.Builder alert = new AlertDialog.Builder(this);
//
alert.setIcon(android.R.drawable.ic_dialog_alert); // alert.setIcon(android.R.drawable.ic_dialog_alert);
alert.setTitle(R.string.warning); // alert.setTitle(R.string.warning);
alert.setMessage(this.getString(R.string.fileDeleteConfirmation, getDeleteFile())); // alert.setMessage(this.getString(R.string.fileDeleteConfirmation, getDeleteFile()));
//
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { // alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { // public void onClick(DialogInterface dialog, int id) {
removeDialog(Id.dialog.delete_file); // removeDialog(Id.dialog.delete_file);
final File file = new File(getDeleteFile()); // final File file = new File(getDeleteFile());
showDialog(Id.dialog.deleting); // showDialog(Id.dialog.deleting);
mDeletingThread = new Thread(new Runnable() { // mDeletingThread = new Thread(new Runnable() {
public void run() { // public void run() {
Bundle data = new Bundle(); // Bundle data = new Bundle();
data.putInt(Constants.extras.STATUS, Id.message.delete_done); // data.putInt(Constants.extras.STATUS, Id.message.delete_done);
try { // try {
Apg.deleteFileSecurely(BaseActivity.this, file, BaseActivity.this); // Apg.deleteFileSecurely(BaseActivity.this, file, BaseActivity.this);
} catch (FileNotFoundException e) { // } catch (FileNotFoundException e) {
data.putString(Apg.EXTRA_ERROR, BaseActivity.this.getString( // data.putString(Apg.EXTRA_ERROR, BaseActivity.this.getString(
R.string.error_fileNotFound, file)); // R.string.error_fileNotFound, file));
} catch (IOException e) { // } catch (IOException e) {
data.putString(Apg.EXTRA_ERROR, BaseActivity.this.getString( // data.putString(Apg.EXTRA_ERROR, BaseActivity.this.getString(
R.string.error_fileDeleteFailed, file)); // R.string.error_fileDeleteFailed, file));
} // }
Message msg = new Message(); // Message msg = new Message();
msg.setData(data); // msg.setData(data);
sendMessage(msg); // sendMessage(msg);
} // }
}); // });
mDeletingThread.start(); // mDeletingThread.start();
} // }
}); // });
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { // alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { // public void onClick(DialogInterface dialog, int id) {
removeDialog(Id.dialog.delete_file); // removeDialog(Id.dialog.delete_file);
} // }
}); // });
alert.setCancelable(true); // alert.setCancelable(true);
//
return alert.create(); // return alert.create();
} // }
default: { default: {
break; break;
@ -335,11 +335,11 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable,
break; break;
} }
case Id.message.delete_done: { // case Id.message.delete_done: {
mProgressDialog = null; // mProgressDialog = null;
deleteDoneCallback(msg); // deleteDoneCallback(msg);
break; // break;
} // }
case Id.message.import_done: // intentionally no break case Id.message.import_done: // intentionally no break
case Id.message.export_done: // intentionally no break case Id.message.export_done: // intentionally no break
@ -360,21 +360,21 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable,
} }
public void deleteDoneCallback(Message msg) { // public void deleteDoneCallback(Message msg) {
removeDialog(Id.dialog.deleting); // removeDialog(Id.dialog.deleting);
mDeletingThread = null; // mDeletingThread = null;
//
Bundle data = msg.getData(); // Bundle data = msg.getData();
String error = data.getString(Apg.EXTRA_ERROR); // String error = data.getString(Apg.EXTRA_ERROR);
String message; // String message;
if (error != null) { // if (error != null) {
message = getString(R.string.errorMessage, error); // message = getString(R.string.errorMessage, error);
} else { // } else {
message = getString(R.string.fileDeleteSuccessful); // message = getString(R.string.fileDeleteSuccessful);
} // }
//
Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); // Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
} // }
public void passPhraseCallback(long keyId, String passPhrase) { public void passPhraseCallback(long keyId, String passPhrase) {
// TODO: Not needed anymore, now implemented in AskForSecretKeyPass // TODO: Not needed anymore, now implemented in AskForSecretKeyPass

View File

@ -1,4 +1,5 @@
/* /*
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org> * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -26,6 +27,7 @@ import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.Preferences;
import org.thialfihar.android.apg.service.ApgHandler; import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService; import org.thialfihar.android.apg.service.ApgService;
import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment;
import org.thialfihar.android.apg.ui.dialog.FileDialogFragment; import org.thialfihar.android.apg.ui.dialog.FileDialogFragment;
import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment; import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment;
import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment; import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment;
@ -115,7 +117,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
private boolean mGenerateSignature = false; private boolean mGenerateSignature = false;
private long mSecretKeyId = 0; private long mSecretKeyId = Id.key.none;
private ProgressDialogFragment mEncryptingDialog; private ProgressDialogFragment mEncryptingDialog;
private FileDialogFragment mFileDialog; private FileDialogFragment mFileDialog;
@ -698,8 +700,6 @@ public class EncryptActivity extends SherlockFragmentActivity {
} }
private void askForOutputFilename() { private void askForOutputFilename() {
// showDialog(Id.dialog.output_filename);
// Message is received after passphrase is cached // Message is received after passphrase is cached
Handler returnHandler = new Handler() { Handler returnHandler = new Handler() {
@Override @Override
@ -733,7 +733,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
boolean useAsciiArmour = true; boolean useAsciiArmour = true;
long encryptionKeyIds[] = null; long encryptionKeyIds[] = null;
long signatureKeyId = -1; // -1 means no signature! long signatureKeyId = Id.key.none;
int compressionId = 0; int compressionId = 0;
boolean signOnly = false; boolean signOnly = false;
@ -743,6 +743,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
if (passPhrase.length() == 0) { if (passPhrase.length() == 0) {
passPhrase = null; passPhrase = null;
} }
// signatureKeyId = Id.key.symmetric;
data.putString(ApgService.SYMMETRIC_PASSPHRASE, passPhrase); data.putString(ApgService.SYMMETRIC_PASSPHRASE, passPhrase);
} else { } else {
@ -799,7 +800,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
intent.putExtra(ApgService.EXTRA_DATA, data); intent.putExtra(ApgService.EXTRA_DATA, data);
// show progress dialog // create progress dialog
mEncryptingDialog = ProgressDialogFragment.newInstance(R.string.progress_encrypting, mEncryptingDialog = ProgressDialogFragment.newInstance(R.string.progress_encrypting,
ProgressDialog.STYLE_HORIZONTAL); ProgressDialog.STYLE_HORIZONTAL);
@ -852,10 +853,12 @@ public class EncryptActivity extends SherlockFragmentActivity {
case Id.target.file: case Id.target.file:
Toast.makeText(EncryptActivity.this, R.string.encryptionSuccessful, Toast.makeText(EncryptActivity.this, R.string.encryptionSuccessful,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
if (mDeleteAfter.isChecked()) { if (mDeleteAfter.isChecked()) {
// TODO: Reimplement that! // Create and show dialog to delete original file
// setDeleteFile(mInputFilename); DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
// showDialog(Id.dialog.delete_file); .newInstance(mInputFilename);
deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
} }
break; break;
@ -872,7 +875,8 @@ public class EncryptActivity extends SherlockFragmentActivity {
Messenger messenger = new Messenger(saveHandler); Messenger messenger = new Messenger(saveHandler);
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger); intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
mEncryptingDialog.show(getSupportFragmentManager(), "dialog"); // show progress dialog
mEncryptingDialog.show(getSupportFragmentManager(), "encryptingDialog");
// start service with intent // start service with intent
startService(intent); startService(intent);
@ -908,7 +912,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
+ getResources().getString(R.string.nKeysSelected)); + getResources().getString(R.string.nKeysSelected));
} }
if (getSecretKeyId() == 0) { if (getSecretKeyId() == Id.key.none) {
mSign.setChecked(false); mSign.setChecked(false);
mMainUserId.setText(""); mMainUserId.setText("");
mMainUserIdRest.setText(""); mMainUserIdRest.setText("");

View File

@ -0,0 +1,118 @@
/*
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thialfihar.android.apg.ui.dialog;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;
public class DeleteFileDialogFragment extends DialogFragment {
private static final String ARG_DELETE_FILE = "delete_file";
/**
* Creates new instance of this delete file dialog fragment
*/
public static DeleteFileDialogFragment newInstance(String deleteFile) {
DeleteFileDialogFragment frag = new DeleteFileDialogFragment();
Bundle args = new Bundle();
args.putString(ARG_DELETE_FILE, deleteFile);
frag.setArguments(args);
return frag;
}
/**
* Creates dialog
*/
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final FragmentActivity activity = getActivity();
final String deleteFile = getArguments().getString(ARG_DELETE_FILE);
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
alert.setIcon(android.R.drawable.ic_dialog_alert);
alert.setTitle(R.string.warning);
alert.setMessage(this.getString(R.string.fileDeleteConfirmation, deleteFile));
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
// Send all information needed to service to edit key in other thread
Intent intent = new Intent(activity, ApgService.class);
// fill values for this action
Bundle data = new Bundle();
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_DELETE_FILE_SECURELY);
data.putString(ApgService.DELETE_FILE, deleteFile);
intent.putExtra(ApgService.EXTRA_DATA, data);
ProgressDialogFragment deletingDialog = ProgressDialogFragment.newInstance(
R.string.progress_deletingSecurely, ProgressDialog.STYLE_HORIZONTAL);
// Message is received after deleting is done in ApgService
ApgHandler saveHandler = new ApgHandler(activity, deletingDialog) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
Toast.makeText(activity, R.string.fileDeleteSuccessful,
Toast.LENGTH_SHORT).show();
}
};
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
// show progress dialog
deletingDialog.show(activity.getSupportFragmentManager(), "deletingDialog");
// start service with intent
activity.startService(intent);
}
});
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
}
});
alert.setCancelable(true);
return alert.create();
}
}