aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/org/thialfihar/android/apg/ApgService.java270
1 files changed, 168 insertions, 102 deletions
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<String, Set<arg>> FUNCTIONS_REQUIRED_ARGS = new HashMap<String, Set<arg>>();
+ static {
+ HashSet<arg> args = new HashSet<arg>();
+ 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<arg>();
+ 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<String, Set<arg>> FUNCTIONS_OPTIONAL_ARGS = new HashMap<String, Set<arg>>();
+ static {
+ HashSet<arg> args = new HashSet<arg>();
+ 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<String, String> FUNCTIONS_DEFAULTS = new HashMap<String, String>();
+ private static final HashMap<arg, String> FUNCTIONS_DEFAULTS = new HashMap<arg, String>();
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<String, Class> FUNCTIONS_DEFAULTS_TYPES = new HashMap<String, Class>();
+ private static final HashMap<String, Class<?>> FUNCTIONS_DEFAULTS_TYPES = new HashMap<String, Class<?>>();
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<String, Method> FUNCTIONS_DEFAULTS_METHODS = new HashMap<String, Method>();
+ private static final HashMap<String, Method> FUNCTIONS_DEFAULTS_METHODS = new HashMap<String, Method>();
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<String> _iter = FUNCTIONS_DEFAULTS.keySet().iterator();
+ Iterator<arg> _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<String> errors = new ArrayList<String>();
- ArrayList<String> warnings = new ArrayList<String>();
-
- 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<String> errors = new ArrayList<String>();
+ ArrayList<String> warnings = new ArrayList<String>();
- /* 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<arg> _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<arg> all_args = new HashSet<arg>(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<String> _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<String> _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<String> errors = new ArrayList<String>();
- ArrayList<String> warnings = new ArrayList<String>();
-
- 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<String> 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;
}
};