diff options
Diffstat (limited to 'src/org')
-rw-r--r-- | src/org/thialfihar/android/apg/DecryptMessageActivity.java | 2 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/EncryptActivity.java | 783 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/EncryptFileActivity.java | 520 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/EncryptMessageActivity.java | 379 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/Id.java | 1 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/MainActivity.java | 14 |
6 files changed, 792 insertions, 907 deletions
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 <thi@thialfihar.org> + * + * 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<PGPSecretKey> signKeys = Apg.getUsableSigningKeys(keyRing); + if (signKeys.size() > 0) { + setSecretKeyId(masterKey.getKeyID()); + } + } + } + } + + if (encryptionKeyIds != null) { + Vector<Long> goodIds = new Vector<Long>(); + 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<PGPPublicKey> 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 <thi@thialfihar.org>
- *
- * 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<Choice> adapter =
- new ArrayAdapter<Choice>(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 <thi@thialfihar.org> - * - * 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<PGPSecretKey> signKeys = Apg.getUsableSigningKeys(keyRing); - if (signKeys.size() > 0) { - setSecretKeyId(masterKey.getKeyID()); - } - } - } - } - - if (encryptionKeyIds != null) { - Vector<Long> goodIds = new Vector<Long>(); - 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<PGPPublicKey> 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" + |