aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OpenPGP-Keychain-API-Demo/res/layout/crypto_provider_demo.xml2
-rw-r--r--OpenPGP-Keychain-API-Demo/src/org/openintents/crypto/ICryptoService.aidl12
-rw-r--r--OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java17
-rw-r--r--OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml36
-rw-r--r--OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl6
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/KeychainApplication.java6
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java56
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java1
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java13
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java3
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettings.java16
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettingsFragment.java103
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java97
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/KeyValueSpinnerAdapter.java101
14 files changed, 345 insertions, 124 deletions
diff --git a/OpenPGP-Keychain-API-Demo/res/layout/crypto_provider_demo.xml b/OpenPGP-Keychain-API-Demo/res/layout/crypto_provider_demo.xml
index 47a8b6520..0579aa643 100644
--- a/OpenPGP-Keychain-API-Demo/res/layout/crypto_provider_demo.xml
+++ b/OpenPGP-Keychain-API-Demo/res/layout/crypto_provider_demo.xml
@@ -78,7 +78,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:onClick="decryptOnClick"
+ android:onClick="decryptAndVerifyOnClick"
android:text="Decrypt" />
</LinearLayout>
diff --git a/OpenPGP-Keychain-API-Demo/src/org/openintents/crypto/ICryptoService.aidl b/OpenPGP-Keychain-API-Demo/src/org/openintents/crypto/ICryptoService.aidl
index b74ab642c..45a80dfd3 100644
--- a/OpenPGP-Keychain-API-Demo/src/org/openintents/crypto/ICryptoService.aidl
+++ b/OpenPGP-Keychain-API-Demo/src/org/openintents/crypto/ICryptoService.aidl
@@ -34,7 +34,7 @@ interface ICryptoService {
* @param callback
* Callback where to return results
*/
- oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback);
+ oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, in ICryptoCallback callback);
/**
* Sign
@@ -44,7 +44,7 @@ interface ICryptoService {
* @param callback
* Callback where to return results
*/
- oneway void sign(in byte[] inputBytes, in ICryptoCallback callback);
+ oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in ICryptoCallback callback);
/**
* Encrypt and sign
@@ -58,7 +58,7 @@ interface ICryptoService {
* @param callback
* Callback where to return results
*/
- oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback);
+ oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, in ICryptoCallback callback);
/**
* Decrypts and verifies given input bytes. If no signature is present this method
@@ -71,10 +71,4 @@ interface ICryptoService {
*/
oneway void decryptAndVerify(in byte[] inputBytes, in ICryptoCallback callback);
- /**
- * Opens setup using default parameters
- *
- */
- oneway void setup(boolean asciiArmor, boolean newKeyring, String newKeyringUserId);
-
} \ No newline at end of file
diff --git a/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java b/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java
index db84a1742..f60db04b2 100644
--- a/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java
+++ b/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java
@@ -74,7 +74,7 @@ public class CryptoProviderDemoActivity extends Activity {
@Override
public void onSuccess(final byte[] outputBytes, CryptoSignatureResult signatureResult)
throws RemoteException {
- Log.d(Constants.TAG, "onEncryptSignSuccess");
+ Log.d(Constants.TAG, "encryptCallback");
runOnUiThread(new Runnable() {
@@ -92,12 +92,12 @@ public class CryptoProviderDemoActivity extends Activity {
};
- final ICryptoCallback.Stub decryptCallback = new ICryptoCallback.Stub() {
+ final ICryptoCallback.Stub decryptAndVerifyCallback = new ICryptoCallback.Stub() {
@Override
public void onSuccess(final byte[] outputBytes, final CryptoSignatureResult signatureResult)
throws RemoteException {
- Log.d(Constants.TAG, "onDecryptVerifySuccess");
+ Log.d(Constants.TAG, "decryptAndVerifyCallback");
runOnUiThread(new Runnable() {
@@ -136,7 +136,7 @@ public class CryptoProviderDemoActivity extends Activity {
try {
mCryptoServiceConnection.getService().encrypt(inputBytes,
- mEncryptUserIds.getText().toString().split(","), encryptCallback);
+ mEncryptUserIds.getText().toString().split(","), true, encryptCallback);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoProviderDemo", e);
}
@@ -146,7 +146,7 @@ public class CryptoProviderDemoActivity extends Activity {
byte[] inputBytes = mMessage.getText().toString().getBytes();
try {
- mCryptoServiceConnection.getService().sign(inputBytes, encryptCallback);
+ mCryptoServiceConnection.getService().sign(inputBytes, true, encryptCallback);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoProviderDemo", e);
}
@@ -157,17 +157,18 @@ public class CryptoProviderDemoActivity extends Activity {
try {
mCryptoServiceConnection.getService().encryptAndSign(inputBytes,
- mEncryptUserIds.getText().toString().split(","), encryptCallback);
+ mEncryptUserIds.getText().toString().split(","), true, encryptCallback);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoProviderDemo", e);
}
}
- public void decryptOnClick(View view) {
+ public void decryptAndVerifyOnClick(View view) {
byte[] inputBytes = mCiphertext.getText().toString().getBytes();
try {
- mCryptoServiceConnection.getService().decryptAndVerify(inputBytes, decryptCallback);
+ mCryptoServiceConnection.getService().decryptAndVerify(inputBytes,
+ decryptAndVerifyCallback);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoProviderDemo", e);
}
diff --git a/OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml b/OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml
index 307da3efb..45dd11252 100644
--- a/OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml
+++ b/OpenPGP-Keychain/res/layout/api_app_settings_fragment.xml
@@ -82,15 +82,41 @@
android:id="@+id/api_app_settings_advanced"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:visibility="invisible" >
- <CheckBox
- android:id="@+id/api_app_ascii_armor"
+ <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:text="@string/label_asciiArmour" />
+ android:text="@string/label_encryptionAlgorithm"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Spinner
+ android:id="@+id/api_app_settings_encryption_algorithm"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/label_hashAlgorithm"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Spinner
+ android:id="@+id/api_app_settings_hash_algorithm"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/label_messageCompression"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Spinner
+ android:id="@+id/api_app_settings_compression"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl b/OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl
index 555a71cd6..45a80dfd3 100644
--- a/OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl
+++ b/OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl
@@ -34,7 +34,7 @@ interface ICryptoService {
* @param callback
* Callback where to return results
*/
- oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback);
+ oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, in ICryptoCallback callback);
/**
* Sign
@@ -44,7 +44,7 @@ interface ICryptoService {
* @param callback
* Callback where to return results
*/
- oneway void sign(in byte[] inputBytes, in ICryptoCallback callback);
+ oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in ICryptoCallback callback);
/**
* Encrypt and sign
@@ -58,7 +58,7 @@ interface ICryptoService {
* @param callback
* Callback where to return results
*/
- oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback);
+ oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, in ICryptoCallback callback);
/**
* Decrypts and verifies given input bytes. If no signature is present this method
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/KeychainApplication.java
index 7f06ccc04..654eca5b8 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/KeychainApplication.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/KeychainApplication.java
@@ -21,6 +21,7 @@ import java.io.File;
import java.security.Security;
import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PRNGFixes;
import android.app.Application;
@@ -30,15 +31,16 @@ public class KeychainApplication extends Application {
static {
// Define Java Security Provider to be Bouncy Castle
- Security.insertProviderAt(new BouncyCastleProvider(), 1);
+ Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
@Override
public void onCreate() {
super.onCreate();
-
+
// apply RNG fixes
PRNGFixes.apply();
+ Log.d(Constants.TAG, "PRNG Fixes applied!");
// Create APG directory on sdcard if not existing
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java
index 76fc880a0..71466ff22 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java
@@ -17,6 +17,30 @@
package org.sufficientlysecure.keychain.helper;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.SignatureException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.regex.Pattern;
+
import org.spongycastle.bcpg.ArmoredInputStream;
import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.bcpg.BCPGOutputStream;
@@ -45,7 +69,6 @@ import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPPublicKeyRingCollection;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
@@ -75,17 +98,17 @@ import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactory
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
+import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.util.HkpKeyServer;
import org.sufficientlysecure.keychain.util.InputData;
+import org.sufficientlysecure.keychain.util.IterableIterator;
+import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
import org.sufficientlysecure.keychain.util.Primes;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
-import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException;
-import org.sufficientlysecure.keychain.util.IterableIterator;
-import org.sufficientlysecure.keychain.R;
import android.content.Context;
import android.content.pm.PackageInfo;
@@ -93,31 +116,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Environment;
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.SignatureException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.regex.Pattern;
-
/**
* TODO:
*
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java
index 9207cb596..82dcfe15f 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainContract.java
@@ -56,7 +56,6 @@ public class KeychainContract {
interface ApiAppsColumns {
String PACKAGE_NAME = "package_name";
String KEY_ID = "key_id"; // not a database id
- String ASCII_ARMOR = "ascii_armor";
String ENCRYPTION_ALGORITHM = "encryption_algorithm";
String HASH_ALORITHM = "hash_algorithm";
String COMPRESSION = "compression";
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
index be640df57..0f962967d 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
@@ -64,14 +64,11 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
+ BaseColumns._ID + ") ON DELETE CASCADE)";
- private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS "
- + Tables.API_APPS + " (" + BaseColumns._ID
- + " INTEGER PRIMARY KEY AUTOINCREMENT, " + ApiAppsColumns.PACKAGE_NAME
- + " TEXT UNIQUE, " + ApiAppsColumns.KEY_ID + " INT64, "
- + ApiAppsColumns.ASCII_ARMOR + " INTEGER, "
- + ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, "
- + ApiAppsColumns.HASH_ALORITHM + " INTEGER, "
- + ApiAppsColumns.COMPRESSION + " INTEGER)";
+ private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS
+ + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, " + ApiAppsColumns.KEY_ID + " INT64, "
+ + ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + ApiAppsColumns.HASH_ALORITHM
+ + " INTEGER, " + ApiAppsColumns.COMPRESSION + " INTEGER)";
KeychainDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index 13f4e085c..7f7e81e8c 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -745,7 +745,6 @@ public class ProviderHelper {
ContentValues values = new ContentValues();
values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName());
values.put(ApiApps.KEY_ID, appSettings.getKeyId());
- values.put(ApiApps.ASCII_ARMOR, appSettings.isAsciiArmor());
values.put(ApiApps.COMPRESSION, appSettings.getCompression());
values.put(ApiApps.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm());
values.put(ApiApps.HASH_ALORITHM, appSettings.getHashAlgorithm());
@@ -775,8 +774,6 @@ public class ProviderHelper {
settings.setPackageName(cur.getString(cur
.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME)));
settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.ApiApps.KEY_ID)));
- settings.setAsciiArmor(cur.getInt(cur
- .getColumnIndexOrThrow(KeychainContract.ApiApps.ASCII_ARMOR)) == 1);
settings.setCompression(cur.getInt(cur
.getColumnIndexOrThrow(KeychainContract.ApiApps.COMPRESSION)));
settings.setHashAlgorithm(cur.getInt(cur
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettings.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettings.java
index 98f48ff59..eb2527455 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettings.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettings.java
@@ -24,7 +24,6 @@ import org.sufficientlysecure.keychain.Id;
public class AppSettings {
private String packageName;
private long keyId = Id.key.none;
- private boolean asciiArmor;
private int encryptionAlgorithm;
private int hashAlgorithm;
private int compression;
@@ -37,10 +36,9 @@ public class AppSettings {
super();
this.packageName = packageName;
// defaults:
- this.asciiArmor = true;
- this.encryptionAlgorithm = PGPEncryptedData.AES_128; // AES-128
- this.hashAlgorithm = HashAlgorithmTags.SHA512; // SHA-512
- this.compression = Id.choice.compression.zlib; // zlib
+ this.encryptionAlgorithm = PGPEncryptedData.AES_128;
+ this.hashAlgorithm = HashAlgorithmTags.SHA256;
+ this.compression = Id.choice.compression.zlib;
}
public String getPackageName() {
@@ -59,14 +57,6 @@ public class AppSettings {
this.keyId = scretKeyId;
}
- public boolean isAsciiArmor() {
- return asciiArmor;
- }
-
- public void setAsciiArmor(boolean asciiArmor) {
- this.asciiArmor = asciiArmor;
- }
-
public int getEncryptionAlgorithm() {
return encryptionAlgorithm;
}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettingsFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettingsFragment.java
index 8cef63ca3..a29b63e97 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettingsFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/AppSettingsFragment.java
@@ -17,6 +17,10 @@
package org.sufficientlysecure.keychain.remote_api;
+import java.util.HashMap;
+
+import org.spongycastle.bcpg.HashAlgorithmTags;
+import org.spongycastle.openpgp.PGPEncryptedData;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.Constants;
@@ -25,6 +29,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.PgpHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.ui.SelectSecretKeyActivity;
+import org.sufficientlysecure.keychain.util.KeyValueSpinnerAdapter;
import org.sufficientlysecure.keychain.util.Log;
import android.app.Activity;
@@ -41,12 +46,12 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.Spinner;
import android.widget.TextView;
public class AppSettingsFragment extends Fragment {
@@ -62,7 +67,13 @@ public class AppSettingsFragment extends Fragment {
private TextView mKeyUserId;
private TextView mKeyUserIdRest;
private Button mSelectKeyButton;
- private CheckBox mAsciiArmorCheckBox;
+ private Spinner mEncryptionAlgorithm;
+ private Spinner mHashAlgorithm;
+ private Spinner mCompression;
+
+ KeyValueSpinnerAdapter encryptionAdapter;
+ KeyValueSpinnerAdapter hashAdapter;
+ KeyValueSpinnerAdapter compressionAdapter;
public AppSettings getAppSettings() {
return appSettings;
@@ -72,7 +83,10 @@ public class AppSettingsFragment extends Fragment {
this.appSettings = appSettings;
setPackage(appSettings.getPackageName());
updateSelectedKeyView(appSettings.getKeyId());
- mAsciiArmorCheckBox.setChecked(appSettings.isAsciiArmor());
+ mEncryptionAlgorithm.setSelection(encryptionAdapter.getPosition(appSettings
+ .getEncryptionAlgorithm()));
+ mHashAlgorithm.setSelection(hashAdapter.getPosition(appSettings.getHashAlgorithm()));
+ mCompression.setSelection(compressionAdapter.getPosition(appSettings.getCompression()));
}
/**
@@ -95,21 +109,86 @@ public class AppSettingsFragment extends Fragment {
mKeyUserId = (TextView) view.findViewById(R.id.api_app_settings_user_id);
mKeyUserIdRest = (TextView) view.findViewById(R.id.api_app_settings_user_id_rest);
mSelectKeyButton = (Button) view.findViewById(R.id.api_app_settings_select_key_button);
- mAsciiArmorCheckBox = (CheckBox) view.findViewById(R.id.api_app_ascii_armor);
+ mEncryptionAlgorithm = (Spinner) view
+ .findViewById(R.id.api_app_settings_encryption_algorithm);
+ mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm);
+ mCompression = (Spinner) view.findViewById(R.id.api_app_settings_compression);
- mSelectKeyButton.setOnClickListener(new OnClickListener() {
+ HashMap<Integer, String> encryptionMap = new HashMap<Integer, String>();
+ encryptionMap.put(PGPEncryptedData.AES_128, "AES-128");
+ encryptionMap.put(PGPEncryptedData.AES_192, "AES-192");
+ encryptionMap.put(PGPEncryptedData.AES_256, "AES-256");
+ encryptionMap.put(PGPEncryptedData.BLOWFISH, "Blowfish");
+ encryptionMap.put(PGPEncryptedData.TWOFISH, "Twofish");
+ encryptionMap.put(PGPEncryptedData.CAST5, "CAST5");
+ encryptionMap.put(PGPEncryptedData.DES, "DES");
+ encryptionMap.put(PGPEncryptedData.TRIPLE_DES, "Triple DES");
+ encryptionMap.put(PGPEncryptedData.IDEA, "IDEA");
+
+ encryptionAdapter = new KeyValueSpinnerAdapter(getActivity(), encryptionMap);
+ mEncryptionAlgorithm.setAdapter(encryptionAdapter);
+ mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
- public void onClick(View v) {
- selectSecretKey();
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ appSettings.setEncryptionAlgorithm((int) id);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+
+ HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
+ hashMap.put(HashAlgorithmTags.MD5, "MD5");
+ hashMap.put(HashAlgorithmTags.RIPEMD160, "RIPEMD-160");
+ hashMap.put(HashAlgorithmTags.SHA1, "SHA-1");
+ hashMap.put(HashAlgorithmTags.SHA224, "SHA-224");
+ hashMap.put(HashAlgorithmTags.SHA256, "SHA-256");
+ hashMap.put(HashAlgorithmTags.SHA384, "SHA-384");
+ hashMap.put(HashAlgorithmTags.SHA512, "SHA-512");
+
+ hashAdapter = new KeyValueSpinnerAdapter(getActivity(), hashMap);
+ mHashAlgorithm.setAdapter(hashAdapter);
+ mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ appSettings.setHashAlgorithm((int) id);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
}
});
- mAsciiArmorCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+ HashMap<Integer, String> compressionMap = new HashMap<Integer, String>();
+ compressionMap.put(Id.choice.compression.none, getString(R.string.choice_none) + " ("
+ + getString(R.string.fast) + ")");
+ compressionMap.put(Id.choice.compression.zip, "ZIP (" + getString(R.string.fast) + ")");
+ compressionMap.put(Id.choice.compression.zlib, "ZLIB (" + getString(R.string.fast) + ")");
+ compressionMap.put(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow)
+ + ")");
+
+ compressionAdapter = new KeyValueSpinnerAdapter(getActivity(), compressionMap);
+ mCompression.setAdapter(compressionAdapter);
+ mCompression.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- appSettings.setAsciiArmor(isChecked);
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ appSettings.setCompression((int) id);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+
+ mSelectKeyButton.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ selectSecretKey();
}
});
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java
index e33314ea6..defacb448 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java
@@ -24,6 +24,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
import org.openintents.crypto.CryptoError;
import org.openintents.crypto.CryptoSignatureResult;
@@ -233,7 +234,8 @@ public class CryptoService extends Service {
};
private synchronized void encryptAndSignSafe(byte[] inputBytes, String[] encryptionUserIds,
- ICryptoCallback callback, AppSettings appSettings, boolean sign) throws RemoteException {
+ boolean asciiArmor, ICryptoCallback callback, AppSettings appSettings, boolean sign)
+ throws RemoteException {
try {
// build InputData and write into OutputStream
InputStream inputStream = new ByteArrayInputStream(inputBytes);
@@ -252,13 +254,13 @@ public class CryptoService extends Service {
return;
}
- PgpMain.encryptAndSign(mContext, null, inputData, outputStream,
- appSettings.isAsciiArmor(), appSettings.getCompression(), keyIds, null,
+ PgpMain.encryptAndSign(mContext, null, inputData, outputStream, asciiArmor,
+ appSettings.getCompression(), keyIds, null,
appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
appSettings.getHashAlgorithm(), true, passphrase);
} else {
- PgpMain.encryptAndSign(mContext, null, inputData, outputStream,
- appSettings.isAsciiArmor(), appSettings.getCompression(), keyIds, null,
+ PgpMain.encryptAndSign(mContext, null, inputData, outputStream, asciiArmor,
+ appSettings.getCompression(), keyIds, null,
appSettings.getEncryptionAlgorithm(), Id.key.none,
appSettings.getHashAlgorithm(), true, null);
}
@@ -280,6 +282,7 @@ public class CryptoService extends Service {
}
}
+ // TODO: asciiArmor?!
private void signSafe(byte[] inputBytes, ICryptoCallback callback, AppSettings appSettings)
throws RemoteException {
try {
@@ -327,19 +330,50 @@ public class CryptoService extends Service {
InputStream inputStream = new ByteArrayInputStream(inputBytes);
long inputLength = inputBytes.length;
InputData inputData = new InputData(inputStream, inputLength);
+ OutputStream outputStream = new ByteArrayOutputStream();
- Log.d(Constants.TAG, "in: " + new String(inputBytes));
+ String message = new String(inputBytes);
+ Log.d(Constants.TAG, "in: " + message);
- OutputStream outputStream = new ByteArrayOutputStream();
+ // checked if signed only
+ boolean signedOnly = false;
+ Matcher matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(message);
+ if (matcher.matches()) {
+ signedOnly = true;
+ }
// TODO: This allows to decrypt messages with ALL secret keys, not only the one for the
// app, Fix this?
- long secretKeyId = PgpMain.getDecryptionKeyId(mContext, inputStream);
- if (secretKeyId == Id.key.none) {
- throw new PgpMain.PgpGeneralException(getString(R.string.error_noSecretKeyFound));
- }
+ // long secretKeyId = PgpMain.getDecryptionKeyId(mContext, inputStream);
+ // if (secretKeyId == Id.key.none) {
+ // throw new PgpMain.PgpGeneralException(getString(R.string.error_noSecretKeyFound));
+ // }
- Log.d(Constants.TAG, "Got input:\n" + new String(inputBytes));
+ // TODO: duplicates functions from DecryptActivity!
+ boolean assumeSymmetricEncryption = false;
+ long secretKeyId;
+ try {
+ if (inputStream.markSupported()) {
+ inputStream.mark(200); // should probably set this to the max size of two pgpF
+ // objects, if it even needs to be anything other than 0.
+ }
+ secretKeyId = PgpMain.getDecryptionKeyId(this, inputStream);
+ if (secretKeyId == Id.key.none) {
+ throw new PgpMain.PgpGeneralException(
+ getString(R.string.error_noSecretKeyFound));
+ }
+ assumeSymmetricEncryption = false;
+ } catch (PgpMain.NoAsymmetricEncryptionException e) {
+ if (inputStream.markSupported()) {
+ inputStream.reset();
+ }
+ secretKeyId = Id.key.symmetric;
+ if (!PgpMain.hasSymmetricEncryption(this, inputStream)) {
+ throw new PgpMain.PgpGeneralException(
+ getString(R.string.error_noKnownEncryptionFound));
+ }
+ assumeSymmetricEncryption = true;
+ }
Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
@@ -350,17 +384,15 @@ public class CryptoService extends Service {
return;
}
- // if (signedOnly) {
- // resultData = PgpMain.verifyText(this, this, inputData, outStream,
- // lookupUnknownKey);
- // } else {
- // resultData = PgpMain.decryptAndVerify(this, this, inputData, outStream,
- // PassphraseCacheService.getCachedPassphrase(this, secretKeyId),
- // assumeSymmetricEncryption);
- // }
-
- Bundle outputBundle = PgpMain.decryptAndVerify(mContext, null, inputData, outputStream,
- passphrase, false);
+ Bundle outputBundle;
+ if (signedOnly) {
+ // TODO: download missing keys from keyserver?
+ outputBundle = PgpMain.verifyText(this, null, inputData, outputStream, false);
+ } else {
+ // TODO: assume symmetric: callback to enter symmetric pass
+ outputBundle = PgpMain.decryptAndVerify(this, null, inputData, outputStream,
+ passphrase, false);
+ }
outputStream.close();
@@ -377,8 +409,11 @@ public class CryptoService extends Service {
boolean signatureUnknown = outputBundle
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN);
- CryptoSignatureResult sigResult = new CryptoSignatureResult(signatureUserId, signature,
- signatureSuccess, signatureUnknown);
+ CryptoSignatureResult sigResult = null;
+ if (signature) {
+ sigResult = new CryptoSignatureResult(signatureUserId, signature, signatureSuccess,
+ signatureUnknown);
+ }
// return over handler on client side
callback.onSuccess(outputBytes, sigResult);
@@ -397,7 +432,7 @@ public class CryptoService extends Service {
@Override
public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds,
- final ICryptoCallback callback) throws RemoteException {
+ final boolean asciiArmor, final ICryptoCallback callback) throws RemoteException {
final AppSettings settings = getAppSettings();
@@ -406,7 +441,8 @@ public class CryptoService extends Service {
@Override
public void run() {
try {
- encryptAndSignSafe(inputBytes, encryptionUserIds, callback, settings, false);
+ encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, callback,
+ settings, false);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoService", e);
}
@@ -418,7 +454,7 @@ public class CryptoService extends Service {
@Override
public void encryptAndSign(final byte[] inputBytes, final String[] encryptionUserIds,
- final ICryptoCallback callback) throws RemoteException {
+ final boolean asciiArmor, final ICryptoCallback callback) throws RemoteException {
final AppSettings settings = getAppSettings();
@@ -427,7 +463,8 @@ public class CryptoService extends Service {
@Override
public void run() {
try {
- encryptAndSignSafe(inputBytes, encryptionUserIds, callback, settings, true);
+ encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, callback,
+ settings, true);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoService", e);
}
@@ -438,7 +475,7 @@ public class CryptoService extends Service {
}
@Override
- public void sign(final byte[] inputBytes, final ICryptoCallback callback)
+ public void sign(final byte[] inputBytes, boolean asciiArmor, final ICryptoCallback callback)
throws RemoteException {
final AppSettings settings = getAppSettings();
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/KeyValueSpinnerAdapter.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/KeyValueSpinnerAdapter.java
new file mode 100644
index 000000000..e8905062c
--- /dev/null
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/util/KeyValueSpinnerAdapter.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.util;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import android.content.Context;
+import android.widget.ArrayAdapter;
+
+public class KeyValueSpinnerAdapter extends ArrayAdapter<String> {
+ private final HashMap<Integer, String> mData;
+ private final int[] mKeys;
+ private final String[] mValues;
+
+ static <K, V extends Comparable<? super V>> SortedSet<Map.Entry<K, V>> entriesSortedByValues(
+ Map<K, V> map) {
+ SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
+ new Comparator<Map.Entry<K, V>>() {
+ @Override
+ public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
+ return e1.getValue().compareTo(e2.getValue());
+ }
+ });
+ sortedEntries.addAll(map.entrySet());
+ return sortedEntries;
+ }
+
+ public KeyValueSpinnerAdapter(Context context, HashMap<Integer, String> objects) {
+ // To make the drop down a simple text box
+ super(context, android.R.layout.simple_spinner_item);
+ mData = objects;
+
+ // To make the drop down view a radio button list
+ setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+
+ SortedSet<Map.Entry<Integer, String>> sorted = entriesSortedByValues(objects);
+
+ // Assign hash keys with a position so that we can present and retrieve them
+ int i = 0;
+ mKeys = new int[mData.size()];
+ mValues = new String[mData.size()];
+ for (Map.Entry<Integer, String> entry : sorted) {
+ mKeys[i] = entry.getKey();
+ mValues[i] = entry.getValue();
+ i++;
+ }
+ }
+
+ public int getCount() {
+ return mData.size();
+ }
+
+ /**
+ * Returns the value
+ */
+ @Override
+ public String getItem(int position) {
+ // return the value based on the position. This is displayed in the list.
+ return mValues[position];
+ }
+
+ /**
+ * Returns item key
+ */
+ public long getItemId(int position) {
+ // Return an id to represent the item.
+
+ return mKeys[position];
+ }
+
+ /**
+ * Find position from key
+ */
+ public int getPosition(long itemId) {
+ for (int i = 0; i < mKeys.length; i++) {
+ if ((int) itemId == mKeys[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+} \ No newline at end of file