diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/org/thialfihar/android/apg/Apg.java | 8 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/BaseActivity.java | 17 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/Constants.java | 29 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/EditKeyActivity.java | 2 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/EncryptFileActivity.java | 183 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/EncryptMessageActivity.java | 22 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/FileDialog.java | 7 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/Id.java | 2 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/MainActivity.java | 8 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/PublicKeyListActivity.java | 6 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/SecretKeyListActivity.java | 6 |
11 files changed, 220 insertions, 70 deletions
diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java index fd9d29ccc..dc7090ea6 100644 --- a/src/org/thialfihar/android/apg/Apg.java +++ b/src/org/thialfihar/android/apg/Apg.java @@ -183,6 +183,14 @@ public class Apg { return;
}
+ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ File dir = new File(Constants.path.app_dir);
+ if (!dir.exists() && !dir.mkdirs()) {
+ // ignore this for now, it's not crucial
+ // that the directory doesn't exist at this point
+ }
+ }
+
loadKeyRings(context, Id.type.public_key);
loadKeyRings(context, Id.type.secret_key);
diff --git a/src/org/thialfihar/android/apg/BaseActivity.java b/src/org/thialfihar/android/apg/BaseActivity.java index 09de2ae5a..3365270dd 100644 --- a/src/org/thialfihar/android/apg/BaseActivity.java +++ b/src/org/thialfihar/android/apg/BaseActivity.java @@ -25,7 +25,6 @@ import android.content.Intent; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
public class BaseActivity extends Activity
implements Runnable, ProgressDialogUpdater,
@@ -142,6 +141,21 @@ public class BaseActivity extends Activity @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
+ case Id.request.secret_keys: {
+ if (resultCode == RESULT_OK) {
+ Bundle bundle = data.getExtras();
+ long newId = bundle.getLong("selectedKeyId");
+ if (getSecretKeyId() != newId) {
+ Apg.setPassPhrase(null);
+ }
+ setSecretKeyId(newId);
+ } else {
+ setSecretKeyId(0);
+ Apg.setPassPhrase(null);
+ }
+ break;
+ }
+
default: {
break;
}
@@ -208,7 +222,6 @@ public class BaseActivity extends Activity }
public void passPhraseCallback(String passPhrase) {
- Log.e("oink", "setting pass phrase to " + passPhrase);
Apg.setPassPhrase(passPhrase);
}
diff --git a/src/org/thialfihar/android/apg/Constants.java b/src/org/thialfihar/android/apg/Constants.java new file mode 100644 index 000000000..fdd71578e --- /dev/null +++ b/src/org/thialfihar/android/apg/Constants.java @@ -0,0 +1,29 @@ +/*
+ * 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 android.os.Environment;
+
+public final class Constants {
+ public static final class path {
+ public static final String app_dir = Environment.getExternalStorageDirectory() + "/APG";
+ }
+
+ public static final class pref {
+ public static final String has_seen_change_log = "seenChangeLogDialog" + Apg.VERSION;
+ }
+}
diff --git a/src/org/thialfihar/android/apg/EditKeyActivity.java b/src/org/thialfihar/android/apg/EditKeyActivity.java index 6f13efabb..b44cc145d 100644 --- a/src/org/thialfihar/android/apg/EditKeyActivity.java +++ b/src/org/thialfihar/android/apg/EditKeyActivity.java @@ -36,7 +36,6 @@ import android.os.Bundle; import android.os.Message; import android.text.InputType; import android.text.method.PasswordTransformationMethod; -import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -116,7 +115,6 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener { } public boolean havePassPhrase() { - Log.e("oink", "password is " + Apg.getPassPhrase()); return (Apg.getPassPhrase() != null && !Apg.getPassPhrase().equals("")) || (mNewPassPhrase != null && mNewPassPhrase.equals("")); } diff --git a/src/org/thialfihar/android/apg/EncryptFileActivity.java b/src/org/thialfihar/android/apg/EncryptFileActivity.java index a9b05c687..461938a14 100644 --- a/src/org/thialfihar/android/apg/EncryptFileActivity.java +++ b/src/org/thialfihar/android/apg/EncryptFileActivity.java @@ -16,10 +16,13 @@ package org.thialfihar.android.apg;
-import java.io.ByteArrayOutputStream;
+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;
@@ -32,11 +35,14 @@ import org.bouncycastle2.openpgp.PGPPublicKeyRing; import org.bouncycastle2.openpgp.PGPSecretKey;
import org.bouncycastle2.openpgp.PGPSecretKeyRing;
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.view.View;
import android.view.View.OnClickListener;
@@ -51,44 +57,49 @@ import android.widget.Toast; import android.widget.TabHost.TabSpec;
public class EncryptFileActivity extends BaseActivity {
+ private final String TAB_ASYMMETRIC = "TAB_ASYMMETRIC";
+ private final String TAB_SYMMETRIC = "TAB_SYMMETRIC";
+ private TabHost mTabHost = null;
private EditText mFilename = null;
private ImageButton mBrowse = null;
private CheckBox mSign = null;
private TextView mMainUserId = null;
private TextView mMainUserIdRest = null;
- private ListView mList;
+ private ListView mPublicKeyList = null;
private Button mEncryptButton = 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);
- TabHost tabHost = (TabHost) findViewById(R.id.tab_host);
- tabHost.setup();
+ mTabHost = (TabHost) findViewById(R.id.tab_host);
+ mTabHost.setup();
- TabSpec ts1 = tabHost.newTabSpec("TAB_ASYMMETRIC");
+ TabSpec ts1 = mTabHost.newTabSpec(TAB_ASYMMETRIC);
ts1.setIndicator(getString(R.string.tab_asymmetric),
getResources().getDrawable(R.drawable.key));
ts1.setContent(R.id.tab_asymmetric);
- tabHost.addTab(ts1);
+ mTabHost.addTab(ts1);
- TabSpec ts2 = tabHost.newTabSpec("TAB_SYMMETRIC");
+ TabSpec ts2 = mTabHost.newTabSpec(TAB_SYMMETRIC);
ts2.setIndicator(getString(R.string.tab_symmetric),
getResources().getDrawable(R.drawable.encrypted));
ts2.setContent(R.id.tab_symmetric);
- tabHost.addTab(ts2);
+ mTabHost.addTab(ts2);
- tabHost.setCurrentTab(0);
+ mTabHost.setCurrentTab(0);
Vector<PGPPublicKeyRing> keyRings =
(Vector<PGPPublicKeyRing>) Apg.getPublicKeyRings().clone();
Collections.sort(keyRings, new Apg.PublicKeySorter());
- mList = (ListView) findViewById(R.id.public_key_list);
- mList.setAdapter(new SelectPublicKeyListAdapter(mList, keyRings));
+ mPublicKeyList = (ListView) findViewById(R.id.public_key_list);
+ mPublicKeyList.setAdapter(new SelectPublicKeyListAdapter(mPublicKeyList, keyRings));
mFilename = (EditText) findViewById(R.id.filename);
mBrowse = (ImageButton) findViewById(R.id.btn_browse);
@@ -180,17 +191,60 @@ public class EncryptFileActivity extends BaseActivity { }
private void encryptClicked() {
- if (getSecretKeyId() != 0 && Apg.getPassPhrase() == null) {
- showDialog(Id.dialog.pass_phrase);
+ String currentFilename = mFilename.getText().toString();
+ if (mInputFilename == null || !mInputFilename.equals(currentFilename)) {
+ mInputFilename = mFilename.getText().toString();
+ File file = new File(mInputFilename);
+ mOutputFilename = Constants.path.app_dir + "/" + file.getName() + ".gpg";
+ }
+
+ if (mInputFilename.equals("")) {
+ Toast.makeText(this, "Select a file first.", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ if (mTabHost.getCurrentTabTag().equals(TAB_ASYMMETRIC)) {
+ Vector<Long> vector = new Vector<Long>();
+ for (int i = 0; i < mPublicKeyList.getCount(); ++i) {
+ if (mPublicKeyList.isItemChecked(i)) {
+ vector.add(mPublicKeyList.getItemIdAtPosition(i));
+ }
+ }
+ if (vector.size() > 0) {
+ mEncryptionKeyIds = new long[vector.size()];
+ for (int i = 0; i < vector.size(); ++i) {
+ mEncryptionKeyIds[i] = vector.get(i);
+ }
+ } else {
+ mEncryptionKeyIds = null;
+ }
+
+ boolean encryptIt = mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0;
+ if (getSecretKeyId() == 0 && !encryptIt) {
+ Toast.makeText(this, "Select a signature key or encryption keys.",
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ if (getSecretKeyId() != 0 && Apg.getPassPhrase() == null) {
+ showDialog(Id.dialog.pass_phrase);
+ return;
+ }
} else {
- encryptStart();
+
}
+
+ askForOutputFilename();
}
@Override
public void passPhraseCallback(String passPhrase) {
super.passPhraseCallback(passPhrase);
- encryptStart();
+ askForOutputFilename();
+ }
+
+ private void askForOutputFilename() {
+ showDialog(Id.dialog.output_filename);
}
private void encryptStart() {
@@ -205,19 +259,35 @@ public class EncryptFileActivity extends BaseActivity { Message msg = new Message();
try {
- InputStream in = new FileInputStream(mFilename.getText().toString());
- ByteArrayOutputStream out = new ByteArrayOutputStream();
+ 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");
+ }
+ }
- if (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) {
- Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(),
- Apg.getPassPhrase(), this);
- data.putString("message", new String(out.toByteArray()));
+ InputStream in = new FileInputStream(mInputFilename);
+ OutputStream out = new FileOutputStream(mOutputFilename);
+
+ if (mTabHost.getCurrentTabTag().equals(TAB_ASYMMETRIC)) {
+ boolean encryptIt = mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0;
+
+ if (encryptIt) {
+ Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(),
+ Apg.getPassPhrase(), this);
+ } else {
+ Apg.signText(in, out, getSecretKeyId(),
+ Apg.getPassPhrase(), HashAlgorithmTags.SHA256, this);
+ }
} else {
- Apg.signText(in, out, getSecretKeyId(),
- Apg.getPassPhrase(), HashAlgorithmTags.SHA256, this);
- data.putString("message", new String(out.toByteArray()));
+
}
- } catch (IOException e) {
+
+ out.close();
+ } catch (FileNotFoundException e) {
+ error = "file not found: " + e.getMessage();
+ }
+ catch (IOException e) {
error = e.getMessage();
} catch (PGPException e) {
error = e.getMessage();
@@ -235,6 +305,9 @@ public class EncryptFileActivity extends BaseActivity { if (error != null) {
data.putString("error", error);
+ // delete the file if an error occurred
+ File file = new File(mOutputFilename);
+ file.delete();
}
msg.setData(data);
@@ -242,6 +315,41 @@ public class EncryptFileActivity extends BaseActivity { }
@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: {
@@ -261,20 +369,21 @@ public class EncryptFileActivity extends BaseActivity { return;
}
- case Id.request.secret_keys: {
- if (resultCode == RESULT_OK) {
- Bundle bundle = data.getExtras();
- long newId = bundle.getLong("selectedKeyId");
- if (getSecretKeyId() != newId) {
- Apg.setPassPhrase(null);
+ 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);
}
- setSecretKeyId(newId);
- } else {
- setSecretKeyId(0);
- Apg.setPassPhrase(null);
}
- updateView();
- break;
+ return;
}
default: {
diff --git a/src/org/thialfihar/android/apg/EncryptMessageActivity.java b/src/org/thialfihar/android/apg/EncryptMessageActivity.java index d89e62bd0..4b808ba85 100644 --- a/src/org/thialfihar/android/apg/EncryptMessageActivity.java +++ b/src/org/thialfihar/android/apg/EncryptMessageActivity.java @@ -178,6 +178,9 @@ public class EncryptMessageActivity extends BaseActivity { 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) { @@ -198,12 +201,11 @@ public class EncryptMessageActivity extends BaseActivity { if (encryptIt) { Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(), Apg.getPassPhrase(), this); - data.putString("message", new String(out.toByteArray())); } else { Apg.signText(in, out, getSecretKeyId(), Apg.getPassPhrase(), HashAlgorithmTags.SHA256, this); - data.putString("message", new String(out.toByteArray())); } + data.putString("message", new String(out.toByteArray())); } catch (IOException e) { error = e.getMessage(); } catch (PGPException e) { @@ -288,22 +290,6 @@ public class EncryptMessageActivity extends BaseActivity { break; } - case Id.request.secret_keys: { - if (resultCode == RESULT_OK) { - Bundle bundle = data.getExtras(); - long newId = bundle.getLong("selectedKeyId"); - if (getSecretKeyId() != newId) { - Apg.setPassPhrase(null); - } - setSecretKeyId(newId); - } else { - setSecretKeyId(0); - Apg.setPassPhrase(null); - } - updateView(); - break; - } - default: { break; } diff --git a/src/org/thialfihar/android/apg/FileDialog.java b/src/org/thialfihar/android/apg/FileDialog.java index 653ca1005..891606362 100644 --- a/src/org/thialfihar/android/apg/FileDialog.java +++ b/src/org/thialfihar/android/apg/FileDialog.java @@ -37,6 +37,7 @@ public class FileDialog { private static Activity mActivity;
private static String mFileManagerTitle;
private static String mFileManagerButton;
+ private static int mRequestCode;
public static interface OnClickListener {
public void onCancelClick();
@@ -45,7 +46,8 @@ public class FileDialog { public static AlertDialog build(Activity activity, String title, String message,
String defaultFile, OnClickListener onClickListener,
- String fileManagerTitle, String fileManagerButton) {
+ String fileManagerTitle, String fileManagerButton,
+ int requestCode) {
LayoutInflater inflater =
(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
@@ -67,6 +69,7 @@ public class FileDialog { });
mFileManagerTitle = fileManagerTitle;
mFileManagerButton = fileManagerButton;
+ mRequestCode = requestCode;
alert.setView(view);
@@ -107,7 +110,7 @@ public class FileDialog { intent.putExtra(FileManager.EXTRA_BUTTON_TEXT, mFileManagerButton);
try {
- mActivity.startActivityForResult(intent, Id.request.filename);
+ mActivity.startActivityForResult(intent, mRequestCode);
} catch (ActivityNotFoundException e) {
// No compatible file manager was found.
Toast.makeText(mActivity, R.string.no_filemanager_installed, Toast.LENGTH_SHORT).show();
diff --git a/src/org/thialfihar/android/apg/Id.java b/src/org/thialfihar/android/apg/Id.java index 7a57b706d..92932a7d6 100644 --- a/src/org/thialfihar/android/apg/Id.java +++ b/src/org/thialfihar/android/apg/Id.java @@ -48,6 +48,7 @@ public final class Id { public static final int public_keys = 0x21070001;
public static final int secret_keys = 0x21070002;
public static final int filename = 0x21070003;
+ public static final int output_filename = 0x21070004;
}
public static final class dialog {
@@ -67,6 +68,7 @@ public final class Id { public static final int new_account = 0x2107000e;
public static final int about = 0x2107000f;
public static final int change_log = 0x21070010;
+ public static final int output_filename = 0x21070011;
}
public static final class task {
diff --git a/src/org/thialfihar/android/apg/MainActivity.java b/src/org/thialfihar/android/apg/MainActivity.java index 8cd9df6bf..b1c656207 100644 --- a/src/org/thialfihar/android/apg/MainActivity.java +++ b/src/org/thialfihar/android/apg/MainActivity.java @@ -52,9 +52,6 @@ import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; public class MainActivity extends BaseActivity { - - private static String PREF_SEEN_CHANGE_LOG = "seenChangeLogDialog" + Apg.VERSION; - private ListView mAccounts = null; @Override @@ -116,7 +113,7 @@ public class MainActivity extends BaseActivity { registerForContextMenu(mAccounts); SharedPreferences prefs = getPreferences(MODE_PRIVATE); - if (!prefs.getBoolean(PREF_SEEN_CHANGE_LOG, false)) { + if (!prefs.getBoolean(Constants.pref.has_seen_change_log, false)) { showDialog(Id.dialog.change_log); } } @@ -227,6 +224,7 @@ public class MainActivity extends BaseActivity { new SpannableString("Read the warnings!\n\n" + "Changes:\n" + " * OI File Manager support\n" + + " * file encryption\n" + "\n" + "WARNING: be careful editing your existing keys, as they " + "WILL be stripped of certificates right now.\n" + @@ -253,7 +251,7 @@ public class MainActivity extends BaseActivity { MainActivity.this.removeDialog(Id.dialog.change_log); SharedPreferences prefs = getPreferences(MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(PREF_SEEN_CHANGE_LOG, true); + editor.putBoolean(Constants.pref.has_seen_change_log, true); editor.commit(); } }); diff --git a/src/org/thialfihar/android/apg/PublicKeyListActivity.java b/src/org/thialfihar/android/apg/PublicKeyListActivity.java index d6a2aa577..417d7e626 100644 --- a/src/org/thialfihar/android/apg/PublicKeyListActivity.java +++ b/src/org/thialfihar/android/apg/PublicKeyListActivity.java @@ -192,7 +192,8 @@ public class PublicKeyListActivity extends BaseActivity { }
},
getString(R.string.filemanager_title_open),
- getString(R.string.filemanager_btn_open));
+ getString(R.string.filemanager_btn_open),
+ Id.request.filename);
}
case Id.dialog.export_key: {
@@ -228,7 +229,8 @@ public class PublicKeyListActivity extends BaseActivity { }
},
getString(R.string.filemanager_title_save),
- getString(R.string.filemanager_btn_save));
+ getString(R.string.filemanager_btn_save),
+ Id.request.filename);
}
default: {
diff --git a/src/org/thialfihar/android/apg/SecretKeyListActivity.java b/src/org/thialfihar/android/apg/SecretKeyListActivity.java index 9eff85d24..f2f89fae9 100644 --- a/src/org/thialfihar/android/apg/SecretKeyListActivity.java +++ b/src/org/thialfihar/android/apg/SecretKeyListActivity.java @@ -217,7 +217,8 @@ public class SecretKeyListActivity extends BaseActivity implements OnChildClickL }
},
getString(R.string.filemanager_title_open),
- getString(R.string.filemanager_btn_open));
+ getString(R.string.filemanager_btn_open),
+ Id.request.filename);
}
case Id.dialog.export_key: {
@@ -254,7 +255,8 @@ public class SecretKeyListActivity extends BaseActivity implements OnChildClickL }
},
getString(R.string.filemanager_title_save),
- getString(R.string.filemanager_btn_save));
+ getString(R.string.filemanager_btn_save),
+ Id.request.filename);
}
case Id.dialog.pass_phrase: {
|