From e8d29c01c286f24f660f6d1c55f896c7bc0994c9 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Wed, 29 Dec 2010 16:31:58 +0000 Subject: Add first basic implementation of Apgservice Provides an AIDL-API for other apps to encrypt and decrypt a string symmetrically with a passphrase. Function names and API is by no way finalized and will change! Support for asymetric encription will follow. For reference and discussion see issue #71, https://code.google.com/p/android-privacy-guard/issues/detail?id=71 --- src/org/thialfihar/android/apg/ApgService.java | 76 ++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/org/thialfihar/android/apg/ApgService.java (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java new file mode 100644 index 000000000..6110fe7cd --- /dev/null +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -0,0 +1,76 @@ +package org.thialfihar.android.apg; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; + +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; + +public class ApgService extends Service { + static String TAG = "ApgService"; + + @Override + public IBinder onBind(Intent intent) { + Log.d(TAG, "bound"); + return mBinder; + } + + private final IApgService.Stub mBinder = new IApgService.Stub() { + + public String encrypt_with_passphrase(String msg, String passphrase) { + Preferences mPreferences = Preferences + .getPreferences(getApplicationContext()); + InputStream inStream = new ByteArrayInputStream(msg.getBytes()); + InputData in = new InputData(inStream, 9999); + OutputStream out = new ByteArrayOutputStream(); + long enc_keys[] = {}; + + Apg.initialize(getApplicationContext()); + try { + Apg.encrypt( + getApplicationContext(), + in, + out, + true, // armored + enc_keys, // encryption keys + 0, // signature key + null, // signature passphrase + null, // progress + mPreferences.getDefaultEncryptionAlgorithm(), + mPreferences.getDefaultHashAlgorithm(), + Id.choice.compression.none, false, // mPreferences.getForceV3Signatures(), + passphrase // passPhrase + ); + } catch (Exception e) { + Log.d(TAG, "Exception in encrypt"); + e.printStackTrace(); + return null; + } + Log.d(TAG, "Encrypted"); + return out.toString(); + } + + public String decrypt_with_passphrase(String encrypted_msg, + String passphrase) { + InputStream inStream = new ByteArrayInputStream(encrypted_msg + .getBytes()); + InputData in = new InputData(inStream, 9999); // XXX what size in + // second parameter? + OutputStream out = new ByteArrayOutputStream(); + try { + Apg.decrypt(getApplicationContext(), in, out, passphrase, null, // progress + true // symmetric + ); + } catch (Exception e) { + Log.d(TAG, "Exception in decrypt"); + e.printStackTrace(); + return null; + } + + return out.toString(); + } + }; +} -- cgit v1.2.3 From 2660c561a171a09c1c6ed2610aea3d0efca23f98 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Thu, 30 Dec 2010 13:48:24 +0000 Subject: Reload preferences on call refs r326 --- src/org/thialfihar/android/apg/ApgService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 6110fe7cd..9cdc5099d 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -21,8 +21,7 @@ public class ApgService extends Service { private final IApgService.Stub mBinder = new IApgService.Stub() { public String encrypt_with_passphrase(String msg, String passphrase) { - Preferences mPreferences = Preferences - .getPreferences(getApplicationContext()); + Preferences mPreferences = Preferences.getPreferences(getBaseContext(), true); InputStream inStream = new ByteArrayInputStream(msg.getBytes()); InputData in = new InputData(inStream, 9999); OutputStream out = new ByteArrayOutputStream(); @@ -41,7 +40,8 @@ public class ApgService extends Service { null, // progress mPreferences.getDefaultEncryptionAlgorithm(), mPreferences.getDefaultHashAlgorithm(), - Id.choice.compression.none, false, // mPreferences.getForceV3Signatures(), + Id.choice.compression.none, // compression + false, // mPreferences.getForceV3Signatures(), passphrase // passPhrase ); } catch (Exception e) { -- cgit v1.2.3 From 6477f6076420b71ad1697aa8db9d453bd2422412 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 4 Jan 2011 23:08:08 +0000 Subject: Add connection helper for other projects This eases using the AIDL-Interface and is the recommended way for other project to implement the connection. --- src/org/thialfihar/android/apg/ApgService.java | 31 ++++++++++++++++---------- 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 9cdc5099d..bb5b6463a 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -4,6 +4,10 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import android.content.Intent; import android.os.IBinder; @@ -20,7 +24,10 @@ public class ApgService extends Service { private final IApgService.Stub mBinder = new IApgService.Stub() { - public String encrypt_with_passphrase(String msg, String passphrase) { + public String encrypt_with_passphrase(List args) { + String msg = args.remove(0); + String passphrase = args.remove(0); + Preferences mPreferences = Preferences.getPreferences(getBaseContext(), true); InputStream inStream = new ByteArrayInputStream(msg.getBytes()); InputData in = new InputData(inStream, 9999); @@ -29,17 +36,16 @@ public class ApgService extends Service { Apg.initialize(getApplicationContext()); try { - Apg.encrypt( - getApplicationContext(), - in, - out, + Apg.encrypt(getApplicationContext(), // context + in, // input stream + out, // output stream true, // armored enc_keys, // encryption keys 0, // signature key null, // signature passphrase null, // progress - mPreferences.getDefaultEncryptionAlgorithm(), - mPreferences.getDefaultHashAlgorithm(), + mPreferences.getDefaultEncryptionAlgorithm(), // encryption + mPreferences.getDefaultHashAlgorithm(), // hash Id.choice.compression.none, // compression false, // mPreferences.getForceV3Signatures(), passphrase // passPhrase @@ -53,12 +59,13 @@ public class ApgService extends Service { return out.toString(); } - public String decrypt_with_passphrase(String encrypted_msg, - String passphrase) { - InputStream inStream = new ByteArrayInputStream(encrypted_msg - .getBytes()); + public String decrypt_with_passphrase(List args) { + String encrypted_msg = args.remove(0); + String passphrase = args.remove(0); + + InputStream inStream = new ByteArrayInputStream(encrypted_msg.getBytes()); InputData in = new InputData(inStream, 9999); // XXX what size in - // second parameter? + // second parameter? OutputStream out = new ByteArrayOutputStream(); try { Apg.decrypt(getApplicationContext(), in, out, passphrase, null, // progress -- cgit v1.2.3 From 1a338de47e7d9faa73a3bc6eda51cb47a18dc91b Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Wed, 5 Jan 2011 14:07:09 +0000 Subject: Redesign AIDL-Interface once more Using Bundles makes passing data easier and does not need to redefine the interface if the internel functions change. The helper class has been updated accordingly. In addition, it wrappes completely around all input and output (if wanted). --- src/org/thialfihar/android/apg/ApgService.java | 103 +++++++++++++++++++++---- 1 file changed, 87 insertions(+), 16 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index bb5b6463a..316e9a22c 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -4,12 +4,11 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.ArrayList; +import java.util.Iterator; import android.content.Intent; +import android.os.Bundle; import android.os.IBinder; import android.util.Log; @@ -22,11 +21,45 @@ public class ApgService extends Service { return mBinder; } + private enum error { + ARGUMENTS_MISSING, + APG_FAILURE + } + private final IApgService.Stub mBinder = new IApgService.Stub() { - public String encrypt_with_passphrase(List args) { - String msg = args.remove(0); - String passphrase = args.remove(0); + public boolean encrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { + ArrayList errors = new ArrayList(); + ArrayList warnings = new ArrayList(); + + pReturn.putStringArrayList("ERRORS", errors); + pReturn.putStringArrayList("WARNINGS", warnings); + + String msg = pArgs.getString("MSG"); + pArgs.remove("MSG"); + + String passphrase = pArgs.getString("SYM_KEY"); + pArgs.remove("SYM_KEY"); + + if (msg == null) { + errors.add("Message to encrypt (MSG) missing"); + } + + if (passphrase == null) { + errors.add("Symmetric key (SYM_KEY) missing"); + } + + if (!pArgs.isEmpty()) { + Iterator iter = pArgs.keySet().iterator(); + while (iter.hasNext()) { + warnings.add("Unknown key: " + iter.next()); + } + } + + if (errors.size() != 0) { + pReturn.putInt("ERROR", error.ARGUMENTS_MISSING.ordinal()); + return false; + } Preferences mPreferences = Preferences.getPreferences(getBaseContext(), true); InputStream inStream = new ByteArrayInputStream(msg.getBytes()); @@ -52,16 +85,50 @@ public class ApgService extends Service { ); } catch (Exception e) { Log.d(TAG, "Exception in encrypt"); - e.printStackTrace(); - return null; + errors.add("Internal failure in APG when encrypting: " + e.getMessage()); + + pReturn.putInt("ERROR", error.APG_FAILURE.ordinal()); + return false; } + Log.d(TAG, "Encrypted"); - return out.toString(); + pReturn.putString("RESULT", out.toString()); + return true; } - public String decrypt_with_passphrase(List args) { - String encrypted_msg = args.remove(0); - String passphrase = args.remove(0); + public boolean decrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { + ArrayList errors = new ArrayList(); + ArrayList warnings = new ArrayList(); + + pReturn.putStringArrayList("ERRORS", errors); + pReturn.putStringArrayList("WARNINGS", warnings); + + String encrypted_msg = pArgs.getString("MSG"); + pArgs.remove("MSG"); + + String passphrase = pArgs.getString("SYM_KEY"); + pArgs.remove("SYM_KEY"); + + if (encrypted_msg == null) { + errors.add("Message to decrypt (MSG) missing"); + } + + if (passphrase == null) { + errors.add("Symmetric key (SYM_KEY) missing"); + } + + if (!pArgs.isEmpty()) { + Iterator iter = pArgs.keySet().iterator(); + while (iter.hasNext()) { + warnings.add("Unknown key: " + iter.next()); + } + } + + if (errors.size() != 0) { + pReturn.putStringArrayList("ERROR", errors); + pReturn.putInt("ERROR", error.ARGUMENTS_MISSING.ordinal()); + return false; + } InputStream inStream = new ByteArrayInputStream(encrypted_msg.getBytes()); InputData in = new InputData(inStream, 9999); // XXX what size in @@ -73,11 +140,15 @@ public class ApgService extends Service { ); } catch (Exception e) { Log.d(TAG, "Exception in decrypt"); - e.printStackTrace(); - return null; + errors.add("Internal failure in APG when decrypting: " + e.getMessage()); + + pReturn.putInt("ERROR", error.APG_FAILURE.ordinal()); + pReturn.putStringArrayList("ERROR", errors); + return false; } - return out.toString(); + pReturn.putString("RESULT", out.toString()); + return true; } }; } -- cgit v1.2.3 From 9e089f03b6efb656650be7fa465833f189398af5 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Sun, 9 Jan 2011 19:16:22 +0000 Subject: Prefix local vars with "_" --- src/org/thialfihar/android/apg/ApgService.java | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 316e9a22c..ec744448b 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -50,9 +50,9 @@ public class ApgService extends Service { } if (!pArgs.isEmpty()) { - Iterator iter = pArgs.keySet().iterator(); - while (iter.hasNext()) { - warnings.add("Unknown key: " + iter.next()); + Iterator _iter = pArgs.keySet().iterator(); + while (_iter.hasNext()) { + warnings.add("Unknown key: " + _iter.next()); } } @@ -61,24 +61,24 @@ public class ApgService extends Service { return false; } - Preferences mPreferences = Preferences.getPreferences(getBaseContext(), true); - InputStream inStream = new ByteArrayInputStream(msg.getBytes()); - InputData in = new InputData(inStream, 9999); - OutputStream out = new ByteArrayOutputStream(); - long enc_keys[] = {}; + Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); + InputStream _inStream = new ByteArrayInputStream(msg.getBytes()); + InputData _in = new InputData(_inStream, 9999); + OutputStream _out = new ByteArrayOutputStream(); + long _enc_keys[] = {}; Apg.initialize(getApplicationContext()); try { Apg.encrypt(getApplicationContext(), // context - in, // input stream - out, // output stream + _in, // input stream + _out, // output stream true, // armored - enc_keys, // encryption keys + _enc_keys, // encryption keys 0, // signature key null, // signature passphrase null, // progress - mPreferences.getDefaultEncryptionAlgorithm(), // encryption - mPreferences.getDefaultHashAlgorithm(), // hash + _mPreferences.getDefaultEncryptionAlgorithm(), // encryption + _mPreferences.getDefaultHashAlgorithm(), // hash Id.choice.compression.none, // compression false, // mPreferences.getForceV3Signatures(), passphrase // passPhrase @@ -92,7 +92,7 @@ public class ApgService extends Service { } Log.d(TAG, "Encrypted"); - pReturn.putString("RESULT", out.toString()); + pReturn.putString("RESULT", _out.toString()); return true; } @@ -105,7 +105,7 @@ public class ApgService extends Service { String encrypted_msg = pArgs.getString("MSG"); pArgs.remove("MSG"); - + String passphrase = pArgs.getString("SYM_KEY"); pArgs.remove("SYM_KEY"); -- cgit v1.2.3 From c84c449035db1498414486b13e63e590ddf49a58 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Sun, 9 Jan 2011 19:16:45 +0000 Subject: Respect options but allow to overwrite them for each call By default the values set in APG's options are respected now. But they can be overwritten by special parameters passed through. --- src/org/thialfihar/android/apg/ApgService.java | 99 ++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 15 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index ec744448b..4d38f9693 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import android.content.Intent; @@ -13,7 +14,7 @@ import android.os.IBinder; import android.util.Log; public class ApgService extends Service { - static String TAG = "ApgService"; + final static String TAG = "ApgService"; @Override public IBinder onBind(Intent intent) { @@ -26,21 +27,89 @@ public class ApgService extends Service { APG_FAILURE } + /** a map from ApgService parameters to function calls to get the default */ + static final HashMap FUNCTIONS_DEFAULTS = new HashMap(); + static { + FUNCTIONS_DEFAULTS.put("ENCRYPTION_ALGO", "getDefaultEncryptionAlgorithm"); + FUNCTIONS_DEFAULTS.put("HASH_ALGO", "getDefaultHashAlgorithm"); + FUNCTIONS_DEFAULTS.put("ARMORED", "getDefaultAsciiArmour"); + FUNCTIONS_DEFAULTS.put("FORCE_V3_SIG", "getForceV3Signatures"); + FUNCTIONS_DEFAULTS.put("COMPRESSION", "getDefaultMessageCompression"); + } + + /** + * Add default arguments if missing + * + * @param args + * the bundle to add default parameters to if missing + * + */ + private void add_defaults(Bundle args) { + Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); + + Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator(); + while (_iter.hasNext()) { + String _current_key = _iter.next(); + if (!args.containsKey(_current_key)) { + String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_key); + try { + @SuppressWarnings("unchecked") + Class _ret_type = Preferences.class.getMethod(_current_function_name).getReturnType(); + if (_ret_type == String.class) { + args.putString(_current_key, (String) Preferences.class.getMethod(_current_function_name).invoke(_mPreferences)); + } else if (_ret_type == boolean.class) { + args.putBoolean(_current_key, (Boolean) Preferences.class.getMethod(_current_function_name).invoke(_mPreferences)); + } else if (_ret_type == int.class) { + args.putInt(_current_key, (Integer) Preferences.class.getMethod(_current_function_name).invoke(_mPreferences)); + } else { + Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option"); + } + } catch (Exception e) { + Log.e(TAG, "Exception in add_defaults " + e.getMessage()); + } + } + } + } + private final IApgService.Stub mBinder = new IApgService.Stub() { public boolean encrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { + ArrayList errors = new ArrayList(); ArrayList warnings = new ArrayList(); pReturn.putStringArrayList("ERRORS", errors); pReturn.putStringArrayList("WARNINGS", warnings); - String msg = pArgs.getString("MSG"); - pArgs.remove("MSG"); + Bundle _my_args = new Bundle(pArgs); - String passphrase = pArgs.getString("SYM_KEY"); - pArgs.remove("SYM_KEY"); + /* add default values if missing */ + add_defaults(_my_args); + + /* required args */ + String msg = _my_args.getString("MSG"); + _my_args.remove("MSG"); + + String passphrase = _my_args.getString("SYM_KEY"); + _my_args.remove("SYM_KEY"); + + /* optional args */ + Boolean armored = _my_args.getBoolean("ARMORED"); + _my_args.remove("ARMORED"); + + int encryption_algorithm = _my_args.getInt("ENCRYPTION_ALGO"); + _my_args.remove("ENCRYPTION_ALGO"); + int hash_algorithm = _my_args.getInt("HASH_ALGO"); + _my_args.remove("HASH_ALGO"); + + int compression = _my_args.getInt("COMPRESSION"); + _my_args.remove("COMPRESSION"); + + Boolean force_v3_signatures = _my_args.getBoolean("FORCE_V3_SIG"); + _my_args.remove("FORCE_V3_SIG"); + + /* check required args */ if (msg == null) { errors.add("Message to encrypt (MSG) missing"); } @@ -49,38 +118,38 @@ public class ApgService extends Service { errors.add("Symmetric key (SYM_KEY) missing"); } - if (!pArgs.isEmpty()) { - Iterator _iter = pArgs.keySet().iterator(); + /* check for unknown args and add to warning */ + if (!_my_args.isEmpty()) { + Iterator _iter = _my_args.keySet().iterator(); while (_iter.hasNext()) { warnings.add("Unknown key: " + _iter.next()); } } + /* return if errors happened */ if (errors.size() != 0) { pReturn.putInt("ERROR", error.ARGUMENTS_MISSING.ordinal()); return false; } - Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); InputStream _inStream = new ByteArrayInputStream(msg.getBytes()); InputData _in = new InputData(_inStream, 9999); OutputStream _out = new ByteArrayOutputStream(); - long _enc_keys[] = {}; Apg.initialize(getApplicationContext()); try { Apg.encrypt(getApplicationContext(), // context _in, // input stream _out, // output stream - true, // armored - _enc_keys, // encryption keys + armored, // armored + new long[0], // encryption keys 0, // signature key null, // signature passphrase null, // progress - _mPreferences.getDefaultEncryptionAlgorithm(), // encryption - _mPreferences.getDefaultHashAlgorithm(), // hash - Id.choice.compression.none, // compression - false, // mPreferences.getForceV3Signatures(), + encryption_algorithm, // encryption + hash_algorithm, // hash + compression, // compression + force_v3_signatures, // mPreferences.getForceV3Signatures(), passphrase // passPhrase ); } catch (Exception e) { -- cgit v1.2.3 From d367bc12f833bed8082c99936e0ac5b86a95faf7 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 11 Jan 2011 17:58:13 +0000 Subject: Make some things static *Should* speed up encryption, or better: does not make encryption using AIDL slower than using APG directly. --- src/org/thialfihar/android/apg/ApgService.java | 42 ++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 4d38f9693..717383b98 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -37,6 +38,34 @@ public class ApgService extends Service { FUNCTIONS_DEFAULTS.put("COMPRESSION", "getDefaultMessageCompression"); } + /** a map the default functions to their return types */ + static final HashMap FUNCTIONS_DEFAULTS_TYPES = new HashMap(); + static { + try { + FUNCTIONS_DEFAULTS_TYPES.put("getDefaultEncryptionAlgorithm", Preferences.class.getMethod("getDefaultEncryptionAlgorithm").getReturnType()); + FUNCTIONS_DEFAULTS_TYPES.put("getDefaultHashAlgorithm", Preferences.class.getMethod("getDefaultHashAlgorithm").getReturnType()); + FUNCTIONS_DEFAULTS_TYPES.put("getDefaultAsciiArmour", Preferences.class.getMethod("getDefaultAsciiArmour").getReturnType()); + FUNCTIONS_DEFAULTS_TYPES.put("getForceV3Signatures", Preferences.class.getMethod("getForceV3Signatures").getReturnType()); + FUNCTIONS_DEFAULTS_TYPES.put("getDefaultMessageCompression", Preferences.class.getMethod("getDefaultMessageCompression").getReturnType()); + } catch (Exception e) { + Log.e(TAG, "Function default exception: " + e.getMessage()); + } + } + + /** a map the default function names to their method */ + static final HashMap FUNCTIONS_DEFAULTS_METHODS = new HashMap(); + static { + try { + FUNCTIONS_DEFAULTS_METHODS.put("getDefaultEncryptionAlgorithm", Preferences.class.getMethod("getDefaultEncryptionAlgorithm")); + FUNCTIONS_DEFAULTS_METHODS.put("getDefaultHashAlgorithm", Preferences.class.getMethod("getDefaultHashAlgorithm")); + FUNCTIONS_DEFAULTS_METHODS.put("getDefaultAsciiArmour", Preferences.class.getMethod("getDefaultAsciiArmour")); + FUNCTIONS_DEFAULTS_METHODS.put("getForceV3Signatures", Preferences.class.getMethod("getForceV3Signatures")); + FUNCTIONS_DEFAULTS_METHODS.put("getDefaultMessageCompression", Preferences.class.getMethod("getDefaultMessageCompression")); + } catch (Exception e) { + Log.e(TAG, "Function method exception: " + e.getMessage()); + } + } + /** * Add default arguments if missing * @@ -54,13 +83,13 @@ public class ApgService extends Service { String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_key); try { @SuppressWarnings("unchecked") - Class _ret_type = Preferences.class.getMethod(_current_function_name).getReturnType(); + Class _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name); if (_ret_type == String.class) { - args.putString(_current_key, (String) Preferences.class.getMethod(_current_function_name).invoke(_mPreferences)); + args.putString(_current_key, (String) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); } else if (_ret_type == boolean.class) { - args.putBoolean(_current_key, (Boolean) Preferences.class.getMethod(_current_function_name).invoke(_mPreferences)); + args.putBoolean(_current_key, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); } else if (_ret_type == int.class) { - args.putInt(_current_key, (Integer) Preferences.class.getMethod(_current_function_name).invoke(_mPreferences)); + args.putInt(_current_key, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); } else { Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option"); } @@ -133,7 +162,8 @@ public class ApgService extends Service { } InputStream _inStream = new ByteArrayInputStream(msg.getBytes()); - InputData _in = new InputData(_inStream, 9999); + InputData _in = new InputData(_inStream, 0); // XXX Size second + // param? OutputStream _out = new ByteArrayOutputStream(); Apg.initialize(getApplicationContext()); @@ -200,7 +230,7 @@ public class ApgService extends Service { } InputStream inStream = new ByteArrayInputStream(encrypted_msg.getBytes()); - InputData in = new InputData(inStream, 9999); // XXX what size in + InputData in = new InputData(inStream, 0); // XXX what size in // second parameter? OutputStream out = new ByteArrayOutputStream(); try { -- cgit v1.2.3 From 45e4897dc7f05f1f270f4993cc3060f654e2f3a9 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 11 Jan 2011 22:24:20 +0000 Subject: Redefine many internals of ApgService This helps to add new function calls easily. Some of the new enums could be exported to other files to be included by other projects later on. Next step is asymmetric encryption. --- src/org/thialfihar/android/apg/ApgService.java | 270 +++++++++++++++---------- 1 file changed, 168 insertions(+), 102 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 717383b98..ff2fb8ad8 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -7,7 +7,9 @@ import java.io.OutputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; +import java.util.Set; import android.content.Intent; import android.os.Bundle; @@ -23,23 +25,74 @@ public class ApgService extends Service { return mBinder; } + /** error status */ private enum error { ARGUMENTS_MISSING, APG_FAILURE } + /** all arguments that can be passed by calling application */ + private enum arg { + MSG, // message to encrypt or to decrypt + SYM_KEY, // key for symmetric en/decryption + PUBLIC_KEYS, // public keys for encryption + ENCRYPTION_ALGO, // encryption algorithm + HASH_ALGO, // hash algorithm + ARMORED, // whether to armor output + FORCE_V3_SIG, // whether to force v3 signature + COMPRESSION + // what compression to use for encrypted output + } + + /** all things that might be returned */ + private enum ret { + ERRORS, + WARNINGS, + ERROR, + RESULT + } + + /** required arguments for each AIDL function */ + private static final HashMap> FUNCTIONS_REQUIRED_ARGS = new HashMap>(); + static { + HashSet args = new HashSet(); + args.add(arg.SYM_KEY); + args.add(arg.MSG); + FUNCTIONS_REQUIRED_ARGS.put("encrypt_with_passphrase", args); + FUNCTIONS_REQUIRED_ARGS.put("decrypt_with_passphrase", args); + + args = new HashSet(); + args.add(arg.PUBLIC_KEYS); + args.add(arg.MSG); + FUNCTIONS_REQUIRED_ARGS.put("encrypt_with_public_key", args); + } + + /** optional arguments for each AIDL function */ + private static final HashMap> FUNCTIONS_OPTIONAL_ARGS = new HashMap>(); + static { + HashSet args = new HashSet(); + args.add(arg.ENCRYPTION_ALGO); + args.add(arg.HASH_ALGO); + args.add(arg.ARMORED); + args.add(arg.FORCE_V3_SIG); + args.add(arg.COMPRESSION); + FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_passphrase", args); + FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_public_key", args); + FUNCTIONS_OPTIONAL_ARGS.put("decrypt_with_passphrase", args); + } + /** a map from ApgService parameters to function calls to get the default */ - static final HashMap FUNCTIONS_DEFAULTS = new HashMap(); + private static final HashMap FUNCTIONS_DEFAULTS = new HashMap(); static { - FUNCTIONS_DEFAULTS.put("ENCRYPTION_ALGO", "getDefaultEncryptionAlgorithm"); - FUNCTIONS_DEFAULTS.put("HASH_ALGO", "getDefaultHashAlgorithm"); - FUNCTIONS_DEFAULTS.put("ARMORED", "getDefaultAsciiArmour"); - FUNCTIONS_DEFAULTS.put("FORCE_V3_SIG", "getForceV3Signatures"); - FUNCTIONS_DEFAULTS.put("COMPRESSION", "getDefaultMessageCompression"); + FUNCTIONS_DEFAULTS.put(arg.ENCRYPTION_ALGO, "getDefaultEncryptionAlgorithm"); + FUNCTIONS_DEFAULTS.put(arg.HASH_ALGO, "getDefaultHashAlgorithm"); + FUNCTIONS_DEFAULTS.put(arg.ARMORED, "getDefaultAsciiArmour"); + FUNCTIONS_DEFAULTS.put(arg.FORCE_V3_SIG, "getForceV3Signatures"); + FUNCTIONS_DEFAULTS.put(arg.COMPRESSION, "getDefaultMessageCompression"); } /** a map the default functions to their return types */ - static final HashMap FUNCTIONS_DEFAULTS_TYPES = new HashMap(); + private static final HashMap> FUNCTIONS_DEFAULTS_TYPES = new HashMap>(); static { try { FUNCTIONS_DEFAULTS_TYPES.put("getDefaultEncryptionAlgorithm", Preferences.class.getMethod("getDefaultEncryptionAlgorithm").getReturnType()); @@ -53,7 +106,7 @@ public class ApgService extends Service { } /** a map the default function names to their method */ - static final HashMap FUNCTIONS_DEFAULTS_METHODS = new HashMap(); + private static final HashMap FUNCTIONS_DEFAULTS_METHODS = new HashMap(); static { try { FUNCTIONS_DEFAULTS_METHODS.put("getDefaultEncryptionAlgorithm", Preferences.class.getMethod("getDefaultEncryptionAlgorithm")); @@ -73,17 +126,17 @@ public class ApgService extends Service { * the bundle to add default parameters to if missing * */ - private void add_defaults(Bundle args) { + private void add_default_arguments(Bundle args) { Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); - Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator(); + Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator(); while (_iter.hasNext()) { - String _current_key = _iter.next(); + arg _current_arg = _iter.next(); + String _current_key = _current_arg.name(); if (!args.containsKey(_current_key)) { - String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_key); + String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_arg); try { - @SuppressWarnings("unchecked") - Class _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name); + Class _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name); if (_ret_type == String.class) { args.putString(_current_key, (String) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); } else if (_ret_type == boolean.class) { @@ -94,74 +147,98 @@ public class ApgService extends Service { Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option"); } } catch (Exception e) { - Log.e(TAG, "Exception in add_defaults " + e.getMessage()); + Log.e(TAG, "Exception in add_default_arguments " + e.getMessage()); } } } } - private final IApgService.Stub mBinder = new IApgService.Stub() { - - public boolean encrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { - - ArrayList errors = new ArrayList(); - ArrayList warnings = new ArrayList(); - - pReturn.putStringArrayList("ERRORS", errors); - pReturn.putStringArrayList("WARNINGS", warnings); - - Bundle _my_args = new Bundle(pArgs); - - /* add default values if missing */ - add_defaults(_my_args); + /** + * updates a Bundle with default return values + * + * @param pReturn + * the Bundle to update + */ + private void add_default_returns(Bundle pReturn) { + ArrayList errors = new ArrayList(); + ArrayList warnings = new ArrayList(); - /* required args */ - String msg = _my_args.getString("MSG"); - _my_args.remove("MSG"); + pReturn.putStringArrayList(ret.ERRORS.name(), errors); + pReturn.putStringArrayList(ret.WARNINGS.name(), warnings); + } - String passphrase = _my_args.getString("SYM_KEY"); - _my_args.remove("SYM_KEY"); + /** + * checks for required arguments and adds them to the error if missing + * + * @param function + * the functions required arguments to check for + * @param pArgs + * the Bundle of arguments to check + * @param pReturn + * the bundle to write errors to + */ + private void check_required_args(String function, Bundle pArgs, Bundle pReturn) { + Iterator _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator(); + while (_iter.hasNext()) { + String _cur_arg = _iter.next().name(); + if (!pArgs.containsKey(_cur_arg)) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + _cur_arg); + } + } + } - /* optional args */ - Boolean armored = _my_args.getBoolean("ARMORED"); - _my_args.remove("ARMORED"); + /** + * checks for unknown arguments and add them to warning if found + * + * @param function + * the functions name to check against + * @param pArgs + * the Bundle of arguments to check + * @param pReturn + * the bundle to write warnings to + */ + private void check_unknown_args(String function, Bundle pArgs, Bundle pReturn) { + HashSet all_args = new HashSet(FUNCTIONS_REQUIRED_ARGS.get(function)); + all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function)); - int encryption_algorithm = _my_args.getInt("ENCRYPTION_ALGO"); - _my_args.remove("ENCRYPTION_ALGO"); + Iterator _iter = pArgs.keySet().iterator(); + while (_iter.hasNext()) { + String _cur_key = _iter.next(); + try { + arg.valueOf(_cur_key); + } catch (Exception e) { + pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key); + } - int hash_algorithm = _my_args.getInt("HASH_ALGO"); - _my_args.remove("HASH_ALGO"); + } + } - int compression = _my_args.getInt("COMPRESSION"); - _my_args.remove("COMPRESSION"); + private final IApgService.Stub mBinder = new IApgService.Stub() { - Boolean force_v3_signatures = _my_args.getBoolean("FORCE_V3_SIG"); - _my_args.remove("FORCE_V3_SIG"); + public boolean encrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { + /* add default return values for all functions */ + add_default_returns(pReturn); - /* check required args */ - if (msg == null) { - errors.add("Message to encrypt (MSG) missing"); - } + /* add default arguments if missing */ + add_default_arguments(pArgs); + Log.d(TAG, "add_default_arguments"); - if (passphrase == null) { - errors.add("Symmetric key (SYM_KEY) missing"); - } + /* check for required arguments */ + check_required_args("encrypt_with_passphrase", pArgs, pReturn); + Log.d(TAG, "check_required_args"); - /* check for unknown args and add to warning */ - if (!_my_args.isEmpty()) { - Iterator _iter = _my_args.keySet().iterator(); - while (_iter.hasNext()) { - warnings.add("Unknown key: " + _iter.next()); - } - } + /* check for unknown arguments and add to warning if found */ + check_unknown_args("encrypt_with_passphrase", pArgs, pReturn); + Log.d(TAG, "check_unknown_args"); /* return if errors happened */ - if (errors.size() != 0) { - pReturn.putInt("ERROR", error.ARGUMENTS_MISSING.ordinal()); + if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { + pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.ordinal()); return false; } + Log.d(TAG, "error return"); - InputStream _inStream = new ByteArrayInputStream(msg.getBytes()); + InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MSG.name()).getBytes()); InputData _in = new InputData(_inStream, 0); // XXX Size second // param? OutputStream _out = new ByteArrayOutputStream(); @@ -171,82 +248,71 @@ public class ApgService extends Service { Apg.encrypt(getApplicationContext(), // context _in, // input stream _out, // output stream - armored, // armored + pArgs.getBoolean(arg.ARMORED.name()), // armored new long[0], // encryption keys 0, // signature key null, // signature passphrase null, // progress - encryption_algorithm, // encryption - hash_algorithm, // hash - compression, // compression - force_v3_signatures, // mPreferences.getForceV3Signatures(), - passphrase // passPhrase + pArgs.getInt(arg.ENCRYPTION_ALGO.name()), // encryption + pArgs.getInt(arg.HASH_ALGO.name()), // hash + pArgs.getInt(arg.COMPRESSION.name()), // compression + pArgs.getBoolean(arg.FORCE_V3_SIG.name()), // mPreferences.getForceV3Signatures(), + pArgs.getString(arg.SYM_KEY.name()) // passPhrase ); } catch (Exception e) { Log.d(TAG, "Exception in encrypt"); - errors.add("Internal failure in APG when encrypting: " + e.getMessage()); + pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure in APG when encrypting: " + e.getMessage()); - pReturn.putInt("ERROR", error.APG_FAILURE.ordinal()); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); return false; } - Log.d(TAG, "Encrypted"); - pReturn.putString("RESULT", _out.toString()); + pReturn.putString(ret.RESULT.name(), _out.toString()); return true; } public boolean decrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { - ArrayList errors = new ArrayList(); - ArrayList warnings = new ArrayList(); - - pReturn.putStringArrayList("ERRORS", errors); - pReturn.putStringArrayList("WARNINGS", warnings); + /* add default return values for all functions */ + add_default_returns(pReturn); - String encrypted_msg = pArgs.getString("MSG"); - pArgs.remove("MSG"); + /* add default arguments if missing */ + add_default_arguments(pArgs); + Log.d(TAG, "add_default_arguments"); - String passphrase = pArgs.getString("SYM_KEY"); - pArgs.remove("SYM_KEY"); - if (encrypted_msg == null) { - errors.add("Message to decrypt (MSG) missing"); - } + /* check required args */ + check_required_args("decrypt_with_passphrase", pArgs, pReturn); + Log.d(TAG, "check_required_args"); - if (passphrase == null) { - errors.add("Symmetric key (SYM_KEY) missing"); - } - if (!pArgs.isEmpty()) { - Iterator iter = pArgs.keySet().iterator(); - while (iter.hasNext()) { - warnings.add("Unknown key: " + iter.next()); - } - } + /* check for unknown args and add to warning */ + check_unknown_args("decrypt_with_passphrase", pArgs, pReturn); + Log.d(TAG, "check_unknown_args"); - if (errors.size() != 0) { - pReturn.putStringArrayList("ERROR", errors); - pReturn.putInt("ERROR", error.ARGUMENTS_MISSING.ordinal()); + + /* return if errors happened */ + if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { + pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.ordinal()); return false; } - InputStream inStream = new ByteArrayInputStream(encrypted_msg.getBytes()); + InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MSG.name()).getBytes()); InputData in = new InputData(inStream, 0); // XXX what size in // second parameter? OutputStream out = new ByteArrayOutputStream(); try { - Apg.decrypt(getApplicationContext(), in, out, passphrase, null, // progress + Apg.decrypt(getApplicationContext(), in, out, pArgs.getString(arg.SYM_KEY.name()), null, // progress true // symmetric ); } catch (Exception e) { Log.d(TAG, "Exception in decrypt"); - errors.add("Internal failure in APG when decrypting: " + e.getMessage()); + pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure in APG when decrypting: " + e.getMessage()); - pReturn.putInt("ERROR", error.APG_FAILURE.ordinal()); - pReturn.putStringArrayList("ERROR", errors); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); return false; } - pReturn.putString("RESULT", out.toString()); + pReturn.putString(ret.RESULT.name(), out.toString()); return true; } }; -- cgit v1.2.3 From 8b352296503b555bc8d7e0fa7fff2f66ad5a8701 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 11 Jan 2011 22:31:35 +0000 Subject: Actually check for unknown args for function --- src/org/thialfihar/android/apg/ApgService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index ff2fb8ad8..a298cca8e 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -205,7 +205,10 @@ public class ApgService extends Service { while (_iter.hasNext()) { String _cur_key = _iter.next(); try { - arg.valueOf(_cur_key); + arg _cur_arg = arg.valueOf(_cur_key); + if( !all_args.contains(_cur_arg)) { + pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key); + } } catch (Exception e) { pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key); } -- cgit v1.2.3 From a1c75dd47ce4a72f516366b24c9e00d270a187b6 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Thu, 13 Jan 2011 20:12:10 +0000 Subject: Add asymmetric encryption --- src/org/thialfihar/android/apg/ApgService.java | 248 +++++++++++++++++-------- 1 file changed, 171 insertions(+), 77 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index a298cca8e..796a42913 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -6,12 +6,19 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import org.thialfihar.android.apg.provider.KeyRings; +import org.thialfihar.android.apg.provider.Keys; +import org.thialfihar.android.apg.provider.UserIds; + import android.content.Intent; +import android.database.Cursor; +import android.database.sqlite.SQLiteQueryBuilder; import android.os.Bundle; import android.os.IBinder; import android.util.Log; @@ -28,7 +35,8 @@ public class ApgService extends Service { /** error status */ private enum error { ARGUMENTS_MISSING, - APG_FAILURE + APG_FAILURE, + NO_MATCHING_SECRET_KEY } /** all arguments that can be passed by calling application */ @@ -46,10 +54,11 @@ public class ApgService extends Service { /** all things that might be returned */ private enum ret { - ERRORS, - WARNINGS, - ERROR, + ERRORS, // string array list with errors + WARNINGS, // string array list with warnings + ERROR, // numeric error RESULT + // en-/decrypted test } /** required arguments for each AIDL function */ @@ -59,12 +68,16 @@ public class ApgService extends Service { args.add(arg.SYM_KEY); args.add(arg.MSG); FUNCTIONS_REQUIRED_ARGS.put("encrypt_with_passphrase", args); - FUNCTIONS_REQUIRED_ARGS.put("decrypt_with_passphrase", args); args = new HashSet(); args.add(arg.PUBLIC_KEYS); args.add(arg.MSG); FUNCTIONS_REQUIRED_ARGS.put("encrypt_with_public_key", args); + + args = new HashSet(); + args.add(arg.MSG); + FUNCTIONS_REQUIRED_ARGS.put("decrypt", args); + } /** optional arguments for each AIDL function */ @@ -78,7 +91,11 @@ public class ApgService extends Service { args.add(arg.COMPRESSION); FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_passphrase", args); FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_public_key", args); - FUNCTIONS_OPTIONAL_ARGS.put("decrypt_with_passphrase", args); + + args = new HashSet(); + args.add(arg.SYM_KEY); + args.add(arg.PUBLIC_KEYS); + FUNCTIONS_OPTIONAL_ARGS.put("decrypt", args); } /** a map from ApgService parameters to function calls to get the default */ @@ -119,6 +136,56 @@ public class ApgService extends Service { } } + /** + * maps fingerprints or user ids of keys to master keys in database + * + * @param search_keys + * a list of keys (fingerprints or user ids) to look for in + * database + * @return an array of master keys + */ + private static long[] get_master_key(ArrayList search_keys) { + + SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." + + UserIds.RANK + " = '0') "); + + String orderBy = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; + + long now = new Date().getTime() / 1000; + Cursor mCursor = qb.query(Apg.getDatabase().db(), new String[] { + KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 + KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1 + UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2 + "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + + "." + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " + "tmp." + Keys.CAN_ENCRYPT + " = '1')", // 3 + "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + + "." + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " + "tmp." + Keys.CAN_ENCRYPT + " = '1' AND " + "tmp." + + Keys.CREATION + " <= '" + now + "' AND " + "(tmp." + Keys.EXPIRY + " IS NULL OR " + "tmp." + Keys.EXPIRY + " >= '" + now + "'))", // 4 + }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { "" + Id.database.type_public }, null, null, orderBy); + + ArrayList _master_keys = new ArrayList(); + while (mCursor.moveToNext()) { + long _cur_mkey = mCursor.getLong(1); + String _cur_user = mCursor.getString(2); + Log.d(TAG, "current master key: " + _cur_mkey + " from " + _cur_user); + if (search_keys.contains(Apg.getSmallFingerPrint(_cur_mkey)) || search_keys.contains(_cur_user)) { + Log.d(TAG, "master key found for: " + Apg.getSmallFingerPrint(_cur_mkey)); + _master_keys.add(_cur_mkey); + } + } + mCursor.close(); + + long[] _master_longs = new long[_master_keys.size()]; + int i = 0; + for (Long _key : _master_keys) { + _master_longs[i++] = _key; + } + return _master_longs; + } + /** * Add default arguments if missing * @@ -126,14 +193,14 @@ public class ApgService extends Service { * the bundle to add default parameters to if missing * */ - private void add_default_arguments(Bundle args) { + private void add_default_arguments(String call, Bundle args) { Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator(); while (_iter.hasNext()) { arg _current_arg = _iter.next(); String _current_key = _current_arg.name(); - if (!args.containsKey(_current_key)) { + if (!args.containsKey(_current_key) && FUNCTIONS_OPTIONAL_ARGS.get(call).contains(_current_arg)) { String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_arg); try { Class _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name); @@ -201,101 +268,123 @@ public class ApgService extends Service { HashSet all_args = new HashSet(FUNCTIONS_REQUIRED_ARGS.get(function)); all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function)); + ArrayList _unknown_args = new ArrayList(); Iterator _iter = pArgs.keySet().iterator(); while (_iter.hasNext()) { String _cur_key = _iter.next(); try { arg _cur_arg = arg.valueOf(_cur_key); - if( !all_args.contains(_cur_arg)) { + if (!all_args.contains(_cur_arg)) { pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key); + _unknown_args.add(_cur_key); } } catch (Exception e) { pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key); + _unknown_args.add(_cur_key); } + } + // remove unknown arguments so our bundle has just what we need + for (String _arg : _unknown_args) { + pArgs.remove(_arg); } } - private final IApgService.Stub mBinder = new IApgService.Stub() { + private boolean prepare_args(String call, Bundle pArgs, Bundle pReturn) { + Apg.initialize(getBaseContext()); - public boolean encrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { - /* add default return values for all functions */ - add_default_returns(pReturn); + /* add default return values for all functions */ + add_default_returns(pReturn); - /* add default arguments if missing */ - add_default_arguments(pArgs); - Log.d(TAG, "add_default_arguments"); + /* add default arguments if missing */ + add_default_arguments(call, pArgs); + Log.d(TAG, "add_default_arguments"); - /* check for required arguments */ - check_required_args("encrypt_with_passphrase", pArgs, pReturn); - Log.d(TAG, "check_required_args"); + /* check for required arguments */ + check_required_args(call, pArgs, pReturn); + Log.d(TAG, "check_required_args"); - /* check for unknown arguments and add to warning if found */ - check_unknown_args("encrypt_with_passphrase", pArgs, pReturn); - Log.d(TAG, "check_unknown_args"); + /* check for unknown arguments and add to warning if found */ + check_unknown_args(call, pArgs, pReturn); + Log.d(TAG, "check_unknown_args"); - /* return if errors happened */ - if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { - pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.ordinal()); - return false; - } - Log.d(TAG, "error return"); + /* return if errors happened */ + if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { + pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.ordinal()); + return false; + } + Log.d(TAG, "error return"); - InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MSG.name()).getBytes()); - InputData _in = new InputData(_inStream, 0); // XXX Size second - // param? - OutputStream _out = new ByteArrayOutputStream(); + return true; + } - Apg.initialize(getApplicationContext()); - try { - Apg.encrypt(getApplicationContext(), // context - _in, // input stream - _out, // output stream - pArgs.getBoolean(arg.ARMORED.name()), // armored - new long[0], // encryption keys - 0, // signature key - null, // signature passphrase - null, // progress - pArgs.getInt(arg.ENCRYPTION_ALGO.name()), // encryption - pArgs.getInt(arg.HASH_ALGO.name()), // hash - pArgs.getInt(arg.COMPRESSION.name()), // compression - pArgs.getBoolean(arg.FORCE_V3_SIG.name()), // mPreferences.getForceV3Signatures(), - pArgs.getString(arg.SYM_KEY.name()) // passPhrase - ); - } catch (Exception e) { - Log.d(TAG, "Exception in encrypt"); - pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure in APG when encrypting: " + e.getMessage()); + private boolean encrypt(Bundle pArgs, Bundle pReturn) { - pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); - return false; + long _pub_master_keys[] = {}; + if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) { + ArrayList _list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name()); + ArrayList _pub_keys = new ArrayList(); + Log.d(TAG, "Long size: " + _list.size()); + Iterator _iter = _list.iterator(); + while (_iter.hasNext()) { + _pub_keys.add(_iter.next()); } - Log.d(TAG, "Encrypted"); - pReturn.putString(ret.RESULT.name(), _out.toString()); - return true; + _pub_master_keys = get_master_key(_pub_keys); } - public boolean decrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { - /* add default return values for all functions */ - add_default_returns(pReturn); + InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MSG.name()).getBytes()); + InputData _in = new InputData(_inStream, 0); // XXX Size second + // param? - /* add default arguments if missing */ - add_default_arguments(pArgs); - Log.d(TAG, "add_default_arguments"); + OutputStream _out = new ByteArrayOutputStream(); + try { + Apg.encrypt(getBaseContext(), // context + _in, // input stream + _out, // output stream + pArgs.getBoolean(arg.ARMORED.name()), // armored + _pub_master_keys, // encryption keys + 0, // signature key + null, // signature passphrase + null, // progress + pArgs.getInt(arg.ENCRYPTION_ALGO.name()), // encryption + pArgs.getInt(arg.HASH_ALGO.name()), // hash + pArgs.getInt(arg.COMPRESSION.name()), // compression + pArgs.getBoolean(arg.FORCE_V3_SIG.name()), // mPreferences.getForceV3Signatures(), + pArgs.getString(arg.SYM_KEY.name()) // passPhrase + ); + } catch (Exception e) { + Log.d(TAG, "Exception in encrypt"); + pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage()); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); + return false; + } + Log.d(TAG, "Encrypted"); + pReturn.putString(ret.RESULT.name(), _out.toString()); + return true; + } - /* check required args */ - check_required_args("decrypt_with_passphrase", pArgs, pReturn); - Log.d(TAG, "check_required_args"); + private final IApgService.Stub mBinder = new IApgService.Stub() { + public boolean encrypt_with_public_key(Bundle pArgs, Bundle pReturn) { + if (!prepare_args("encrypt_with_public_key", pArgs, pReturn)) { + return false; + } - /* check for unknown args and add to warning */ - check_unknown_args("decrypt_with_passphrase", pArgs, pReturn); - Log.d(TAG, "check_unknown_args"); + return encrypt(pArgs, pReturn); + } - - /* return if errors happened */ - if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { - pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.ordinal()); + public boolean encrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { + if (!prepare_args("encrypt_with_passphrase", pArgs, pReturn)) { + return false; + } + + return encrypt(pArgs, pReturn); + + } + + public boolean decrypt(Bundle pArgs, Bundle pReturn) { + if (!prepare_args("decrypt", pArgs, pReturn)) { return false; } @@ -304,14 +393,19 @@ public class ApgService extends Service { // second parameter? OutputStream out = new ByteArrayOutputStream(); try { - Apg.decrypt(getApplicationContext(), in, out, pArgs.getString(arg.SYM_KEY.name()), null, // progress - true // symmetric + Apg.decrypt(getBaseContext(), in, out, pArgs.getString(arg.SYM_KEY.name()), null, // progress + pArgs.getString(arg.SYM_KEY.name()) != null // symmetric ); } catch (Exception e) { Log.d(TAG, "Exception in decrypt"); - pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure in APG when decrypting: " + e.getMessage()); - - pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); + if (e.getMessage() == getBaseContext().getString(R.string.error_noSecretKeyFound)) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + e.getMessage()); + pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.ordinal()); + } else { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + e.getMessage()); + e.printStackTrace(); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); + } return false; } -- cgit v1.2.3 From f9ee141ce140fa94ec6ab7d0f3b25e0110e377cc Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Mon, 17 Jan 2011 22:16:49 +0000 Subject: Allow to sign and specify passphrase on decrypting --- src/org/thialfihar/android/apg/ApgService.java | 48 +++++++++++++++++++------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 796a42913..0cfb065db 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -48,8 +48,9 @@ public class ApgService extends Service { HASH_ALGO, // hash algorithm ARMORED, // whether to armor output FORCE_V3_SIG, // whether to force v3 signature - COMPRESSION - // what compression to use for encrypted output + COMPRESSION, // what compression to use for encrypted output + SIGNATURE_KEY, // key for signing + PRIVATE_KEY_PASS, // passphrase for encrypted private key } /** all things that might be returned */ @@ -57,8 +58,7 @@ public class ApgService extends Service { ERRORS, // string array list with errors WARNINGS, // string array list with warnings ERROR, // numeric error - RESULT - // en-/decrypted test + RESULT, // en-/decrypted test } /** required arguments for each AIDL function */ @@ -89,12 +89,15 @@ public class ApgService extends Service { args.add(arg.ARMORED); args.add(arg.FORCE_V3_SIG); args.add(arg.COMPRESSION); + args.add(arg.PRIVATE_KEY_PASS); + args.add(arg.SIGNATURE_KEY); FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_passphrase", args); FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_public_key", args); args = new HashSet(); args.add(arg.SYM_KEY); args.add(arg.PUBLIC_KEYS); + args.add(arg.PRIVATE_KEY_PASS); FUNCTIONS_OPTIONAL_ARGS.put("decrypt", args); } @@ -136,6 +139,23 @@ public class ApgService extends Service { } } + /** + * maps a fingerprint or user id of a key to as master key in database + * + * @param search_key + * fingerprint or user id to search for + * @return master key if found, or 0 + */ + private static long get_master_key(String search_key) { + ArrayList tmp = new ArrayList(); + tmp.add(search_key); + long[] _keys = get_master_key(tmp); + if (_keys.length > 0) + return _keys[0]; + else + return 0; + } + /** * maps fingerprints or user ids of keys to master keys in database * @@ -164,7 +184,9 @@ public class ApgService extends Service { "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " + "tmp." + Keys.CAN_ENCRYPT + " = '1' AND " + "tmp." + Keys.CREATION + " <= '" + now + "' AND " + "(tmp." + Keys.EXPIRY + " IS NULL OR " + "tmp." + Keys.EXPIRY + " >= '" + now + "'))", // 4 - }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { "" + Id.database.type_public }, null, null, orderBy); + }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { + "" + Id.database.type_public + }, null, null, orderBy); ArrayList _master_keys = new ArrayList(); while (mCursor.moveToNext()) { @@ -191,7 +213,6 @@ public class ApgService extends Service { * * @param args * the bundle to add default parameters to if missing - * */ private void add_default_arguments(String call, Bundle args) { Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); @@ -333,8 +354,7 @@ public class ApgService extends Service { } InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MSG.name()).getBytes()); - InputData _in = new InputData(_inStream, 0); // XXX Size second - // param? + InputData _in = new InputData(_inStream, 0); // XXX Size second param? OutputStream _out = new ByteArrayOutputStream(); try { @@ -343,8 +363,8 @@ public class ApgService extends Service { _out, // output stream pArgs.getBoolean(arg.ARMORED.name()), // armored _pub_master_keys, // encryption keys - 0, // signature key - null, // signature passphrase + get_master_key(pArgs.getString(arg.SIGNATURE_KEY.name())), // signature key + pArgs.getString(arg.PRIVATE_KEY_PASS.name()), // signature passphrase null, // progress pArgs.getInt(arg.ENCRYPTION_ALGO.name()), // encryption pArgs.getInt(arg.HASH_ALGO.name()), // hash @@ -388,12 +408,14 @@ public class ApgService extends Service { return false; } + String _passphrase = pArgs.getString(arg.SYM_KEY.name()) != null ? pArgs.getString(arg.SYM_KEY.name()) : pArgs.getString(arg.PRIVATE_KEY_PASS + .name()); + InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MSG.name()).getBytes()); - InputData in = new InputData(inStream, 0); // XXX what size in - // second parameter? + InputData in = new InputData(inStream, 0); // XXX what size in second parameter? OutputStream out = new ByteArrayOutputStream(); try { - Apg.decrypt(getBaseContext(), in, out, pArgs.getString(arg.SYM_KEY.name()), null, // progress + Apg.decrypt(getBaseContext(), in, out, _passphrase, null, // progress pArgs.getString(arg.SYM_KEY.name()) != null // symmetric ); } catch (Exception e) { -- cgit v1.2.3 From eb75eea64fbb0c9bfb86ed1fc1ef5dc1248144e0 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Mon, 17 Jan 2011 22:21:41 +0000 Subject: Allow get_master_key to accept null string Return earlier on wrong length, too. --- src/org/thialfihar/android/apg/ApgService.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 0cfb065db..e395a808d 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -147,6 +147,9 @@ public class ApgService extends Service { * @return master key if found, or 0 */ private static long get_master_key(String search_key) { + if (search_key == null || search_key.length() != 8) { + return 0; + } ArrayList tmp = new ArrayList(); tmp.add(search_key); long[] _keys = get_master_key(tmp); -- cgit v1.2.3 From 5eaea519adfda20246d11b380048adfc83f1ff37 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 18 Jan 2011 20:35:33 +0000 Subject: Refactor some log prios --- src/org/thialfihar/android/apg/ApgService.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index e395a808d..b10de694a 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -24,7 +24,7 @@ import android.os.IBinder; import android.util.Log; public class ApgService extends Service { - final static String TAG = "ApgService"; + private final static String TAG = "ApgService"; @Override public IBinder onBind(Intent intent) { @@ -322,22 +322,22 @@ public class ApgService extends Service { /* add default arguments if missing */ add_default_arguments(call, pArgs); - Log.d(TAG, "add_default_arguments"); + Log.v(TAG, "add_default_arguments"); /* check for required arguments */ check_required_args(call, pArgs, pReturn); - Log.d(TAG, "check_required_args"); + Log.v(TAG, "check_required_args"); /* check for unknown arguments and add to warning if found */ check_unknown_args(call, pArgs, pReturn); - Log.d(TAG, "check_unknown_args"); + Log.v(TAG, "check_unknown_args"); /* return if errors happened */ if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.ordinal()); return false; } - Log.d(TAG, "error return"); + Log.v(TAG, "error return"); return true; } @@ -348,7 +348,7 @@ public class ApgService extends Service { if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) { ArrayList _list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name()); ArrayList _pub_keys = new ArrayList(); - Log.d(TAG, "Long size: " + _list.size()); + Log.v(TAG, "Long size: " + _list.size()); Iterator _iter = _list.iterator(); while (_iter.hasNext()) { _pub_keys.add(_iter.next()); @@ -376,13 +376,13 @@ public class ApgService extends Service { pArgs.getString(arg.SYM_KEY.name()) // passPhrase ); } catch (Exception e) { - Log.d(TAG, "Exception in encrypt"); + Log.e(TAG, "Exception in encrypt"); pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage()); pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); return false; } - Log.d(TAG, "Encrypted"); + Log.v(TAG, "Encrypted"); pReturn.putString(ret.RESULT.name(), _out.toString()); return true; } @@ -422,13 +422,12 @@ public class ApgService extends Service { pArgs.getString(arg.SYM_KEY.name()) != null // symmetric ); } catch (Exception e) { - Log.d(TAG, "Exception in decrypt"); + Log.e(TAG, "Exception in decrypt"); if (e.getMessage() == getBaseContext().getString(R.string.error_noSecretKeyFound)) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + e.getMessage()); pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.ordinal()); } else { pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + e.getMessage()); - e.printStackTrace(); pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); } return false; -- cgit v1.2.3 From 79238cbcce46c9623214a9d0a895cf1a7bc64867 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 18 Jan 2011 20:35:41 +0000 Subject: Rename parameters Writing them out should make them clearer --- src/org/thialfihar/android/apg/ApgService.java | 66 +++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index b10de694a..fe32e01b5 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -41,16 +41,16 @@ public class ApgService extends Service { /** all arguments that can be passed by calling application */ private enum arg { - MSG, // message to encrypt or to decrypt - SYM_KEY, // key for symmetric en/decryption + MESSAGE, // message to encrypt or to decrypt + SYMMETRIC_PASSPHRASE, // key for symmetric en/decryption PUBLIC_KEYS, // public keys for encryption - ENCRYPTION_ALGO, // encryption algorithm - HASH_ALGO, // hash algorithm - ARMORED, // whether to armor output - FORCE_V3_SIG, // whether to force v3 signature + ENCRYPTION_ALGORYTHM, // encryption algorithm + HASH_ALGORYTHM, // hash algorithm + ARMORED_OUTPUT, // whether to armor output + FORCE_V3_SIGNATURE, // whether to force v3 signature COMPRESSION, // what compression to use for encrypted output SIGNATURE_KEY, // key for signing - PRIVATE_KEY_PASS, // passphrase for encrypted private key + PRIVATE_KEY_PASSPHRASE // passphrase for encrypted private key } /** all things that might be returned */ @@ -58,24 +58,24 @@ public class ApgService extends Service { ERRORS, // string array list with errors WARNINGS, // string array list with warnings ERROR, // numeric error - RESULT, // en-/decrypted test + RESULT // en-/decrypted } /** required arguments for each AIDL function */ private static final HashMap> FUNCTIONS_REQUIRED_ARGS = new HashMap>(); static { HashSet args = new HashSet(); - args.add(arg.SYM_KEY); - args.add(arg.MSG); + args.add(arg.SYMMETRIC_PASSPHRASE); + args.add(arg.MESSAGE); FUNCTIONS_REQUIRED_ARGS.put("encrypt_with_passphrase", args); args = new HashSet(); args.add(arg.PUBLIC_KEYS); - args.add(arg.MSG); + args.add(arg.MESSAGE); FUNCTIONS_REQUIRED_ARGS.put("encrypt_with_public_key", args); args = new HashSet(); - args.add(arg.MSG); + args.add(arg.MESSAGE); FUNCTIONS_REQUIRED_ARGS.put("decrypt", args); } @@ -84,30 +84,30 @@ public class ApgService extends Service { private static final HashMap> FUNCTIONS_OPTIONAL_ARGS = new HashMap>(); static { HashSet args = new HashSet(); - args.add(arg.ENCRYPTION_ALGO); - args.add(arg.HASH_ALGO); - args.add(arg.ARMORED); - args.add(arg.FORCE_V3_SIG); + args.add(arg.ENCRYPTION_ALGORYTHM); + args.add(arg.HASH_ALGORYTHM); + args.add(arg.ARMORED_OUTPUT); + args.add(arg.FORCE_V3_SIGNATURE); args.add(arg.COMPRESSION); - args.add(arg.PRIVATE_KEY_PASS); + args.add(arg.PRIVATE_KEY_PASSPHRASE); args.add(arg.SIGNATURE_KEY); FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_passphrase", args); FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_public_key", args); args = new HashSet(); - args.add(arg.SYM_KEY); + args.add(arg.SYMMETRIC_PASSPHRASE); args.add(arg.PUBLIC_KEYS); - args.add(arg.PRIVATE_KEY_PASS); + args.add(arg.PRIVATE_KEY_PASSPHRASE); FUNCTIONS_OPTIONAL_ARGS.put("decrypt", args); } /** a map from ApgService parameters to function calls to get the default */ private static final HashMap FUNCTIONS_DEFAULTS = new HashMap(); static { - FUNCTIONS_DEFAULTS.put(arg.ENCRYPTION_ALGO, "getDefaultEncryptionAlgorithm"); - FUNCTIONS_DEFAULTS.put(arg.HASH_ALGO, "getDefaultHashAlgorithm"); - FUNCTIONS_DEFAULTS.put(arg.ARMORED, "getDefaultAsciiArmour"); - FUNCTIONS_DEFAULTS.put(arg.FORCE_V3_SIG, "getForceV3Signatures"); + FUNCTIONS_DEFAULTS.put(arg.ENCRYPTION_ALGORYTHM, "getDefaultEncryptionAlgorithm"); + FUNCTIONS_DEFAULTS.put(arg.HASH_ALGORYTHM, "getDefaultHashAlgorithm"); + FUNCTIONS_DEFAULTS.put(arg.ARMORED_OUTPUT, "getDefaultAsciiArmour"); + FUNCTIONS_DEFAULTS.put(arg.FORCE_V3_SIGNATURE, "getForceV3Signatures"); FUNCTIONS_DEFAULTS.put(arg.COMPRESSION, "getDefaultMessageCompression"); } @@ -356,7 +356,7 @@ public class ApgService extends Service { _pub_master_keys = get_master_key(_pub_keys); } - InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MSG.name()).getBytes()); + InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); InputData _in = new InputData(_inStream, 0); // XXX Size second param? OutputStream _out = new ByteArrayOutputStream(); @@ -364,16 +364,16 @@ public class ApgService extends Service { Apg.encrypt(getBaseContext(), // context _in, // input stream _out, // output stream - pArgs.getBoolean(arg.ARMORED.name()), // armored + pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT _pub_master_keys, // encryption keys get_master_key(pArgs.getString(arg.SIGNATURE_KEY.name())), // signature key - pArgs.getString(arg.PRIVATE_KEY_PASS.name()), // signature passphrase + pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE.name()), // signature passphrase null, // progress - pArgs.getInt(arg.ENCRYPTION_ALGO.name()), // encryption - pArgs.getInt(arg.HASH_ALGO.name()), // hash + pArgs.getInt(arg.ENCRYPTION_ALGORYTHM.name()), // encryption + pArgs.getInt(arg.HASH_ALGORYTHM.name()), // hash pArgs.getInt(arg.COMPRESSION.name()), // compression - pArgs.getBoolean(arg.FORCE_V3_SIG.name()), // mPreferences.getForceV3Signatures(), - pArgs.getString(arg.SYM_KEY.name()) // passPhrase + pArgs.getBoolean(arg.FORCE_V3_SIGNATURE.name()), // mPreferences.getForceV3Signatures(), + pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) // passPhrase ); } catch (Exception e) { Log.e(TAG, "Exception in encrypt"); @@ -411,15 +411,15 @@ public class ApgService extends Service { return false; } - String _passphrase = pArgs.getString(arg.SYM_KEY.name()) != null ? pArgs.getString(arg.SYM_KEY.name()) : pArgs.getString(arg.PRIVATE_KEY_PASS + String _passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE .name()); - InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MSG.name()).getBytes()); + InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); InputData in = new InputData(inStream, 0); // XXX what size in second parameter? OutputStream out = new ByteArrayOutputStream(); try { Apg.decrypt(getBaseContext(), in, out, _passphrase, null, // progress - pArgs.getString(arg.SYM_KEY.name()) != null // symmetric + pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric ); } catch (Exception e) { Log.e(TAG, "Exception in decrypt"); -- cgit v1.2.3 From 3f703fa4ea5ffb59def408455399cc1ea43b0434 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 18 Jan 2011 21:17:05 +0000 Subject: More finegrained errors --- src/org/thialfihar/android/apg/ApgService.java | 38 ++++++++++++++++++-------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index fe32e01b5..72f0e5dcc 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -36,7 +36,9 @@ public class ApgService extends Service { private enum error { ARGUMENTS_MISSING, APG_FAILURE, - NO_MATCHING_SECRET_KEY + NO_MATCHING_SECRET_KEY, + PRIVATE_KEY_PASSPHRASE_WRONG, + PRIVATE_KEY_PASSPHRASE_MISSING } /** all arguments that can be passed by calling application */ @@ -50,7 +52,8 @@ public class ApgService extends Service { FORCE_V3_SIGNATURE, // whether to force v3 signature COMPRESSION, // what compression to use for encrypted output SIGNATURE_KEY, // key for signing - PRIVATE_KEY_PASSPHRASE // passphrase for encrypted private key + PRIVATE_KEY_PASSPHRASE + // passphrase for encrypted private key } /** all things that might be returned */ @@ -58,7 +61,8 @@ public class ApgService extends Service { ERRORS, // string array list with errors WARNINGS, // string array list with warnings ERROR, // numeric error - RESULT // en-/decrypted + RESULT + // en-/decrypted } /** required arguments for each AIDL function */ @@ -377,9 +381,17 @@ public class ApgService extends Service { ); } catch (Exception e) { Log.e(TAG, "Exception in encrypt"); - pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage()); - - pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); + String _msg = e.getMessage(); + if (_msg == getBaseContext().getString(R.string.error_noSignaturePassPhrase)) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + _msg); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.ordinal()); + } else if (_msg == getBaseContext().getString(R.string.error_couldNotExtractPrivateKey)) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + _msg); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.ordinal()); + } else { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage()); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); + } return false; } Log.v(TAG, "Encrypted"); @@ -411,8 +423,8 @@ public class ApgService extends Service { return false; } - String _passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE - .name()); + String _passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs + .getString(arg.PRIVATE_KEY_PASSPHRASE.name()); InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); InputData in = new InputData(inStream, 0); // XXX what size in second parameter? @@ -423,11 +435,15 @@ public class ApgService extends Service { ); } catch (Exception e) { Log.e(TAG, "Exception in decrypt"); - if (e.getMessage() == getBaseContext().getString(R.string.error_noSecretKeyFound)) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + e.getMessage()); + String _msg = e.getMessage(); + if (_msg == getBaseContext().getString(R.string.error_noSecretKeyFound)) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + _msg); pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.ordinal()); + } else if (_msg == getBaseContext().getString(R.string.error_wrongPassPhrase)) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + _msg); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.ordinal()); } else { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + e.getMessage()); + pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + _msg); pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); } return false; -- cgit v1.2.3 From 79cf07f1e23f5b19c151b360cc25fc9c5a62589f Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 18 Jan 2011 22:24:28 +0000 Subject: Compare strings like they should be compared --- src/org/thialfihar/android/apg/ApgService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 72f0e5dcc..fe9e84d4b 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -382,10 +382,10 @@ public class ApgService extends Service { } catch (Exception e) { Log.e(TAG, "Exception in encrypt"); String _msg = e.getMessage(); - if (_msg == getBaseContext().getString(R.string.error_noSignaturePassPhrase)) { + if (_msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + _msg); pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.ordinal()); - } else if (_msg == getBaseContext().getString(R.string.error_couldNotExtractPrivateKey)) { + } else if (_msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + _msg); pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.ordinal()); } else { @@ -436,10 +436,10 @@ public class ApgService extends Service { } catch (Exception e) { Log.e(TAG, "Exception in decrypt"); String _msg = e.getMessage(); - if (_msg == getBaseContext().getString(R.string.error_noSecretKeyFound)) { + if (_msg.equals(getBaseContext().getString(R.string.error_noSecretKeyFound))) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + _msg); pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.ordinal()); - } else if (_msg == getBaseContext().getString(R.string.error_wrongPassPhrase)) { + } else if (_msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + _msg); pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.ordinal()); } else { -- cgit v1.2.3 From 05627fbd623411e0c138d5e182b207c222e46e31 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Thu, 20 Jan 2011 18:19:42 +0000 Subject: Print some info about keys on asymmetric encryption --- src/org/thialfihar/android/apg/ApgService.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index fe9e84d4b..4e55f80d7 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -199,10 +199,15 @@ public class ApgService extends Service { while (mCursor.moveToNext()) { long _cur_mkey = mCursor.getLong(1); String _cur_user = mCursor.getString(2); + + String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey); Log.d(TAG, "current master key: " + _cur_mkey + " from " + _cur_user); - if (search_keys.contains(Apg.getSmallFingerPrint(_cur_mkey)) || search_keys.contains(_cur_user)) { - Log.d(TAG, "master key found for: " + Apg.getSmallFingerPrint(_cur_mkey)); + if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) { + Log.v(TAG, "master key found for: " + _cur_fprint); _master_keys.add(_cur_mkey); + search_keys.remove(_cur_fprint); + } else { + Log.v(TAG, "Installed key "+_cur_fprint+" is not in the list of public keys to encrypt with"); } } mCursor.close(); @@ -212,6 +217,15 @@ public class ApgService extends Service { for (Long _key : _master_keys) { _master_longs[i++] = _key; } + + if( i == 0) { + Log.e(TAG, "Found no public key to encrypt with, APG will error out"); + } + + for( String _key : search_keys) { + Log.w(TAG, "Cannot encrypt with key "+_key+": cannot find it in APG"); + } + return _master_longs; } -- cgit v1.2.3 From 1af5a985b5db356860a622dacda767c85ef444e6 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Thu, 20 Jan 2011 18:25:38 +0000 Subject: Redefine some log-msges --- src/org/thialfihar/android/apg/ApgService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 4e55f80d7..b7c4f0d4a 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -195,13 +195,14 @@ public class ApgService extends Service { "" + Id.database.type_public }, null, null, orderBy); + Log.v(TAG, "going through installed user keys"); ArrayList _master_keys = new ArrayList(); while (mCursor.moveToNext()) { long _cur_mkey = mCursor.getLong(1); String _cur_user = mCursor.getString(2); String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey); - Log.d(TAG, "current master key: " + _cur_mkey + " from " + _cur_user); + Log.v(TAG, "current user: "+_cur_user+" ("+_cur_fprint+")"); if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) { Log.v(TAG, "master key found for: " + _cur_fprint); _master_keys.add(_cur_mkey); -- cgit v1.2.3 From 392969629c9fb4953a0a257e866d8538515faa50 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Thu, 20 Jan 2011 18:38:15 +0000 Subject: Some better (non-misleading) error msgs Also some reindentation --- src/org/thialfihar/android/apg/ApgService.java | 32 ++++++++++++++------------ 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index b7c4f0d4a..fc6742445 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -150,13 +150,13 @@ public class ApgService extends Service { * fingerprint or user id to search for * @return master key if found, or 0 */ - private static long get_master_key(String search_key) { + private static long get_master_key(String search_key, Bundle pReturn) { if (search_key == null || search_key.length() != 8) { return 0; } ArrayList tmp = new ArrayList(); tmp.add(search_key); - long[] _keys = get_master_key(tmp); + long[] _keys = get_master_key(tmp, pReturn); if (_keys.length > 0) return _keys[0]; else @@ -171,7 +171,7 @@ public class ApgService extends Service { * database * @return an array of master keys */ - private static long[] get_master_key(ArrayList search_keys) { + private static long[] get_master_key(ArrayList search_keys, Bundle pReturn) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME @@ -200,15 +200,15 @@ public class ApgService extends Service { while (mCursor.moveToNext()) { long _cur_mkey = mCursor.getLong(1); String _cur_user = mCursor.getString(2); - + String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey); - Log.v(TAG, "current user: "+_cur_user+" ("+_cur_fprint+")"); + Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")"); if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) { Log.v(TAG, "master key found for: " + _cur_fprint); _master_keys.add(_cur_mkey); search_keys.remove(_cur_fprint); } else { - Log.v(TAG, "Installed key "+_cur_fprint+" is not in the list of public keys to encrypt with"); + Log.v(TAG, "Installed key " + _cur_fprint + " is not in the list of public keys to encrypt with"); } } mCursor.close(); @@ -218,15 +218,17 @@ public class ApgService extends Service { for (Long _key : _master_keys) { _master_longs[i++] = _key; } - - if( i == 0) { - Log.e(TAG, "Found no public key to encrypt with, APG will error out"); + + if (i == 0) { + Log.w(TAG, "Found not one public key"); + pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for public key(s) but found not one"); } - - for( String _key : search_keys) { - Log.w(TAG, "Cannot encrypt with key "+_key+": cannot find it in APG"); + + for (String _key : search_keys) { + Log.w(TAG, "Searched for key " + _key + " but cannot find it in APG"); + pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for key " + _key + " but cannot find it in APG"); } - + return _master_longs; } @@ -372,7 +374,7 @@ public class ApgService extends Service { while (_iter.hasNext()) { _pub_keys.add(_iter.next()); } - _pub_master_keys = get_master_key(_pub_keys); + _pub_master_keys = get_master_key(_pub_keys, pReturn); } InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); @@ -385,7 +387,7 @@ public class ApgService extends Service { _out, // output stream pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT _pub_master_keys, // encryption keys - get_master_key(pArgs.getString(arg.SIGNATURE_KEY.name())), // signature key + get_master_key(pArgs.getString(arg.SIGNATURE_KEY.name()), pReturn), // signature key pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE.name()), // signature passphrase null, // progress pArgs.getInt(arg.ENCRYPTION_ALGORYTHM.name()), // encryption -- cgit v1.2.3 From c9f6f56827ce7b368a009c153d1f9995651f6522 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Thu, 20 Jan 2011 20:00:28 +0000 Subject: Work on errors and documentation - once more --- src/org/thialfihar/android/apg/ApgService.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index fc6742445..c4a348cb4 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -38,7 +38,11 @@ public class ApgService extends Service { APG_FAILURE, NO_MATCHING_SECRET_KEY, PRIVATE_KEY_PASSPHRASE_WRONG, - PRIVATE_KEY_PASSPHRASE_MISSING + PRIVATE_KEY_PASSPHRASE_MISSING; + + public int shifted_ordinal() { + return ordinal() + 100; + } } /** all arguments that can be passed by calling application */ @@ -355,7 +359,7 @@ public class ApgService extends Service { /* return if errors happened */ if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { - pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.ordinal()); + pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shifted_ordinal()); return false; } Log.v(TAG, "error return"); @@ -401,13 +405,13 @@ public class ApgService extends Service { String _msg = e.getMessage(); if (_msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + _msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.ordinal()); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.shifted_ordinal()); } else if (_msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + _msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.ordinal()); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shifted_ordinal()); } else { pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage()); - pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shifted_ordinal()); } return false; } @@ -455,13 +459,13 @@ public class ApgService extends Service { String _msg = e.getMessage(); if (_msg.equals(getBaseContext().getString(R.string.error_noSecretKeyFound))) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + _msg); - pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.ordinal()); + pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shifted_ordinal()); } else if (_msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + _msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.ordinal()); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shifted_ordinal()); } else { pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + _msg); - pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal()); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shifted_ordinal()); } return false; } -- cgit v1.2.3 From b5097b7a417b13c288adfbd1c0ea4f6d86715cf1 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Thu, 20 Jan 2011 20:23:13 +0000 Subject: Some more verbose logs --- src/org/thialfihar/android/apg/ApgService.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index c4a348cb4..b36b5cd0a 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -385,6 +385,7 @@ public class ApgService extends Service { InputData _in = new InputData(_inStream, 0); // XXX Size second param? OutputStream _out = new ByteArrayOutputStream(); + Log.v(TAG, "About to encrypt"); try { Apg.encrypt(getBaseContext(), // context _in, // input stream @@ -450,6 +451,7 @@ public class ApgService extends Service { InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); InputData in = new InputData(inStream, 0); // XXX what size in second parameter? OutputStream out = new ByteArrayOutputStream(); + Log.v(TAG, "About to decrypt"); try { Apg.decrypt(getBaseContext(), in, out, _passphrase, null, // progress pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric @@ -469,6 +471,7 @@ public class ApgService extends Service { } return false; } + Log.v(TAG, "Decrypted"); pReturn.putString(ret.RESULT.name(), out.toString()); return true; -- cgit v1.2.3 From 6b7db8161a158e12344145815534f6552797cf6d Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Sun, 23 Jan 2011 21:36:27 +0000 Subject: Don't query things we don't need --- src/org/thialfihar/android/apg/ApgService.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index b36b5cd0a..3fa88673f 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -6,7 +6,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -185,16 +184,9 @@ public class ApgService extends Service { String orderBy = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; - long now = new Date().getTime() / 1000; Cursor mCursor = qb.query(Apg.getDatabase().db(), new String[] { - KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 - KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1 - UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2 - "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME - + "." + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " + "tmp." + Keys.CAN_ENCRYPT + " = '1')", // 3 - "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME - + "." + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " + "tmp." + Keys.CAN_ENCRYPT + " = '1' AND " + "tmp." - + Keys.CREATION + " <= '" + now + "' AND " + "(tmp." + Keys.EXPIRY + " IS NULL OR " + "tmp." + Keys.EXPIRY + " >= '" + now + "'))", // 4 + KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0 + UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1 }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { "" + Id.database.type_public }, null, null, orderBy); @@ -202,8 +194,8 @@ public class ApgService extends Service { Log.v(TAG, "going through installed user keys"); ArrayList _master_keys = new ArrayList(); while (mCursor.moveToNext()) { - long _cur_mkey = mCursor.getLong(1); - String _cur_user = mCursor.getString(2); + long _cur_mkey = mCursor.getLong(0); + String _cur_user = mCursor.getString(1); String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey); Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")"); -- cgit v1.2.3 From 1ec5fc05412c6d7019dd40497a81397752bee602 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Sun, 23 Jan 2011 21:36:35 +0000 Subject: Allow to retrieve fingerprints and user ids through AIDL Update ApgCon and doc accordingly. Not very tested. --- src/org/thialfihar/android/apg/ApgService.java | 148 +++++++++++++++++-------- 1 file changed, 102 insertions(+), 46 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 3fa88673f..20bd1b1e3 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -9,7 +9,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.Set; import org.thialfihar.android.apg.provider.KeyRings; import org.thialfihar.android.apg.provider.Keys; @@ -38,7 +37,7 @@ public class ApgService extends Service { NO_MATCHING_SECRET_KEY, PRIVATE_KEY_PASSPHRASE_WRONG, PRIVATE_KEY_PASSPHRASE_MISSING; - + public int shifted_ordinal() { return ordinal() + 100; } @@ -55,8 +54,8 @@ public class ApgService extends Service { FORCE_V3_SIGNATURE, // whether to force v3 signature COMPRESSION, // what compression to use for encrypted output SIGNATURE_KEY, // key for signing - PRIVATE_KEY_PASSPHRASE - // passphrase for encrypted private key + PRIVATE_KEY_PASSPHRASE, // passphrase for encrypted private key + KEY_TYPE, // type of key (private or public) } /** all things that might be returned */ @@ -64,12 +63,13 @@ public class ApgService extends Service { ERRORS, // string array list with errors WARNINGS, // string array list with warnings ERROR, // numeric error - RESULT - // en-/decrypted + RESULT, // en-/decrypted + FINGERPRINTS, // fingerprints of keys + USER_IDS, // user ids } /** required arguments for each AIDL function */ - private static final HashMap> FUNCTIONS_REQUIRED_ARGS = new HashMap>(); + private static final HashMap> FUNCTIONS_REQUIRED_ARGS = new HashMap>(); static { HashSet args = new HashSet(); args.add(arg.SYMMETRIC_PASSPHRASE); @@ -85,10 +85,14 @@ public class ApgService extends Service { args.add(arg.MESSAGE); FUNCTIONS_REQUIRED_ARGS.put("decrypt", args); + args = new HashSet(); + args.add(arg.KEY_TYPE); + FUNCTIONS_REQUIRED_ARGS.put("get_keys", args); + } /** optional arguments for each AIDL function */ - private static final HashMap> FUNCTIONS_OPTIONAL_ARGS = new HashMap>(); + private static final HashMap> FUNCTIONS_OPTIONAL_ARGS = new HashMap>(); static { HashSet args = new HashSet(); args.add(arg.ENCRYPTION_ALGORYTHM); @@ -166,6 +170,26 @@ public class ApgService extends Service { return 0; } + private static Cursor get_key_entries(HashMap params) { + SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." + + UserIds.RANK + " = '0') "); + + String orderBy = params.containsKey("order_by") ? (String) params.get("order_by") : UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; + + String type_val[] = null; + String type_where = null; + if (params.containsKey("key_type")) { + type_where = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?"; + type_val = new String[] { + "" + params.get("key_type") + }; + } + return qb.query(Apg.getDatabase().db(), (String[]) params.get("columns"), type_where, type_val, null, null, orderBy); + } + /** * maps fingerprints or user ids of keys to master keys in database * @@ -176,20 +200,14 @@ public class ApgService extends Service { */ private static long[] get_master_key(ArrayList search_keys, Bundle pReturn) { - SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME - + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME - + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." - + UserIds.RANK + " = '0') "); - - String orderBy = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; - - Cursor mCursor = qb.query(Apg.getDatabase().db(), new String[] { + HashMap qParams = new HashMap(); + qParams.put("columns", new String[] { KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0 UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1 - }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { - "" + Id.database.type_public - }, null, null, orderBy); + }); + qParams.put("key_type", Id.database.type_public); + + Cursor mCursor = get_key_entries(qParams); Log.v(TAG, "going through installed user keys"); ArrayList _master_keys = new ArrayList(); @@ -235,27 +253,30 @@ public class ApgService extends Service { * the bundle to add default parameters to if missing */ private void add_default_arguments(String call, Bundle args) { - Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); + // check whether there are optional elements defined for that call + if (FUNCTIONS_OPTIONAL_ARGS.containsKey(call)) { + Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); - Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator(); - while (_iter.hasNext()) { - arg _current_arg = _iter.next(); - String _current_key = _current_arg.name(); - if (!args.containsKey(_current_key) && FUNCTIONS_OPTIONAL_ARGS.get(call).contains(_current_arg)) { - String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_arg); - try { - Class _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name); - if (_ret_type == String.class) { - args.putString(_current_key, (String) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); - } else if (_ret_type == boolean.class) { - args.putBoolean(_current_key, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); - } else if (_ret_type == int.class) { - args.putInt(_current_key, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); - } else { - Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option"); + Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator(); + while (_iter.hasNext()) { + arg _current_arg = _iter.next(); + String _current_key = _current_arg.name(); + if (!args.containsKey(_current_key) && FUNCTIONS_OPTIONAL_ARGS.get(call).contains(_current_arg)) { + String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_arg); + try { + Class _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name); + if (_ret_type == String.class) { + args.putString(_current_key, (String) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); + } else if (_ret_type == boolean.class) { + args.putBoolean(_current_key, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); + } else if (_ret_type == int.class) { + args.putInt(_current_key, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); + } else { + Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option"); + } + } catch (Exception e) { + Log.e(TAG, "Exception in add_default_arguments " + e.getMessage()); } - } catch (Exception e) { - Log.e(TAG, "Exception in add_default_arguments " + e.getMessage()); } } } @@ -286,11 +307,13 @@ public class ApgService extends Service { * the bundle to write errors to */ private void check_required_args(String function, Bundle pArgs, Bundle pReturn) { - Iterator _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator(); - while (_iter.hasNext()) { - String _cur_arg = _iter.next().name(); - if (!pArgs.containsKey(_cur_arg)) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + _cur_arg); + if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) { + Iterator _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator(); + while (_iter.hasNext()) { + String _cur_arg = _iter.next().name(); + if (!pArgs.containsKey(_cur_arg)) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + _cur_arg); + } } } } @@ -306,8 +329,14 @@ public class ApgService extends Service { * the bundle to write warnings to */ private void check_unknown_args(String function, Bundle pArgs, Bundle pReturn) { - HashSet all_args = new HashSet(FUNCTIONS_REQUIRED_ARGS.get(function)); - all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function)); + + HashSet all_args = new HashSet(); + if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) { + all_args.addAll(FUNCTIONS_REQUIRED_ARGS.get(function)); + } + if (FUNCTIONS_OPTIONAL_ARGS.containsKey(function)) { + all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function)); + } ArrayList _unknown_args = new ArrayList(); Iterator _iter = pArgs.keySet().iterator(); @@ -415,6 +444,32 @@ public class ApgService extends Service { private final IApgService.Stub mBinder = new IApgService.Stub() { + public boolean get_keys(Bundle pArgs, Bundle pReturn) { + + prepare_args("get_keys", pArgs, pReturn); + + HashMap qParams = new HashMap(); + qParams.put("columns", new String[] { + KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0 + UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1 + }); + + qParams.put("key_type", pArgs.getInt(arg.KEY_TYPE.name())); + + Cursor mCursor = get_key_entries(qParams); + ArrayList fprints = new ArrayList(); + ArrayList ids = new ArrayList(); + while (mCursor.moveToNext()) { + fprints.add(Apg.getSmallFingerPrint(mCursor.getLong(0))); + ids.add(mCursor.getString(1)); + } + mCursor.close(); + + pReturn.putStringArrayList(ret.FINGERPRINTS.name(), fprints); + pReturn.putStringArrayList(ret.USER_IDS.name(), ids); + return true; + } + public boolean encrypt_with_public_key(Bundle pArgs, Bundle pReturn) { if (!prepare_args("encrypt_with_public_key", pArgs, pReturn)) { return false; @@ -468,5 +523,6 @@ public class ApgService extends Service { pReturn.putString(ret.RESULT.name(), out.toString()); return true; } + }; } -- cgit v1.2.3 From cb4f1933d55abeda08623115464e393a886b8032 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Sun, 23 Jan 2011 21:36:51 +0000 Subject: Dont remove result and warnings from result Some more debug output, too --- src/org/thialfihar/android/apg/ApgService.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 20bd1b1e3..87437e629 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -380,6 +380,7 @@ public class ApgService extends Service { /* return if errors happened */ if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { + Log.v(TAG, "Errors after preparing, not executing "+call); pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shifted_ordinal()); return false; } @@ -460,6 +461,7 @@ public class ApgService extends Service { ArrayList fprints = new ArrayList(); ArrayList ids = new ArrayList(); while (mCursor.moveToNext()) { + Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(mCursor.getLong(0))); fprints.add(Apg.getSmallFingerPrint(mCursor.getLong(0))); ids.add(mCursor.getString(1)); } -- cgit v1.2.3 From 6502e58c26cddc8472b6b46932250eb1fca88156 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Sun, 5 Jun 2011 19:05:18 +0000 Subject: Possibility to not compile Log.d and Log.v in --- src/org/thialfihar/android/apg/ApgService.java | 34 ++++++++++++++------------ 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 87437e629..34248c809 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -23,10 +23,12 @@ import android.util.Log; public class ApgService extends Service { private final static String TAG = "ApgService"; + private static final boolean LOCAL_LOGV = true; + private static final boolean LOCAL_LOGD = true; @Override public IBinder onBind(Intent intent) { - Log.d(TAG, "bound"); + if( LOCAL_LOGD ) Log.d(TAG, "bound"); return mBinder; } @@ -209,20 +211,20 @@ public class ApgService extends Service { Cursor mCursor = get_key_entries(qParams); - Log.v(TAG, "going through installed user keys"); + if( LOCAL_LOGV ) Log.v(TAG, "going through installed user keys"); ArrayList _master_keys = new ArrayList(); while (mCursor.moveToNext()) { long _cur_mkey = mCursor.getLong(0); String _cur_user = mCursor.getString(1); String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey); - Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")"); + if( LOCAL_LOGV ) Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")"); if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) { - Log.v(TAG, "master key found for: " + _cur_fprint); + if( LOCAL_LOGV ) Log.v(TAG, "master key found for: " + _cur_fprint); _master_keys.add(_cur_mkey); search_keys.remove(_cur_fprint); } else { - Log.v(TAG, "Installed key " + _cur_fprint + " is not in the list of public keys to encrypt with"); + if( LOCAL_LOGV ) Log.v(TAG, "Installed key " + _cur_fprint + " is not in the list of public keys to encrypt with"); } } mCursor.close(); @@ -368,23 +370,23 @@ public class ApgService extends Service { /* add default arguments if missing */ add_default_arguments(call, pArgs); - Log.v(TAG, "add_default_arguments"); + if( LOCAL_LOGV ) Log.v(TAG, "add_default_arguments"); /* check for required arguments */ check_required_args(call, pArgs, pReturn); - Log.v(TAG, "check_required_args"); + if( LOCAL_LOGV ) Log.v(TAG, "check_required_args"); /* check for unknown arguments and add to warning if found */ check_unknown_args(call, pArgs, pReturn); - Log.v(TAG, "check_unknown_args"); + if( LOCAL_LOGV ) Log.v(TAG, "check_unknown_args"); /* return if errors happened */ if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { - Log.v(TAG, "Errors after preparing, not executing "+call); + if( LOCAL_LOGV ) Log.v(TAG, "Errors after preparing, not executing "+call); pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shifted_ordinal()); return false; } - Log.v(TAG, "error return"); + if( LOCAL_LOGV ) Log.v(TAG, "error return"); return true; } @@ -395,7 +397,7 @@ public class ApgService extends Service { if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) { ArrayList _list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name()); ArrayList _pub_keys = new ArrayList(); - Log.v(TAG, "Long size: " + _list.size()); + if( LOCAL_LOGV ) Log.v(TAG, "Long size: " + _list.size()); Iterator _iter = _list.iterator(); while (_iter.hasNext()) { _pub_keys.add(_iter.next()); @@ -407,7 +409,7 @@ public class ApgService extends Service { InputData _in = new InputData(_inStream, 0); // XXX Size second param? OutputStream _out = new ByteArrayOutputStream(); - Log.v(TAG, "About to encrypt"); + if( LOCAL_LOGV ) Log.v(TAG, "About to encrypt"); try { Apg.encrypt(getBaseContext(), // context _in, // input stream @@ -438,7 +440,7 @@ public class ApgService extends Service { } return false; } - Log.v(TAG, "Encrypted"); + if( LOCAL_LOGV ) Log.v(TAG, "Encrypted"); pReturn.putString(ret.RESULT.name(), _out.toString()); return true; } @@ -461,7 +463,7 @@ public class ApgService extends Service { ArrayList fprints = new ArrayList(); ArrayList ids = new ArrayList(); while (mCursor.moveToNext()) { - Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(mCursor.getLong(0))); + if( LOCAL_LOGV ) Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(mCursor.getLong(0))); fprints.add(Apg.getSmallFingerPrint(mCursor.getLong(0))); ids.add(mCursor.getString(1)); } @@ -500,7 +502,7 @@ public class ApgService extends Service { InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); InputData in = new InputData(inStream, 0); // XXX what size in second parameter? OutputStream out = new ByteArrayOutputStream(); - Log.v(TAG, "About to decrypt"); + if( LOCAL_LOGV ) Log.v(TAG, "About to decrypt"); try { Apg.decrypt(getBaseContext(), in, out, _passphrase, null, // progress pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric @@ -520,7 +522,7 @@ public class ApgService extends Service { } return false; } - Log.v(TAG, "Decrypted"); + if( LOCAL_LOGV ) Log.v(TAG, "Decrypted"); pReturn.putString(ret.RESULT.name(), out.toString()); return true; -- cgit v1.2.3 From 24205b8dbc6487ee066fec07c9c0840a3be30bb7 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Sun, 5 Jun 2011 19:05:57 +0000 Subject: Cleanup of code, AIDL-calls renamed! --- src/org/thialfihar/android/apg/ApgService.java | 320 ++++++++++++------------- 1 file changed, 153 insertions(+), 167 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 34248c809..0a25c6055 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -40,7 +40,7 @@ public class ApgService extends Service { PRIVATE_KEY_PASSPHRASE_WRONG, PRIVATE_KEY_PASSPHRASE_MISSING; - public int shifted_ordinal() { + public int shiftedOrdinal() { return ordinal() + 100; } } @@ -90,7 +90,6 @@ public class ApgService extends Service { args = new HashSet(); args.add(arg.KEY_TYPE); FUNCTIONS_REQUIRED_ARGS.put("get_keys", args); - } /** optional arguments for each AIDL function */ @@ -124,21 +123,7 @@ public class ApgService extends Service { FUNCTIONS_DEFAULTS.put(arg.COMPRESSION, "getDefaultMessageCompression"); } - /** a map the default functions to their return types */ - private static final HashMap> FUNCTIONS_DEFAULTS_TYPES = new HashMap>(); - static { - try { - FUNCTIONS_DEFAULTS_TYPES.put("getDefaultEncryptionAlgorithm", Preferences.class.getMethod("getDefaultEncryptionAlgorithm").getReturnType()); - FUNCTIONS_DEFAULTS_TYPES.put("getDefaultHashAlgorithm", Preferences.class.getMethod("getDefaultHashAlgorithm").getReturnType()); - FUNCTIONS_DEFAULTS_TYPES.put("getDefaultAsciiArmour", Preferences.class.getMethod("getDefaultAsciiArmour").getReturnType()); - FUNCTIONS_DEFAULTS_TYPES.put("getForceV3Signatures", Preferences.class.getMethod("getForceV3Signatures").getReturnType()); - FUNCTIONS_DEFAULTS_TYPES.put("getDefaultMessageCompression", Preferences.class.getMethod("getDefaultMessageCompression").getReturnType()); - } catch (Exception e) { - Log.e(TAG, "Function default exception: " + e.getMessage()); - } - } - - /** a map the default function names to their method */ + /** a map of the default function names to their method */ private static final HashMap FUNCTIONS_DEFAULTS_METHODS = new HashMap(); static { try { @@ -152,46 +137,47 @@ public class ApgService extends Service { } } - /** - * maps a fingerprint or user id of a key to as master key in database - * - * @param search_key - * fingerprint or user id to search for - * @return master key if found, or 0 - */ - private static long get_master_key(String search_key, Bundle pReturn) { - if (search_key == null || search_key.length() != 8) { - return 0; - } - ArrayList tmp = new ArrayList(); - tmp.add(search_key); - long[] _keys = get_master_key(tmp, pReturn); - if (_keys.length > 0) - return _keys[0]; - else - return 0; - } - - private static Cursor get_key_entries(HashMap params) { + private static Cursor getKeyEntries(HashMap pParams) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); - String orderBy = params.containsKey("order_by") ? (String) params.get("order_by") : UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; + String orderBy = pParams.containsKey("order_by") ? (String) pParams.get("order_by") : UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; - String type_val[] = null; - String type_where = null; - if (params.containsKey("key_type")) { - type_where = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?"; - type_val = new String[] { - "" + params.get("key_type") + String typeVal[] = null; + String typeWhere = null; + if (pParams.containsKey("key_type")) { + typeWhere = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?"; + typeVal = new String[] { + "" + pParams.get("key_type") }; } - return qb.query(Apg.getDatabase().db(), (String[]) params.get("columns"), type_where, type_val, null, null, orderBy); + return qb.query(Apg.getDatabase().db(), (String[]) pParams.get("columns"), typeWhere, typeVal, null, null, orderBy); } + /** + * maps a fingerprint or user id of a key to a master key in database + * + * @param search_key + * fingerprint or user id to search for + * @return master key if found, or 0 + */ + private static long getMasterKey(String pSearchKey, Bundle pReturn) { + if (pSearchKey == null || pSearchKey.length() != 8) { + return 0; + } + ArrayList keyList = new ArrayList(); + keyList.add(pSearchKey); + long[] keys = getMasterKey(keyList, pReturn); + if (keys.length > 0) { + return keys[0]; + } else { + return 0; + } + } + /** * maps fingerprints or user ids of keys to master keys in database * @@ -200,7 +186,7 @@ public class ApgService extends Service { * database * @return an array of master keys */ - private static long[] get_master_key(ArrayList search_keys, Bundle pReturn) { + private static long[] getMasterKey(ArrayList pSearchKeys, Bundle pReturn) { HashMap qParams = new HashMap(); qParams.put("columns", new String[] { @@ -209,30 +195,30 @@ public class ApgService extends Service { }); qParams.put("key_type", Id.database.type_public); - Cursor mCursor = get_key_entries(qParams); + Cursor mCursor = getKeyEntries(qParams); if( LOCAL_LOGV ) Log.v(TAG, "going through installed user keys"); - ArrayList _master_keys = new ArrayList(); + ArrayList masterKeys = new ArrayList(); while (mCursor.moveToNext()) { - long _cur_mkey = mCursor.getLong(0); - String _cur_user = mCursor.getString(1); - - String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey); - if( LOCAL_LOGV ) Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")"); - if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) { - if( LOCAL_LOGV ) Log.v(TAG, "master key found for: " + _cur_fprint); - _master_keys.add(_cur_mkey); - search_keys.remove(_cur_fprint); + long curMkey = mCursor.getLong(0); + String curUser = mCursor.getString(1); + + String curFprint = Apg.getSmallFingerPrint(curMkey); + if( LOCAL_LOGV ) Log.v(TAG, "current user: " + curUser + " (" + curFprint + ")"); + if (pSearchKeys.contains(curFprint) || pSearchKeys.contains(curUser)) { + if( LOCAL_LOGV ) Log.v(TAG, "master key found for: " + curFprint); + masterKeys.add(curMkey); + pSearchKeys.remove(curFprint); } else { - if( LOCAL_LOGV ) Log.v(TAG, "Installed key " + _cur_fprint + " is not in the list of public keys to encrypt with"); + if( LOCAL_LOGV ) Log.v(TAG, "Installed key " + curFprint + " is not in the list of public keys to encrypt with"); } } mCursor.close(); - long[] _master_longs = new long[_master_keys.size()]; + long[] masterKeyLongs = new long[masterKeys.size()]; int i = 0; - for (Long _key : _master_keys) { - _master_longs[i++] = _key; + for (Long key : masterKeys) { + masterKeyLongs[i++] = key; } if (i == 0) { @@ -240,12 +226,12 @@ public class ApgService extends Service { pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for public key(s) but found not one"); } - for (String _key : search_keys) { - Log.w(TAG, "Searched for key " + _key + " but cannot find it in APG"); - pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for key " + _key + " but cannot find it in APG"); + for (String key : pSearchKeys) { + Log.w(TAG, "Searched for key " + key + " but cannot find it in APG"); + pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for key " + key + " but cannot find it in APG"); } - return _master_longs; + return masterKeyLongs; } /** @@ -254,27 +240,27 @@ public class ApgService extends Service { * @param args * the bundle to add default parameters to if missing */ - private void add_default_arguments(String call, Bundle args) { + private void addDefaultArguments(String pCall, Bundle pArgs) { // check whether there are optional elements defined for that call - if (FUNCTIONS_OPTIONAL_ARGS.containsKey(call)) { - Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true); - - Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator(); - while (_iter.hasNext()) { - arg _current_arg = _iter.next(); - String _current_key = _current_arg.name(); - if (!args.containsKey(_current_key) && FUNCTIONS_OPTIONAL_ARGS.get(call).contains(_current_arg)) { - String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_arg); + if (FUNCTIONS_OPTIONAL_ARGS.containsKey(pCall)) { + Preferences preferences = Preferences.getPreferences(getBaseContext(), true); + + Iterator iter = FUNCTIONS_DEFAULTS.keySet().iterator(); + while (iter.hasNext()) { + arg currentArg = iter.next(); + String currentKey = currentArg.name(); + if (!pArgs.containsKey(currentKey) && FUNCTIONS_OPTIONAL_ARGS.get(pCall).contains(currentArg)) { + String currentFunctionName = FUNCTIONS_DEFAULTS.get(currentArg); try { - Class _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name); - if (_ret_type == String.class) { - args.putString(_current_key, (String) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); - } else if (_ret_type == boolean.class) { - args.putBoolean(_current_key, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); - } else if (_ret_type == int.class) { - args.putInt(_current_key, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences)); + Class returnType = FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).getReturnType(); + if (returnType == String.class) { + pArgs.putString(currentKey, (String) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences)); + } else if (returnType == boolean.class) { + pArgs.putBoolean(currentKey, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences)); + } else if (returnType == int.class) { + pArgs.putInt(currentKey, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences)); } else { - Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option"); + Log.e(TAG, "Unknown return type " + returnType.toString() + " for default option"); } } catch (Exception e) { Log.e(TAG, "Exception in add_default_arguments " + e.getMessage()); @@ -290,7 +276,7 @@ public class ApgService extends Service { * @param pReturn * the Bundle to update */ - private void add_default_returns(Bundle pReturn) { + private void addDefaultReturns(Bundle pReturn) { ArrayList errors = new ArrayList(); ArrayList warnings = new ArrayList(); @@ -308,13 +294,13 @@ public class ApgService extends Service { * @param pReturn * the bundle to write errors to */ - private void check_required_args(String function, Bundle pArgs, Bundle pReturn) { - if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) { - Iterator _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator(); - while (_iter.hasNext()) { - String _cur_arg = _iter.next().name(); - if (!pArgs.containsKey(_cur_arg)) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + _cur_arg); + private void checkForRequiredArgs(String pFunction, Bundle pArgs, Bundle pReturn) { + if (FUNCTIONS_REQUIRED_ARGS.containsKey(pFunction)) { + Iterator iter = FUNCTIONS_REQUIRED_ARGS.get(pFunction).iterator(); + while (iter.hasNext()) { + String curArg = iter.next().name(); + if (!pArgs.containsKey(curArg)) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + curArg); } } } @@ -330,60 +316,60 @@ public class ApgService extends Service { * @param pReturn * the bundle to write warnings to */ - private void check_unknown_args(String function, Bundle pArgs, Bundle pReturn) { + private void checkForUnknownArgs(String pFunction, Bundle pArgs, Bundle pReturn) { - HashSet all_args = new HashSet(); - if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) { - all_args.addAll(FUNCTIONS_REQUIRED_ARGS.get(function)); + HashSet allArgs = new HashSet(); + if (FUNCTIONS_REQUIRED_ARGS.containsKey(pFunction)) { + allArgs.addAll(FUNCTIONS_REQUIRED_ARGS.get(pFunction)); } - if (FUNCTIONS_OPTIONAL_ARGS.containsKey(function)) { - all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function)); + if (FUNCTIONS_OPTIONAL_ARGS.containsKey(pFunction)) { + allArgs.addAll(FUNCTIONS_OPTIONAL_ARGS.get(pFunction)); } - ArrayList _unknown_args = new ArrayList(); - Iterator _iter = pArgs.keySet().iterator(); - while (_iter.hasNext()) { - String _cur_key = _iter.next(); + ArrayList unknownArgs = new ArrayList(); + Iterator iter = pArgs.keySet().iterator(); + while (iter.hasNext()) { + String curKey = iter.next(); try { - arg _cur_arg = arg.valueOf(_cur_key); - if (!all_args.contains(_cur_arg)) { - pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key); - _unknown_args.add(_cur_key); + arg curArg = arg.valueOf(curKey); + if (!allArgs.contains(curArg)) { + pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + curKey); + unknownArgs.add(curKey); } } catch (Exception e) { - pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key); - _unknown_args.add(_cur_key); + pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + curKey); + unknownArgs.add(curKey); } } // remove unknown arguments so our bundle has just what we need - for (String _arg : _unknown_args) { - pArgs.remove(_arg); + for (String arg : unknownArgs) { + pArgs.remove(arg); } } - private boolean prepare_args(String call, Bundle pArgs, Bundle pReturn) { + private boolean prepareArgs(String pCall, Bundle pArgs, Bundle pReturn) { Apg.initialize(getBaseContext()); /* add default return values for all functions */ - add_default_returns(pReturn); + addDefaultReturns(pReturn); /* add default arguments if missing */ - add_default_arguments(call, pArgs); + addDefaultArguments(pCall, pArgs); if( LOCAL_LOGV ) Log.v(TAG, "add_default_arguments"); /* check for required arguments */ - check_required_args(call, pArgs, pReturn); + checkForRequiredArgs(pCall, pArgs, pReturn); if( LOCAL_LOGV ) Log.v(TAG, "check_required_args"); /* check for unknown arguments and add to warning if found */ - check_unknown_args(call, pArgs, pReturn); + checkForUnknownArgs(pCall, pArgs, pReturn); if( LOCAL_LOGV ) Log.v(TAG, "check_unknown_args"); /* return if errors happened */ if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { - if( LOCAL_LOGV ) Log.v(TAG, "Errors after preparing, not executing "+call); - pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shifted_ordinal()); + if( LOCAL_LOGV ) Log.v(TAG, "Errors after preparing, not executing "+pCall); + pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shiftedOrdinal()); return false; } if( LOCAL_LOGV ) Log.v(TAG, "error return"); @@ -393,30 +379,30 @@ public class ApgService extends Service { private boolean encrypt(Bundle pArgs, Bundle pReturn) { - long _pub_master_keys[] = {}; + long pubMasterKeys[] = {}; if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) { - ArrayList _list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name()); - ArrayList _pub_keys = new ArrayList(); - if( LOCAL_LOGV ) Log.v(TAG, "Long size: " + _list.size()); - Iterator _iter = _list.iterator(); - while (_iter.hasNext()) { - _pub_keys.add(_iter.next()); + ArrayList list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name()); + ArrayList pubKeys = new ArrayList(); + if( LOCAL_LOGV ) Log.v(TAG, "Long size: " + list.size()); + Iterator iter = list.iterator(); + while (iter.hasNext()) { + pubKeys.add(iter.next()); } - _pub_master_keys = get_master_key(_pub_keys, pReturn); + pubMasterKeys = getMasterKey(pubKeys, pReturn); } - InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); - InputData _in = new InputData(_inStream, 0); // XXX Size second param? + InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); + InputData in = new InputData(inStream, 0); // XXX Size second param? - OutputStream _out = new ByteArrayOutputStream(); + OutputStream out = new ByteArrayOutputStream(); if( LOCAL_LOGV ) Log.v(TAG, "About to encrypt"); try { Apg.encrypt(getBaseContext(), // context - _in, // input stream - _out, // output stream + in, // input stream + out, // output stream pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT - _pub_master_keys, // encryption keys - get_master_key(pArgs.getString(arg.SIGNATURE_KEY.name()), pReturn), // signature key + pubMasterKeys, // encryption keys + getMasterKey(pArgs.getString(arg.SIGNATURE_KEY.name()), pReturn), // signature key pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE.name()), // signature passphrase null, // progress pArgs.getInt(arg.ENCRYPTION_ALGORYTHM.name()), // encryption @@ -427,29 +413,29 @@ public class ApgService extends Service { ); } catch (Exception e) { Log.e(TAG, "Exception in encrypt"); - String _msg = e.getMessage(); - if (_msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + _msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.shifted_ordinal()); - } else if (_msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + _msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shifted_ordinal()); + String msg = e.getMessage(); + if (msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + msg); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.shiftedOrdinal()); + } else if (msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + msg); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal()); } else { pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage()); - pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shifted_ordinal()); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shiftedOrdinal()); } return false; } if( LOCAL_LOGV ) Log.v(TAG, "Encrypted"); - pReturn.putString(ret.RESULT.name(), _out.toString()); + pReturn.putString(ret.RESULT.name(), out.toString()); return true; } private final IApgService.Stub mBinder = new IApgService.Stub() { - public boolean get_keys(Bundle pArgs, Bundle pReturn) { + public boolean getKeys(Bundle pArgs, Bundle pReturn) { - prepare_args("get_keys", pArgs, pReturn); + prepareArgs("get_keys", pArgs, pReturn); HashMap qParams = new HashMap(); qParams.put("columns", new String[] { @@ -459,31 +445,31 @@ public class ApgService extends Service { qParams.put("key_type", pArgs.getInt(arg.KEY_TYPE.name())); - Cursor mCursor = get_key_entries(qParams); - ArrayList fprints = new ArrayList(); + Cursor cursor = getKeyEntries(qParams); + ArrayList fPrints = new ArrayList(); ArrayList ids = new ArrayList(); - while (mCursor.moveToNext()) { - if( LOCAL_LOGV ) Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(mCursor.getLong(0))); - fprints.add(Apg.getSmallFingerPrint(mCursor.getLong(0))); - ids.add(mCursor.getString(1)); + while (cursor.moveToNext()) { + if( LOCAL_LOGV ) Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(cursor.getLong(0))); + fPrints.add(Apg.getSmallFingerPrint(cursor.getLong(0))); + ids.add(cursor.getString(1)); } - mCursor.close(); + cursor.close(); - pReturn.putStringArrayList(ret.FINGERPRINTS.name(), fprints); + pReturn.putStringArrayList(ret.FINGERPRINTS.name(), fPrints); pReturn.putStringArrayList(ret.USER_IDS.name(), ids); return true; } - public boolean encrypt_with_public_key(Bundle pArgs, Bundle pReturn) { - if (!prepare_args("encrypt_with_public_key", pArgs, pReturn)) { + public boolean encryptWithPublicKey(Bundle pArgs, Bundle pReturn) { + if (!prepareArgs("encrypt_with_public_key", pArgs, pReturn)) { return false; } return encrypt(pArgs, pReturn); } - public boolean encrypt_with_passphrase(Bundle pArgs, Bundle pReturn) { - if (!prepare_args("encrypt_with_passphrase", pArgs, pReturn)) { + public boolean encryptWithPassphrase(Bundle pArgs, Bundle pReturn) { + if (!prepareArgs("encrypt_with_passphrase", pArgs, pReturn)) { return false; } @@ -492,11 +478,11 @@ public class ApgService extends Service { } public boolean decrypt(Bundle pArgs, Bundle pReturn) { - if (!prepare_args("decrypt", pArgs, pReturn)) { + if (!prepareArgs("decrypt", pArgs, pReturn)) { return false; } - String _passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs + String passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs .getString(arg.PRIVATE_KEY_PASSPHRASE.name()); InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); @@ -504,21 +490,21 @@ public class ApgService extends Service { OutputStream out = new ByteArrayOutputStream(); if( LOCAL_LOGV ) Log.v(TAG, "About to decrypt"); try { - Apg.decrypt(getBaseContext(), in, out, _passphrase, null, // progress + Apg.decrypt(getBaseContext(), in, out, passphrase, null, // progress pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric ); } catch (Exception e) { Log.e(TAG, "Exception in decrypt"); - String _msg = e.getMessage(); - if (_msg.equals(getBaseContext().getString(R.string.error_noSecretKeyFound))) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + _msg); - pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shifted_ordinal()); - } else if (_msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + _msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shifted_ordinal()); + String msg = e.getMessage(); + if (msg.equals(getBaseContext().getString(R.string.error_noSecretKeyFound))) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + msg); + pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shiftedOrdinal()); + } else if (msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + msg); + pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal()); } else { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + _msg); - pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shifted_ordinal()); + pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + msg); + pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shiftedOrdinal()); } return false; } -- cgit v1.2.3 From ad1657465778c05cef7a7ba9d25f97943cf68144 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Fri, 4 Nov 2011 21:22:49 +0100 Subject: Allow to pass large blobs and a new content provider to simplify this Since AIDL is not for passing large data, a blob can be passed to APG by a Uri. This Uri is opened as a file by APG and read/written to. Note the file is overwritten by APG, so make sure it is a copy if you want to keep the original. With the ApgServiceBlobProvider, Apg has an own ContentProvider that can be used like mentioned above. For now the data is stored in the dir where APG stores other files and NOT DELETED after en/decryption. This is tbd. It can only be accessed by an application with the permission "org.thialfihar.android.apg.permission.STORE_BLOBS". ApgCon has been updated accordingly and can handle blobs with `setBlob` and `getBlobResult`. That is a really easy way to en/decrypt large data. Note that encrypting by blob should only be used for large files (1MB+). On all other cases, the data should be passed as as String through the AIDl-Interface, so no temporary file must be created. See ApgCon for a complete example of how to connect to the AIDL and use it. Or use it in your own project! --- src/org/thialfihar/android/apg/ApgService.java | 118 ++++++++++++++++++++----- 1 file changed, 97 insertions(+), 21 deletions(-) (limited to 'src/org/thialfihar/android/apg/ApgService.java') diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java index 0a25c6055..46d8b4765 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/thialfihar/android/apg/ApgService.java @@ -2,6 +2,7 @@ package org.thialfihar.android.apg; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Method; @@ -14,17 +15,19 @@ import org.thialfihar.android.apg.provider.KeyRings; import org.thialfihar.android.apg.provider.Keys; import org.thialfihar.android.apg.provider.UserIds; +import android.content.ContentResolver; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteQueryBuilder; +import android.net.Uri; import android.os.Bundle; import android.os.IBinder; import android.util.Log; public class ApgService extends Service { private final static String TAG = "ApgService"; - private static final boolean LOCAL_LOGV = true; - private static final boolean LOCAL_LOGD = true; + public static final boolean LOCAL_LOGV = true; + public static final boolean LOCAL_LOGD = true; @Override public IBinder onBind(Intent intent) { @@ -33,7 +36,7 @@ public class ApgService extends Service { } /** error status */ - private enum error { + private static enum error { ARGUMENTS_MISSING, APG_FAILURE, NO_MATCHING_SECRET_KEY, @@ -44,9 +47,16 @@ public class ApgService extends Service { return ordinal() + 100; } } + + private static enum call { + encrypt_with_passphrase, + encrypt_with_public_key, + decrypt, + get_keys + } /** all arguments that can be passed by calling application */ - private enum arg { + public static enum arg { MESSAGE, // message to encrypt or to decrypt SYMMETRIC_PASSPHRASE, // key for symmetric en/decryption PUBLIC_KEYS, // public keys for encryption @@ -58,10 +68,11 @@ public class ApgService extends Service { SIGNATURE_KEY, // key for signing PRIVATE_KEY_PASSPHRASE, // passphrase for encrypted private key KEY_TYPE, // type of key (private or public) + BLOB, // blob passed } /** all things that might be returned */ - private enum ret { + private static enum ret { ERRORS, // string array list with errors WARNINGS, // string array list with warnings ERROR, // numeric error @@ -75,21 +86,18 @@ public class ApgService extends Service { static { HashSet args = new HashSet(); args.add(arg.SYMMETRIC_PASSPHRASE); - args.add(arg.MESSAGE); - FUNCTIONS_REQUIRED_ARGS.put("encrypt_with_passphrase", args); + FUNCTIONS_REQUIRED_ARGS.put(call.encrypt_with_passphrase.name(), args); args = new HashSet(); args.add(arg.PUBLIC_KEYS); - args.add(arg.MESSAGE); - FUNCTIONS_REQUIRED_ARGS.put("encrypt_with_public_key", args); + FUNCTIONS_REQUIRED_ARGS.put(call.encrypt_with_public_key.name(), args); args = new HashSet(); - args.add(arg.MESSAGE); - FUNCTIONS_REQUIRED_ARGS.put("decrypt", args); + FUNCTIONS_REQUIRED_ARGS.put(call.decrypt.name(), args); args = new HashSet(); args.add(arg.KEY_TYPE); - FUNCTIONS_REQUIRED_ARGS.put("get_keys", args); + FUNCTIONS_REQUIRED_ARGS.put(call.get_keys.name(), args); } /** optional arguments for each AIDL function */ @@ -103,14 +111,18 @@ public class ApgService extends Service { args.add(arg.COMPRESSION); args.add(arg.PRIVATE_KEY_PASSPHRASE); args.add(arg.SIGNATURE_KEY); - FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_passphrase", args); - FUNCTIONS_OPTIONAL_ARGS.put("encrypt_with_public_key", args); + args.add(arg.BLOB); + args.add(arg.MESSAGE); + FUNCTIONS_OPTIONAL_ARGS.put(call.encrypt_with_passphrase.name(), args); + FUNCTIONS_OPTIONAL_ARGS.put(call.encrypt_with_public_key.name(), args); args = new HashSet(); args.add(arg.SYMMETRIC_PASSPHRASE); args.add(arg.PUBLIC_KEYS); args.add(arg.PRIVATE_KEY_PASSPHRASE); - FUNCTIONS_OPTIONAL_ARGS.put("decrypt", args); + args.add(arg.MESSAGE); + args.add(arg.BLOB); + FUNCTIONS_OPTIONAL_ARGS.put(call.decrypt.name(), args); } /** a map from ApgService parameters to function calls to get the default */ @@ -136,6 +148,14 @@ public class ApgService extends Service { Log.e(TAG, "Function method exception: " + e.getMessage()); } } + + private static void writeToOutputStream(InputStream is, OutputStream os) throws IOException { + byte[] buffer = new byte[8]; + int len = 0; + while( (len = is.read(buffer)) != -1) { + os.write(buffer, 0, len); + } + } private static Cursor getKeyEntries(HashMap pParams) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); @@ -304,6 +324,16 @@ public class ApgService extends Service { } } } + + if(pFunction.equals(call.encrypt_with_passphrase.name()) || + pFunction.equals(call.encrypt_with_public_key.name()) || + pFunction.equals(call.decrypt.name())) { + // check that either MESSAGE or BLOB are there + if( !pArgs.containsKey(arg.MESSAGE.name()) && !pArgs.containsKey(arg.BLOB.name())) { + pReturn.getStringArrayList(ret.ERRORS.name()).add("Arguments missing: Neither MESSAGE nor BLOG found"); + } + + } } /** @@ -378,6 +408,7 @@ public class ApgService extends Service { } private boolean encrypt(Bundle pArgs, Bundle pReturn) { + boolean isBlob = pArgs.containsKey(arg.BLOB.name()); long pubMasterKeys[] = {}; if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) { @@ -391,7 +422,17 @@ public class ApgService extends Service { pubMasterKeys = getMasterKey(pubKeys, pReturn); } - InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); + InputStream inStream = null; + if(isBlob) { + ContentResolver cr = getContentResolver(); + try { + inStream = cr.openInputStream(Uri.parse(pArgs.getString(arg.BLOB.name()))); + } catch (Exception e) { + Log.e(TAG, "... exception on opening blob", e); + } + } else { + inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); + } InputData in = new InputData(inStream, 0); // XXX Size second param? OutputStream out = new ByteArrayOutputStream(); @@ -427,7 +468,18 @@ public class ApgService extends Service { return false; } if( LOCAL_LOGV ) Log.v(TAG, "Encrypted"); - pReturn.putString(ret.RESULT.name(), out.toString()); + if(isBlob) { + ContentResolver cr = getContentResolver(); + try { + OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB.name()))); + writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()), outStream); + outStream.close(); + } catch (Exception e) { + Log.e(TAG, "... exception on writing blob", e); + } + } else { + pReturn.putString(ret.RESULT.name(), out.toString()); + } return true; } @@ -481,11 +533,24 @@ public class ApgService extends Service { if (!prepareArgs("decrypt", pArgs, pReturn)) { return false; } + + boolean isBlob = pArgs.containsKey(arg.BLOB.name()); String passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs .getString(arg.PRIVATE_KEY_PASSPHRASE.name()); - InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); + InputStream inStream = null; + if(isBlob) { + ContentResolver cr = getContentResolver(); + try { + inStream = cr.openInputStream(Uri.parse(pArgs.getString(arg.BLOB.name()))); + } catch (Exception e) { + Log.e(TAG, "... exception on opening blob", e); + } + } else { + inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); + } + InputData in = new InputData(inStream, 0); // XXX what size in second parameter? OutputStream out = new ByteArrayOutputStream(); if( LOCAL_LOGV ) Log.v(TAG, "About to decrypt"); @@ -508,9 +573,20 @@ public class ApgService extends Service { } return false; } - if( LOCAL_LOGV ) Log.v(TAG, "Decrypted"); - - pReturn.putString(ret.RESULT.name(), out.toString()); + if( LOCAL_LOGV ) Log.v(TAG, "... decrypted"); + + if(isBlob) { + ContentResolver cr = getContentResolver(); + try { + OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB.name()))); + writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()), outStream); + outStream.close(); + } catch (Exception e) { + Log.e(TAG, "... exception on writing blob", e); + } + } else { + pReturn.putString(ret.RESULT.name(), out.toString()); + } return true; } -- cgit v1.2.3