From 5e73b696d1ff7d39df933a6de5f89b46f8ace22a Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Sun, 9 May 2010 19:51:21 +0000 Subject: new EncryptActivity to handle message and file encryption all in one --- .../android/apg/DecryptMessageActivity.java | 2 +- .../thialfihar/android/apg/EncryptActivity.java | 783 +++++++++++++++++++++ .../android/apg/EncryptFileActivity.java | 520 -------------- .../android/apg/EncryptMessageActivity.java | 379 ---------- src/org/thialfihar/android/apg/Id.java | 1 + src/org/thialfihar/android/apg/MainActivity.java | 14 +- 6 files changed, 792 insertions(+), 907 deletions(-) create mode 100644 src/org/thialfihar/android/apg/EncryptActivity.java delete mode 100644 src/org/thialfihar/android/apg/EncryptFileActivity.java delete mode 100644 src/org/thialfihar/android/apg/EncryptMessageActivity.java (limited to 'src') diff --git a/src/org/thialfihar/android/apg/DecryptMessageActivity.java b/src/org/thialfihar/android/apg/DecryptMessageActivity.java index ea9e960e4..b2eaf589d 100644 --- a/src/org/thialfihar/android/apg/DecryptMessageActivity.java +++ b/src/org/thialfihar/android/apg/DecryptMessageActivity.java @@ -167,7 +167,7 @@ public class DecryptMessageActivity extends BaseActivity { } private void replyClicked() { - Intent intent = new Intent(this, EncryptMessageActivity.class); + Intent intent = new Intent(this, EncryptActivity.class); intent.setAction(Apg.Intent.ENCRYPT); String data = mMessage.getText().toString(); data = data.replaceAll("(?m)^", "> "); diff --git a/src/org/thialfihar/android/apg/EncryptActivity.java b/src/org/thialfihar/android/apg/EncryptActivity.java new file mode 100644 index 000000000..e98a4c785 --- /dev/null +++ b/src/org/thialfihar/android/apg/EncryptActivity.java @@ -0,0 +1,783 @@ +/* + * Copyright (C) 2010 Thialfihar + * + * 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; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SignatureException; +import java.util.Vector; + +import org.bouncycastle2.openpgp.PGPException; +import org.bouncycastle2.openpgp.PGPPublicKey; +import org.bouncycastle2.openpgp.PGPPublicKeyRing; +import org.bouncycastle2.openpgp.PGPSecretKey; +import org.bouncycastle2.openpgp.PGPSecretKeyRing; +import org.bouncycastle2.util.Strings; +import org.openintents.intents.FileManager; +import org.thialfihar.android.apg.Apg.GeneralException; + +import android.app.Dialog; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.os.Message; +import android.text.ClipboardManager; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.animation.AnimationUtils; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.ViewFlipper; + +public class EncryptActivity extends BaseActivity { + private String mSubject = null; + private String mSendTo = null; + + private long mEncryptionKeyIds[] = null; + + private EditText mMessage = null; + private Button mSelectKeysButton = null; + private Button mEncryptButton = null; + private Button mEncryptToClipboardButton = null; + private CheckBox mSign = null; + private TextView mMainUserId = null; + private TextView mMainUserIdRest = null; + + private ViewFlipper mSource = null; + private TextView mSourceLabel = null; + private ImageView mSourcePrevious = null; + private ImageView mSourceNext = null; + + private ViewFlipper mMode = null; + private TextView mModeLabel = null; + private ImageView mModePrevious = null; + private ImageView mModeNext = null; + + private int mEncryptTarget; + + private EditText mPassPhrase = null; + private EditText mPassPhraseAgain = null; + private CheckBox mAsciiArmour = null; + + private EditText mFilename = null; + private CheckBox mDeleteAfter = null; + private ImageButton mBrowse = null; + + private String mInputFilename = null; + private String mOutputFilename = null; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.encrypt); + + mSource = (ViewFlipper) findViewById(R.id.source); + mSourceLabel = (TextView) findViewById(R.id.source_label); + mSourcePrevious = (ImageView) findViewById(R.id.source_previous); + mSourceNext = (ImageView) findViewById(R.id.source_next); + + mSourcePrevious.setClickable(true); + mSourcePrevious.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_right_in)); + mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_right_out)); + mSource.showPrevious(); + updateSource(); + } + }); + + mSourceNext.setClickable(true); + OnClickListener nextSourceClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_left_in)); + mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_left_out)); + mSource.showNext(); + updateSource(); + } + }; + mSourceNext.setOnClickListener(nextSourceClickListener); + + mSourceLabel.setClickable(true); + mSourceLabel.setOnClickListener(nextSourceClickListener); + + mMode = (ViewFlipper) findViewById(R.id.mode); + mModeLabel = (TextView) findViewById(R.id.mode_label); + mModePrevious = (ImageView) findViewById(R.id.mode_previous); + mModeNext = (ImageView) findViewById(R.id.mode_next); + + mModePrevious.setClickable(true); + mModePrevious.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_right_in)); + mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_right_out)); + mMode.showPrevious(); + updateMode(); + } + }); + + OnClickListener nextModeClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_left_in)); + mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_left_out)); + mMode.showNext(); + updateMode(); + } + }; + mModeNext.setOnClickListener(nextModeClickListener); + + mModeLabel.setClickable(true); + mModeLabel.setOnClickListener(nextModeClickListener); + + mMessage = (EditText) findViewById(R.id.message); + mSelectKeysButton = (Button) findViewById(R.id.btn_selectEncryptKeys); + mEncryptButton = (Button) findViewById(R.id.btn_encrypt); + mEncryptToClipboardButton = (Button) findViewById(R.id.btn_encrypt_to_clipboard); + mSign = (CheckBox) findViewById(R.id.sign); + mMainUserId = (TextView) findViewById(R.id.main_user_id); + mMainUserIdRest = (TextView) findViewById(R.id.main_user_id_rest); + + mPassPhrase = (EditText) findViewById(R.id.pass_phrase); + mPassPhraseAgain = (EditText) findViewById(R.id.pass_phrase_again); + + // measure the height of the source_file view and set the message view's min height to that, + // so it fills mSource fully... bit of a hack. + View tmp = findViewById(R.id.source_file); + tmp.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); + int height = tmp.getMeasuredHeight(); + mMessage.setMinimumHeight(height); + + mFilename = (EditText) findViewById(R.id.filename); + mBrowse = (ImageButton) findViewById(R.id.btn_browse); + mBrowse.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + openFile(); + } + }); + + mDeleteAfter = (CheckBox) findViewById(R.id.delete_after_encryption); + + mAsciiArmour = (CheckBox) findViewById(R.id.ascii_armour); + mAsciiArmour.setChecked(getDefaultAsciiArmour()); + mAsciiArmour.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View view) { + guessOutputFilename(); + } + }); + + mEncryptToClipboardButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + encryptToClipboardClicked(); + } + }); + + mEncryptButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + encryptClicked(); + } + }); + + mSelectKeysButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + selectPublicKeys(); + } + }); + + mSign.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + CheckBox checkBox = (CheckBox) v; + if (checkBox.isChecked()) { + selectSecretKey(); + } else { + setSecretKeyId(0); + Apg.setPassPhrase(null); + updateView(); + } + } + }); + + Intent intent = getIntent(); + if (intent.getAction() != null && + (intent.getAction().equals(Apg.Intent.ENCRYPT) || + intent.getAction().equals(Apg.Intent.ENCRYPT_FILE))) { + Bundle extras = intent.getExtras(); + if (extras == null) { + extras = new Bundle(); + } + String data = extras.getString("data"); + mSendTo = extras.getString("sendTo"); + mSubject = extras.getString("subject"); + long signatureKeyId = extras.getLong("signatureKeyId"); + long encryptionKeyIds[] = extras.getLongArray("encryptionKeyIds"); + if (signatureKeyId != 0) { + PGPSecretKeyRing keyRing = Apg.findSecretKeyRing(signatureKeyId); + PGPSecretKey masterKey = null; + if (keyRing != null) { + masterKey = Apg.getMasterKey(keyRing); + if (masterKey != null) { + Vector signKeys = Apg.getUsableSigningKeys(keyRing); + if (signKeys.size() > 0) { + setSecretKeyId(masterKey.getKeyID()); + } + } + } + } + + if (encryptionKeyIds != null) { + Vector goodIds = new Vector(); + for (int i = 0; i < encryptionKeyIds.length; ++i) { + PGPPublicKeyRing keyRing = Apg.findPublicKeyRing(encryptionKeyIds[i]); + PGPPublicKey masterKey = null; + if (keyRing == null) { + continue; + } + masterKey = Apg.getMasterKey(keyRing); + if (masterKey == null) { + continue; + } + Vector encryptKeys = Apg.getUsableEncryptKeys(keyRing); + if (encryptKeys.size() == 0) { + continue; + } + goodIds.add(masterKey.getKeyID()); + } + if (goodIds.size() > 0) { + mEncryptionKeyIds = new long[goodIds.size()]; + for (int i = 0; i < goodIds.size(); ++i) { + mEncryptionKeyIds[i] = goodIds.get(i); + } + } + } + + if (intent.getAction().equals(Apg.Intent.ENCRYPT)) { + if (data != null) { + mMessage.setText(data); + } + mSource.setInAnimation(null); + mSource.setOutAnimation(null); + while (mSource.getCurrentView().getId() != R.id.source_message) { + mSource.showNext(); + } + } else if (intent.getAction().equals(Apg.Intent.ENCRYPT_FILE)) { + mSource.setInAnimation(null); + mSource.setOutAnimation(null); + while (mSource.getCurrentView().getId() != R.id.source_file) { + mSource.showNext(); + } + } + } + + updateView(); + updateSource(); + updateMode(); + } + + private void openFile() { + String filename = mFilename.getText().toString(); + + Intent intent = new Intent(FileManager.ACTION_PICK_FILE); + + intent.setData(Uri.parse("file://" + filename)); + + intent.putExtra(FileManager.EXTRA_TITLE, "Select file to encrypt..."); + intent.putExtra(FileManager.EXTRA_BUTTON_TEXT, "Open"); + + try { + startActivityForResult(intent, Id.request.filename); + } catch (ActivityNotFoundException e) { + // No compatible file manager was found. + Toast.makeText(this, R.string.no_filemanager_installed, Toast.LENGTH_SHORT).show(); + } + } + + private void guessOutputFilename() { + mInputFilename = mFilename.getText().toString(); + File file = new File(mInputFilename); + String ending = (mAsciiArmour.isChecked() ? ".asc" : ".gpg"); + mOutputFilename = Constants.path.app_dir + "/" + file.getName() + ending; + } + + private void updateSource() { + switch (mSource.getCurrentView().getId()) { + case R.id.source_file: { + mSourceLabel.setText(R.string.label_file); + mEncryptButton.setText(R.string.btn_encrypt); + mEncryptToClipboardButton.setEnabled(false); + break; + } + + case R.id.source_message: { + mSourceLabel.setText(R.string.label_message); + mEncryptButton.setText(R.string.btn_send); + mEncryptToClipboardButton.setEnabled(true); + break; + } + + default: { + break; + } + } + } + + private void updateMode() { + switch (mMode.getCurrentView().getId()) { + case R.id.mode_asymmetric: { + mModeLabel.setText(R.string.label_asymmetric); + break; + } + + case R.id.mode_symmetric: { + mModeLabel.setText(R.string.label_symmetric); + break; + } + + default: { + break; + } + } + } + + private void encryptToClipboardClicked() { + mEncryptTarget = Id.target.clipboard; + initiateEncryption(); + } + + private void encryptClicked() { + if (mSource.getCurrentView().getId() == R.id.source_file) { + mEncryptTarget = Id.target.file; + } else { + mEncryptTarget = Id.target.email; + } + initiateEncryption(); + } + + private void initiateEncryption() { + if (mEncryptTarget == Id.target.file) { + String currentFilename = mFilename.getText().toString(); + if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { + guessOutputFilename(); + } + + if (mInputFilename.equals("")) { + Toast.makeText(this, "Select a file first.", Toast.LENGTH_SHORT).show(); + return; + } + + File file = new File(mInputFilename); + if (!file.exists() || !file.isFile()) { + Toast.makeText(this, "Error: file not found", Toast.LENGTH_SHORT).show(); + return; + } + } + + // symmetric encryption + if (mMode.getCurrentView().getId() == R.id.mode_symmetric) { + boolean gotPassPhrase = false; + String passPhrase = mPassPhrase.getText().toString(); + String passPhraseAgain = mPassPhraseAgain.getText().toString(); + if (!passPhrase.equals(passPhraseAgain)) { + Toast.makeText(this, "Pass phrases don't match.", Toast.LENGTH_SHORT).show(); + return; + } + + gotPassPhrase = (passPhrase.length() != 0); + if (!gotPassPhrase) { + Toast.makeText(this, "Enter a pass phrase.", Toast.LENGTH_SHORT).show(); + return; + } + } else { + boolean encryptIt = mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0; + // for now require at least one form of encryption for files + if (!encryptIt && mEncryptTarget == Id.target.file) { + Toast.makeText(this, "Select at least one encryption key.", + Toast.LENGTH_SHORT).show(); + return; + } + + if (!encryptIt && getSecretKeyId() == 0) { + Toast.makeText(this, "Select at least one encryption key or a signature key.", + Toast.LENGTH_SHORT).show(); + return; + } + + if (getSecretKeyId() != 0 && Apg.getPassPhrase() == null) { + showDialog(Id.dialog.pass_phrase); + return; + } + } + + if (mEncryptTarget == Id.target.file) { + askForOutputFilename(); + } else { + encryptStart(); + } + } + + private void askForOutputFilename() { + showDialog(Id.dialog.output_filename); + } + + @Override + public void passPhraseCallback(String passPhrase) { + super.passPhraseCallback(passPhrase); + if (mEncryptTarget == Id.target.file) { + askForOutputFilename(); + } else { + encryptStart(); + } + } + + private void encryptStart() { + showDialog(Id.dialog.encrypting); + startThread(); + } + + @Override + public void run() { + String error = null; + Bundle data = new Bundle(); + Message msg = new Message(); + + try { + InputStream in; + OutputStream out; + long size; + boolean useAsciiArmour = true; + long encryptionKeyIds[] = null; + long signatureKeyId = 0; + boolean signOnly = false; + + String passPhrase = null; + if (mMode.getCurrentView().getId() == R.id.mode_symmetric) { + passPhrase = mPassPhrase.getText().toString(); + if (passPhrase.length() == 0) { + passPhrase = null; + } + } else { + encryptionKeyIds = mEncryptionKeyIds; + signatureKeyId = getSecretKeyId(); + signOnly = mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0; + } + + if (mEncryptTarget == Id.target.file) { + if (mInputFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath()) || + mOutputFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) { + if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + throw new GeneralException("external storage not ready"); + } + } + + in = new FileInputStream(mInputFilename); + out = new FileOutputStream(mOutputFilename); + + File file = new File(mInputFilename); + size = file.length(); + useAsciiArmour = mAsciiArmour.isChecked(); + } else { + String message = mMessage.getText().toString(); + + if (signOnly) { + // fix the message a bit, trailing spaces and newlines break stuff, + // because GMail sends as HTML and such things fuck up the signature, + // TODO: things like "<" and ">" also fuck up the signature + message = message.replaceAll(" +\n", "\n"); + message = message.replaceAll("\n\n+", "\n\n"); + message = message.replaceFirst("^\n+", ""); + // make sure there'll be exactly one newline at the end + message = message.replaceFirst("\n*$", "\n"); + } + + byte[] byteData = Strings.toUTF8ByteArray(message); + in = new ByteArrayInputStream(byteData); + out = new ByteArrayOutputStream(); + + size = byteData.length; + useAsciiArmour = true; + } + + if (signOnly) { + Apg.signText(in, out, getSecretKeyId(), + Apg.getPassPhrase(), getDefaultHashAlgorithm(), this); + } else { + Apg.encrypt(in, out, size, useAsciiArmour, + encryptionKeyIds, signatureKeyId, + Apg.getPassPhrase(), this, + getDefaultEncryptionAlgorithm(), getDefaultHashAlgorithm(), + passPhrase); + } + + out.close(); + if (mEncryptTarget != Id.target.file) { + data.putString("message", new String(((ByteArrayOutputStream)out).toByteArray())); + } + } catch (IOException e) { + error = e.getMessage(); + } catch (PGPException e) { + error = e.getMessage(); + } catch (NoSuchProviderException e) { + error = e.getMessage(); + } catch (NoSuchAlgorithmException e) { + error = e.getMessage(); + } catch (SignatureException e) { + error = e.getMessage(); + } catch (Apg.GeneralException e) { + error = e.getMessage(); + } + + data.putInt("type", Id.message.done); + + if (error != null) { + data.putString("error", error); + } + + msg.setData(data); + sendMessage(msg); + } + + private void updateView() { + if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { + mSelectKeysButton.setText(R.string.no_keys_selected); + } else if (mEncryptionKeyIds.length == 1) { + mSelectKeysButton.setText(R.string.one_key_selected); + } else { + mSelectKeysButton.setText("" + mEncryptionKeyIds.length + " " + + getResources().getString(R.string.n_keys_selected)); + } + + if (getSecretKeyId() == 0) { + mSign.setChecked(false); + mMainUserId.setText(""); + mMainUserIdRest.setText(""); + } else { + String uid = getResources().getString(R.string.unknown_user_id); + String uidExtra = ""; + PGPSecretKeyRing keyRing = Apg.getSecretKeyRing(getSecretKeyId()); + if (keyRing != null) { + PGPSecretKey key = Apg.getMasterKey(keyRing); + if (key != null) { + String userId = Apg.getMainUserIdSafe(this, key); + String chunks[] = userId.split(" <", 2); + uid = chunks[0]; + if (chunks.length > 1) { + uidExtra = "<" + chunks[1]; + } + } + } + mMainUserId.setText(uid); + mMainUserIdRest.setText(uidExtra); + mSign.setChecked(true); + } + } + + private void selectPublicKeys() { + Intent intent = new Intent(this, SelectPublicKeyListActivity.class); + intent.putExtra("selection", mEncryptionKeyIds); + startActivityForResult(intent, Id.request.public_keys); + } + + private void selectSecretKey() { + Intent intent = new Intent(this, SelectSecretKeyListActivity.class); + startActivityForResult(intent, Id.request.secret_keys); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Id.request.filename: { + if (resultCode == RESULT_OK && data != null) { + String filename = data.getDataString(); + if (filename != null) { + // Get rid of URI prefix: + if (filename.startsWith("file://")) { + filename = filename.substring(7); + } + // replace %20 and so on + filename = Uri.decode(filename); + + mFilename.setText(filename); + } + } + return; + } + + case Id.request.output_filename: { + if (resultCode == RESULT_OK && data != null) { + String filename = data.getDataString(); + if (filename != null) { + // Get rid of URI prefix: + if (filename.startsWith("file://")) { + filename = filename.substring(7); + } + // replace %20 and so on + filename = Uri.decode(filename); + + FileDialog.setFilename(filename); + } + } + return; + } + + case Id.request.secret_keys: { + if (resultCode == RESULT_OK) { + super.onActivityResult(requestCode, resultCode, data); + } + updateView(); + break; + } + + case Id.request.public_keys: { + if (resultCode == RESULT_OK) { + Bundle bundle = data.getExtras(); + mEncryptionKeyIds = bundle.getLongArray("selection"); + } + updateView(); + break; + } + + default: { + break; + } + } + + super.onActivityResult(requestCode, resultCode, data); + } + + @Override + public void doneCallback(Message msg) { + super.doneCallback(msg); + + removeDialog(Id.dialog.encrypting); + + Bundle data = msg.getData(); + String error = data.getString("error"); + if (error != null) { + Toast.makeText(EncryptActivity.this, + "Error: " + data.getString("error"), + Toast.LENGTH_SHORT).show(); + return; + } else { + String message = data.getString("message"); + switch (mEncryptTarget) { + case Id.target.clipboard: { + ClipboardManager clip = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + clip.setText(message); + Toast.makeText(this, "Successfully encrypted to clipboard.", + Toast.LENGTH_SHORT).show(); + break; + } + + case Id.target.email: { + Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); + emailIntent.setType("text/plain; charset=utf-8"); + emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message); + if (mSubject != null) { + emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, + mSubject); + } + if (mSendTo != null) { + emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, + new String[] { mSendTo }); + } + EncryptActivity.this. + startActivity(Intent.createChooser(emailIntent, "Send mail...")); + } + + case Id.target.file: { + Toast.makeText(this, "Successfully encrypted.", Toast.LENGTH_SHORT).show(); + if (mDeleteAfter.isChecked()) { + setDeleteFile(mInputFilename); + showDialog(Id.dialog.delete_file); + } + break; + } + + default: { + // shouldn't happen + break; + } + } + } + } + + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case Id.dialog.output_filename: { + return FileDialog.build(this, "Encrypt to file", + "Please specify which file to encrypt to.\n" + + "WARNING! File will be overwritten if it exists.", + mOutputFilename, + new FileDialog.OnClickListener() { + + @Override + public void onOkClick(String filename) { + removeDialog(Id.dialog.output_filename); + mOutputFilename = filename; + encryptStart(); + } + + @Override + public void onCancelClick() { + removeDialog(Id.dialog.output_filename); + } + }, + getString(R.string.filemanager_title_save), + getString(R.string.filemanager_btn_save), + Id.request.output_filename); + } + + default: { + break; + } + } + + return super.onCreateDialog(id); + } +} \ No newline at end of file diff --git a/src/org/thialfihar/android/apg/EncryptFileActivity.java b/src/org/thialfihar/android/apg/EncryptFileActivity.java deleted file mode 100644 index dee9a3e39..000000000 --- a/src/org/thialfihar/android/apg/EncryptFileActivity.java +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar - * - * 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; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SignatureException; - -import org.bouncycastle2.openpgp.PGPEncryptedData; -import org.bouncycastle2.openpgp.PGPException; -import org.bouncycastle2.openpgp.PGPSecretKey; -import org.bouncycastle2.openpgp.PGPSecretKeyRing; -import org.openintents.intents.FileManager; -import org.thialfihar.android.apg.Apg.GeneralException; -import org.thialfihar.android.apg.utils.Choice; - -import android.app.Dialog; -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.os.Message; -import android.view.View; -import android.view.ViewGroup; -import android.view.View.OnClickListener; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.RadioGroup; -import android.widget.Spinner; -import android.widget.TextView; -import android.widget.Toast; -import android.widget.RadioGroup.OnCheckedChangeListener; - -public class EncryptFileActivity extends BaseActivity { - private EditText mFilename = null; - private CheckBox mDeleteAfter = null; - private ImageButton mBrowse = null; - private CheckBox mSign = null; - private TextView mMainUserId = null; - private TextView mMainUserIdRest = null; - private Spinner mAlgorithm = null; - private EditText mPassPhrase = null; - private EditText mPassPhraseAgain = null; - private CheckBox mAsciiArmour = null; - private RadioGroup mEncryptionMode = null; - private ViewGroup mAsymmetricLayout = null; - private ViewGroup mSymmetricLayout = null; - private Button mEncryptButton = null; - private Button mSelectKeysButton = null; - - private long mEncryptionKeyIds[] = null; - private String mInputFilename = null; - private String mOutputFilename = null; - - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.encrypt_file); - - mAsciiArmour = (CheckBox) findViewById(R.id.ascii_armour); - mAsciiArmour.setChecked(getDefaultAsciiArmour()); - mAsciiArmour.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View view) { - guessOutputFilename(); - } - }); - - // asymmetric tab - mSelectKeysButton = (Button) findViewById(R.id.btn_selectEncryptKeys); - mSelectKeysButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - selectPublicKeys(); - } - }); - - mFilename = (EditText) findViewById(R.id.filename); - mBrowse = (ImageButton) findViewById(R.id.btn_browse); - mBrowse.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - openFile(); - } - }); - - mDeleteAfter = (CheckBox) findViewById(R.id.delete_after_encryption); - - mEncryptButton = (Button) findViewById(R.id.btn_encrypt); - mSign = (CheckBox) findViewById(R.id.sign); - mMainUserId = (TextView) findViewById(R.id.main_user_id); - mMainUserIdRest = (TextView) findViewById(R.id.main_user_id_rest); - - mSign.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - CheckBox checkBox = (CheckBox) v; - if (checkBox.isChecked()) { - selectSecretKey(); - } else { - setSecretKeyId(0); - Apg.setPassPhrase(null); - updateView(); - } - } - }); - - // symmetric tab - - mAlgorithm = (Spinner) findViewById(R.id.algorithm); - Choice choices[] = { - new Choice(PGPEncryptedData.AES_128, "AES 128"), - new Choice(PGPEncryptedData.AES_192, "AES 192"), - new Choice(PGPEncryptedData.AES_256, "AES 256"), - new Choice(PGPEncryptedData.BLOWFISH, "Blowfish"), - new Choice(PGPEncryptedData.TWOFISH, "Twofish"), - new Choice(PGPEncryptedData.CAST5, "CAST5"), - new Choice(PGPEncryptedData.DES, "DES"), - new Choice(PGPEncryptedData.TRIPLE_DES, "Triple DES"), - new Choice(PGPEncryptedData.IDEA, "IDEA"), - }; - ArrayAdapter adapter = - new ArrayAdapter(this, android.R.layout.simple_spinner_item, choices); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mAlgorithm.setAdapter(adapter); - for (int i = 0; i < choices.length; ++i) { - if (choices[i].getId() == getDefaultEncryptionAlgorithm()) { - mAlgorithm.setSelection(i); - break; - } - } - - mEncryptionMode = (RadioGroup) findViewById(R.id.encryption_mode); - mAsymmetricLayout = (ViewGroup) findViewById(R.id.layout_asymmetric); - mSymmetricLayout = (ViewGroup) findViewById(R.id.layout_symmetric); - mPassPhrase = (EditText) findViewById(R.id.pass_phrase); - mPassPhraseAgain = (EditText) findViewById(R.id.pass_phrase_again); - - mEncryptionMode.check(R.id.use_asymmetric); - mEncryptionMode.setOnCheckedChangeListener(new OnCheckedChangeListener() { - @Override - public void onCheckedChanged(RadioGroup group, int checkedId) { - if (checkedId == R.id.use_symmetric) { - mAsymmetricLayout.setVisibility(ViewGroup.GONE); - mSymmetricLayout.setVisibility(ViewGroup.VISIBLE); - mEncryptionKeyIds = null; - setSecretKeyId(0); - } else { - mAsymmetricLayout.setVisibility(ViewGroup.VISIBLE); - mSymmetricLayout.setVisibility(ViewGroup.GONE); - mPassPhrase.setText(""); - mPassPhraseAgain.setText(""); - } - updateView(); - } - }); - if (mEncryptionMode.getCheckedRadioButtonId() == R.id.use_symmetric) { - mAsymmetricLayout.setVisibility(ViewGroup.GONE); - mSymmetricLayout.setVisibility(ViewGroup.VISIBLE); - } else { - mAsymmetricLayout.setVisibility(ViewGroup.VISIBLE); - mSymmetricLayout.setVisibility(ViewGroup.GONE); - } - - mEncryptButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - encryptClicked(); - } - }); - - updateView(); - } - - private void updateView() { - if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { - mSelectKeysButton.setText(R.string.no_keys_selected); - } else if (mEncryptionKeyIds.length == 1) { - mSelectKeysButton.setText(R.string.one_key_selected); - } else { - mSelectKeysButton.setText("" + mEncryptionKeyIds.length + " " + - getResources().getString(R.string.n_keys_selected)); - } - - if (getSecretKeyId() == 0) { - mSign.setChecked(false); - mMainUserId.setText(""); - mMainUserIdRest.setText(""); - } else { - String uid = getResources().getString(R.string.unknown_user_id); - String uidExtra = ""; - PGPSecretKeyRing keyRing = Apg.getSecretKeyRing(getSecretKeyId()); - if (keyRing != null) { - PGPSecretKey key = Apg.getMasterKey(keyRing); - if (key != null) { - String userId = Apg.getMainUserIdSafe(this, key); - String chunks[] = userId.split(" <", 2); - uid = chunks[0]; - if (chunks.length > 1) { - uidExtra = "<" + chunks[1]; - } - } - } - mMainUserId.setText(uid); - mMainUserIdRest.setText(uidExtra); - mSign.setChecked(true); - } - } - - private void openFile() { - String filename = mFilename.getText().toString(); - - Intent intent = new Intent(FileManager.ACTION_PICK_FILE); - - intent.setData(Uri.parse("file://" + filename)); - - intent.putExtra(FileManager.EXTRA_TITLE, "Select file to encrypt..."); - intent.putExtra(FileManager.EXTRA_BUTTON_TEXT, "Open"); - - try { - startActivityForResult(intent, Id.request.filename); - } catch (ActivityNotFoundException e) { - // No compatible file manager was found. - Toast.makeText(this, R.string.no_filemanager_installed, Toast.LENGTH_SHORT).show(); - } - } - - private void selectSecretKey() { - Intent intent = new Intent(this, SelectSecretKeyListActivity.class); - startActivityForResult(intent, Id.request.secret_keys); - } - - private void selectPublicKeys() { - Intent intent = new Intent(this, SelectPublicKeyListActivity.class); - intent.putExtra("selection", mEncryptionKeyIds); - startActivityForResult(intent, Id.request.public_keys); - } - - private void guessOutputFilename() { - mInputFilename = mFilename.getText().toString(); - File file = new File(mInputFilename); - String ending = (mAsciiArmour.isChecked() ? ".asc" : ".gpg"); - mOutputFilename = Constants.path.app_dir + "/" + file.getName() + ending; - } - - private void encryptClicked() { - String currentFilename = mFilename.getText().toString(); - if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { - guessOutputFilename(); - } - - if (mInputFilename.equals("")) { - Toast.makeText(this, "Select a file first.", Toast.LENGTH_SHORT).show(); - return; - } - - File file = new File(mInputFilename); - if (!file.exists() || !file.isFile()) { - Toast.makeText(this, "Error: file not found", Toast.LENGTH_SHORT).show(); - return; - } - - // symmetric encryption - if (mEncryptionMode.getCheckedRadioButtonId() == R.id.use_symmetric) { - boolean gotPassPhrase = false; - String passPhrase = mPassPhrase.getText().toString(); - String passPhraseAgain = mPassPhraseAgain.getText().toString(); - if (!passPhrase.equals(passPhraseAgain)) { - Toast.makeText(this, "Pass phrases don't match.", - Toast.LENGTH_SHORT).show(); - return; - } - - gotPassPhrase = (passPhrase.length() != 0); - if (!gotPassPhrase) { - Toast.makeText(this, "Enter a pass phrase.", - Toast.LENGTH_SHORT).show(); - return; - } - } else { - boolean encryptIt = mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0; - // for now require at least one form of encryption - if (!encryptIt) { - Toast.makeText(this, "Select at least one encryption key.", - Toast.LENGTH_SHORT).show(); - return; - } - - if (getSecretKeyId() != 0 && Apg.getPassPhrase() == null) { - showDialog(Id.dialog.pass_phrase); - return; - } - } - - askForOutputFilename(); - } - - @Override - public void passPhraseCallback(String passPhrase) { - super.passPhraseCallback(passPhrase); - askForOutputFilename(); - } - - private void askForOutputFilename() { - showDialog(Id.dialog.output_filename); - } - - private void encryptStart() { - showDialog(Id.dialog.encrypting); - startThread(); - } - - @Override - public void run() { - String error = null; - Bundle data = new Bundle(); - Message msg = new Message(); - - try { - if (mInputFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath()) || - mOutputFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) { - if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - throw new GeneralException("external storage not ready"); - } - } - - InputStream in = new FileInputStream(mInputFilename); - OutputStream out = new FileOutputStream(mOutputFilename); - - String passPhrase = null; - if (mEncryptionMode.getCheckedRadioButtonId() == R.id.use_symmetric) { - passPhrase = mPassPhrase.getText().toString(); - if (passPhrase.length() == 0) { - passPhrase = null; - } - } - - File file = new File(mInputFilename); - long fileSize = file.length(); - - Apg.encrypt(in, out, fileSize, mAsciiArmour.isChecked(), - mEncryptionKeyIds, getSecretKeyId(), - Apg.getPassPhrase(), this, - ((Choice) mAlgorithm.getSelectedItem()).getId(), - getDefaultHashAlgorithm(), - passPhrase); - - out.close(); - } catch (FileNotFoundException e) { - error = "file not found: " + e.getMessage(); - } - catch (IOException e) { - error = e.getMessage(); - } catch (PGPException e) { - error = e.getMessage(); - } catch (NoSuchProviderException e) { - error = e.getMessage(); - } catch (NoSuchAlgorithmException e) { - error = e.getMessage(); - } catch (SignatureException e) { - error = e.getMessage(); - } catch (Apg.GeneralException e) { - error = e.getMessage(); - } - - data.putInt("type", Id.message.done); - - if (error != null) { - data.putString("error", error); - } - - msg.setData(data); - sendMessage(msg); - } - - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case Id.dialog.output_filename: { - return FileDialog.build(this, "Encrypt to file", - "Please specify which file to encrypt to.\n" + - "WARNING! File will be overwritten if it exists.", - mOutputFilename, - new FileDialog.OnClickListener() { - - @Override - public void onOkClick(String filename) { - removeDialog(Id.dialog.output_filename); - mOutputFilename = filename; - encryptStart(); - } - - @Override - public void onCancelClick() { - removeDialog(Id.dialog.output_filename); - } - }, - getString(R.string.filemanager_title_save), - getString(R.string.filemanager_btn_save), - Id.request.output_filename); - } - - default: { - break; - } - } - - return super.onCreateDialog(id); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case Id.request.filename: { - if (resultCode == RESULT_OK && data != null) { - String filename = data.getDataString(); - if (filename != null) { - // Get rid of URI prefix: - if (filename.startsWith("file://")) { - filename = filename.substring(7); - } - // replace %20 and so on - filename = Uri.decode(filename); - - mFilename.setText(filename); - } - } - return; - } - - case Id.request.output_filename: { - if (resultCode == RESULT_OK && data != null) { - String filename = data.getDataString(); - if (filename != null) { - // Get rid of URI prefix: - if (filename.startsWith("file://")) { - filename = filename.substring(7); - } - // replace %20 and so on - filename = Uri.decode(filename); - - FileDialog.setFilename(filename); - } - } - return; - } - - case Id.request.secret_keys: { - if (resultCode == RESULT_OK) { - super.onActivityResult(requestCode, resultCode, data); - } - updateView(); - break; - } - - case Id.request.public_keys: { - if (resultCode == RESULT_OK) { - Bundle bundle = data.getExtras(); - mEncryptionKeyIds = bundle.getLongArray("selection"); - } - updateView(); - break; - } - - default: { - break; - } - } - super.onActivityResult(requestCode, resultCode, data); - } - - @Override - public void doneCallback(Message msg) { - super.doneCallback(msg); - Bundle data = msg.getData(); - removeDialog(Id.dialog.encrypting); - - String error = data.getString("error"); - if (error != null) { - Toast.makeText(EncryptFileActivity.this, - "Error: " + data.getString("error"), - Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(EncryptFileActivity.this, - "Successfully encrypted.", - Toast.LENGTH_SHORT).show(); - if (mDeleteAfter.isChecked()) { - setDeleteFile(mInputFilename); - showDialog(Id.dialog.delete_file); - } - } - } -} diff --git a/src/org/thialfihar/android/apg/EncryptMessageActivity.java b/src/org/thialfihar/android/apg/EncryptMessageActivity.java deleted file mode 100644 index 3e49d7c50..000000000 --- a/src/org/thialfihar/android/apg/EncryptMessageActivity.java +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar - * - * 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; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SignatureException; -import java.util.Vector; - -import org.bouncycastle2.openpgp.PGPException; -import org.bouncycastle2.openpgp.PGPPublicKey; -import org.bouncycastle2.openpgp.PGPPublicKeyRing; -import org.bouncycastle2.openpgp.PGPSecretKey; -import org.bouncycastle2.openpgp.PGPSecretKeyRing; -import org.bouncycastle2.util.Strings; - -import android.content.Intent; -import android.os.Bundle; -import android.os.Message; -import android.text.ClipboardManager; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; - -public class EncryptMessageActivity extends BaseActivity { - private String mSubject = null; - private String mSendTo = null; - - private long mEncryptionKeyIds[] = null; - - private EditText mMessage = null; - private Button mSelectKeysButton = null; - private Button mEncryptButton = null; - private Button mSendButton = null; - private CheckBox mSign = null; - private TextView mMainUserId = null; - private TextView mMainUserIdRest = null; - - private int mEncryptTarget; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.encrypt_message); - - mMessage = (EditText) findViewById(R.id.message); - mSelectKeysButton = (Button) findViewById(R.id.btn_selectEncryptKeys); - mEncryptButton = (Button) findViewById(R.id.btn_encrypt_to_clipboard); - mSendButton = (Button) findViewById(R.id.btn_send); - mSign = (CheckBox) findViewById(R.id.sign); - mMainUserId = (TextView) findViewById(R.id.main_user_id); - mMainUserIdRest = (TextView) findViewById(R.id.main_user_id_rest); - - Intent intent = getIntent(); - if (intent.getAction() != null && - intent.getAction().equals(Apg.Intent.ENCRYPT)) { - String data = intent.getExtras().getString("data"); - mSendTo = intent.getExtras().getString("sendTo"); - mSubject = intent.getExtras().getString("subject"); - long signatureKeyId = intent.getExtras().getLong("signatureKeyId"); - long encryptionKeyIds[] = intent.getExtras().getLongArray("encryptionKeyIds"); - if (signatureKeyId != 0) { - PGPSecretKeyRing keyRing = Apg.findSecretKeyRing(signatureKeyId); - PGPSecretKey masterKey = null; - if (keyRing != null) { - masterKey = Apg.getMasterKey(keyRing); - if (masterKey != null) { - Vector signKeys = Apg.getUsableSigningKeys(keyRing); - if (signKeys.size() > 0) { - setSecretKeyId(masterKey.getKeyID()); - } - } - } - } - - if (encryptionKeyIds != null) { - Vector goodIds = new Vector(); - for (int i = 0; i < encryptionKeyIds.length; ++i) { - PGPPublicKeyRing keyRing = Apg.findPublicKeyRing(encryptionKeyIds[i]); - PGPPublicKey masterKey = null; - if (keyRing == null) { - continue; - } - masterKey = Apg.getMasterKey(keyRing); - if (masterKey == null) { - continue; - } - Vector encryptKeys = Apg.getUsableEncryptKeys(keyRing); - if (encryptKeys.size() == 0) { - continue; - } - goodIds.add(masterKey.getKeyID()); - } - if (goodIds.size() > 0) { - mEncryptionKeyIds = new long[goodIds.size()]; - for (int i = 0; i < goodIds.size(); ++i) { - mEncryptionKeyIds[i] = goodIds.get(i); - } - } - } - if (data != null) { - mMessage.setText(data); - } - } - - mEncryptButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - encryptClicked(); - } - }); - - mSendButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - sendClicked(); - } - }); - - mSelectKeysButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - selectPublicKeys(); - } - }); - - mSign.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - CheckBox checkBox = (CheckBox) v; - if (checkBox.isChecked()) { - selectSecretKey(); - } else { - setSecretKeyId(0); - Apg.setPassPhrase(null); - updateView(); - } - } - }); - - updateView(); - } - - private void encryptClicked() { - mEncryptTarget = Id.target.clipboard; - if (getSecretKeyId() != 0 && Apg.getPassPhrase() == null) { - showDialog(Id.dialog.pass_phrase); - } else { - encryptStart(); - } - } - - private void sendClicked() { - mEncryptTarget = Id.target.email; - if (getSecretKeyId() != 0 && Apg.getPassPhrase() == null) { - showDialog(Id.dialog.pass_phrase); - } else { - encryptStart(); - } - } - - @Override - public void passPhraseCallback(String passPhrase) { - super.passPhraseCallback(passPhrase); - encryptStart(); - } - - private void encryptStart() { - showDialog(Id.dialog.encrypting); - startThread(); - } - - @Override - public void run() { - String error = null; - Bundle data = new Bundle(); - Message msg = new Message(); - - try { - boolean encryptIt = mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0; - if (getSecretKeyId() == 0 && !encryptIt) { - throw new Apg.GeneralException("no signature key or encryption key selected"); - } - - String message = mMessage.getText().toString(); - if (!encryptIt) { - // fix the message a bit, trailing spaces and newlines break stuff, - // because GMail sends as HTML and such things fuck up the signature, - // TODO: things like "<" and ">" also fuck up the signature - message = message.replaceAll(" +\n", "\n"); - message = message.replaceAll("\n\n+", "\n\n"); - message = message.replaceFirst("^\n+", ""); - // make sure there'll be exactly one newline at the end - message = message.replaceFirst("\n*$", "\n"); - } - - byte[] byteData = Strings.toUTF8ByteArray(message); - ByteArrayInputStream in = new ByteArrayInputStream(byteData); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - if (encryptIt) { - Apg.encrypt(in, out, byteData.length, true, mEncryptionKeyIds, getSecretKeyId(), - Apg.getPassPhrase(), this, - getDefaultEncryptionAlgorithm(), getDefaultHashAlgorithm(), - null); - } else { - Apg.signText(in, out, getSecretKeyId(), - Apg.getPassPhrase(), getDefaultHashAlgorithm(), this); - } - - out.close(); - data.putString("message", new String(out.toByteArray())); - } catch (IOException e) { - error = e.getMessage(); - } catch (PGPException e) { - error = e.getMessage(); - } catch (NoSuchProviderException e) { - error = e.getMessage(); - } catch (NoSuchAlgorithmException e) { - error = e.getMessage(); - } catch (SignatureException e) { - error = e.getMessage(); - } catch (Apg.GeneralException e) { - error = e.getMessage(); - } - - data.putInt("type", Id.message.done); - - if (error != null) { - data.putString("error", error); - } - - msg.setData(data); - sendMessage(msg); - } - - private void updateView() { - if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { - mSelectKeysButton.setText(R.string.no_keys_selected); - } else if (mEncryptionKeyIds.length == 1) { - mSelectKeysButton.setText(R.string.one_key_selected); - } else { - mSelectKeysButton.setText("" + mEncryptionKeyIds.length + " " + - getResources().getString(R.string.n_keys_selected)); - } - - if (getSecretKeyId() == 0) { - mSign.setChecked(false); - mMainUserId.setText(""); - mMainUserIdRest.setText(""); - } else { - String uid = getResources().getString(R.string.unknown_user_id); - String uidExtra = ""; - PGPSecretKeyRing keyRing = Apg.getSecretKeyRing(getSecretKeyId()); - if (keyRing != null) { - PGPSecretKey key = Apg.getMasterKey(keyRing); - if (key != null) { - String userId = Apg.getMainUserIdSafe(this, key); - String chunks[] = userId.split(" <", 2); - uid = chunks[0]; - if (chunks.length > 1) { - uidExtra = "<" + chunks[1]; - } - } - } - mMainUserId.setText(uid); - mMainUserIdRest.setText(uidExtra); - mSign.setChecked(true); - } - } - - private void selectPublicKeys() { - Intent intent = new Intent(this, SelectPublicKeyListActivity.class); - intent.putExtra("selection", mEncryptionKeyIds); - startActivityForResult(intent, Id.request.public_keys); - } - - private void selectSecretKey() { - Intent intent = new Intent(this, SelectSecretKeyListActivity.class); - startActivityForResult(intent, Id.request.secret_keys); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case Id.request.secret_keys: { - if (resultCode == RESULT_OK) { - super.onActivityResult(requestCode, resultCode, data); - } - updateView(); - break; - } - - case Id.request.public_keys: { - if (resultCode == RESULT_OK) { - Bundle bundle = data.getExtras(); - mEncryptionKeyIds = bundle.getLongArray("selection"); - } - updateView(); - break; - } - - default: { - break; - } - } - - super.onActivityResult(requestCode, resultCode, data); - } - - @Override - public void doneCallback(Message msg) { - super.doneCallback(msg); - - removeDialog(Id.dialog.encrypting); - - Bundle data = msg.getData(); - String error = data.getString("error"); - if (error != null) { - Toast.makeText(EncryptMessageActivity.this, - "Error: " + data.getString("error"), - Toast.LENGTH_SHORT).show(); - return; - } else { - String message = data.getString("message"); - switch (mEncryptTarget) { - case Id.target.clipboard: { - ClipboardManager clip = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - clip.setText(message); - Toast.makeText(this, "Successfully encrypted to clipboard.", - Toast.LENGTH_SHORT).show(); - break; - } - - case Id.target.email: { - Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); - emailIntent.setType("text/plain; charset=utf-8"); - emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message); - if (mSubject != null) { - emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, - mSubject); - } - if (mSendTo != null) { - emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, - new String[] { mSendTo }); - } - EncryptMessageActivity.this. - startActivity(Intent.createChooser(emailIntent, "Send mail...")); - } - - default: { - // shouldn't happen - break; - } - } - } - } -} \ No newline at end of file diff --git a/src/org/thialfihar/android/apg/Id.java b/src/org/thialfihar/android/apg/Id.java index 88a6b2988..601a0eef4 100644 --- a/src/org/thialfihar/android/apg/Id.java +++ b/src/org/thialfihar/android/apg/Id.java @@ -107,5 +107,6 @@ public final class Id { public static final class target { public static final int clipboard = 0x21070001; public static final int email = 0x21070002; + public static final int file = 0x21070003; } } diff --git a/src/org/thialfihar/android/apg/MainActivity.java b/src/org/thialfihar/android/apg/MainActivity.java index 376b47e78..8a8d57a89 100644 --- a/src/org/thialfihar/android/apg/MainActivity.java +++ b/src/org/thialfihar/android/apg/MainActivity.java @@ -24,14 +24,10 @@ import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.res.ColorStateList; import android.database.Cursor; import android.database.SQLException; import android.net.Uri; import android.os.Bundle; -import android.text.SpannableString; -import android.text.method.LinkMovementMethod; -import android.text.util.Linkify; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; @@ -45,7 +41,6 @@ import android.widget.Button; import android.widget.CursorAdapter; import android.widget.EditText; import android.widget.ListView; -import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; @@ -67,7 +62,9 @@ public class MainActivity extends BaseActivity { encryptMessageButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - startActivity(new Intent(MainActivity.this, EncryptMessageActivity.class)); + Intent intent = new Intent(MainActivity.this, EncryptActivity.class); + intent.setAction(Apg.Intent.ENCRYPT); + startActivity(intent); } }); @@ -81,7 +78,9 @@ public class MainActivity extends BaseActivity { encryptFileButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - startActivity(new Intent(MainActivity.this, EncryptFileActivity.class)); + Intent intent = new Intent(MainActivity.this, EncryptActivity.class); + intent.setAction(Apg.Intent.ENCRYPT_FILE); + startActivity(intent); } }); @@ -212,6 +211,7 @@ public class MainActivity extends BaseActivity { message.setText("Read the warnings!\n\n" + "Changes:\n" + "* encrypt to clipboard\n" + + "* new encrypt GUI to handle everything\n" + "\n" + "WARNING: be careful editing your existing keys, as they " + "WILL be stripped of certificates right now.\n" + -- cgit v1.2.3