mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-30 12:32:17 -05:00
Allow to retrieve fingerprints and user ids through AIDL
Update ApgCon and doc accordingly. Not very tested.
This commit is contained in:
parent
6b7db8161a
commit
1ec5fc0541
@ -9,7 +9,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.thialfihar.android.apg.provider.KeyRings;
|
import org.thialfihar.android.apg.provider.KeyRings;
|
||||||
import org.thialfihar.android.apg.provider.Keys;
|
import org.thialfihar.android.apg.provider.Keys;
|
||||||
@ -55,8 +54,8 @@ public class ApgService extends Service {
|
|||||||
FORCE_V3_SIGNATURE, // whether to force v3 signature
|
FORCE_V3_SIGNATURE, // 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
|
SIGNATURE_KEY, // key for signing
|
||||||
PRIVATE_KEY_PASSPHRASE
|
PRIVATE_KEY_PASSPHRASE, // passphrase for encrypted private key
|
||||||
// passphrase for encrypted private key
|
KEY_TYPE, // type of key (private or public)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** all things that might be returned */
|
/** all things that might be returned */
|
||||||
@ -64,12 +63,13 @@ public class ApgService extends Service {
|
|||||||
ERRORS, // string array list with errors
|
ERRORS, // string array list with errors
|
||||||
WARNINGS, // string array list with warnings
|
WARNINGS, // string array list with warnings
|
||||||
ERROR, // numeric error
|
ERROR, // numeric error
|
||||||
RESULT
|
RESULT, // en-/decrypted
|
||||||
// en-/decrypted
|
FINGERPRINTS, // fingerprints of keys
|
||||||
|
USER_IDS, // user ids
|
||||||
}
|
}
|
||||||
|
|
||||||
/** required arguments for each AIDL function */
|
/** required arguments for each AIDL function */
|
||||||
private static final HashMap<String, Set<arg>> FUNCTIONS_REQUIRED_ARGS = new HashMap<String, Set<arg>>();
|
private static final HashMap<String, HashSet<arg>> FUNCTIONS_REQUIRED_ARGS = new HashMap<String, HashSet<arg>>();
|
||||||
static {
|
static {
|
||||||
HashSet<arg> args = new HashSet<arg>();
|
HashSet<arg> args = new HashSet<arg>();
|
||||||
args.add(arg.SYMMETRIC_PASSPHRASE);
|
args.add(arg.SYMMETRIC_PASSPHRASE);
|
||||||
@ -85,10 +85,14 @@ public class ApgService extends Service {
|
|||||||
args.add(arg.MESSAGE);
|
args.add(arg.MESSAGE);
|
||||||
FUNCTIONS_REQUIRED_ARGS.put("decrypt", args);
|
FUNCTIONS_REQUIRED_ARGS.put("decrypt", args);
|
||||||
|
|
||||||
|
args = new HashSet<arg>();
|
||||||
|
args.add(arg.KEY_TYPE);
|
||||||
|
FUNCTIONS_REQUIRED_ARGS.put("get_keys", args);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** optional arguments for each AIDL function */
|
/** optional arguments for each AIDL function */
|
||||||
private static final HashMap<String, Set<arg>> FUNCTIONS_OPTIONAL_ARGS = new HashMap<String, Set<arg>>();
|
private static final HashMap<String, HashSet<arg>> FUNCTIONS_OPTIONAL_ARGS = new HashMap<String, HashSet<arg>>();
|
||||||
static {
|
static {
|
||||||
HashSet<arg> args = new HashSet<arg>();
|
HashSet<arg> args = new HashSet<arg>();
|
||||||
args.add(arg.ENCRYPTION_ALGORYTHM);
|
args.add(arg.ENCRYPTION_ALGORYTHM);
|
||||||
@ -166,6 +170,26 @@ public class ApgService extends Service {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Cursor get_key_entries(HashMap<String, Object> 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
|
* 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<String> search_keys, Bundle pReturn) {
|
private static long[] get_master_key(ArrayList<String> search_keys, Bundle pReturn) {
|
||||||
|
|
||||||
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
HashMap<String, Object> qParams = new HashMap<String, Object>();
|
||||||
qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME
|
qParams.put("columns", new String[] {
|
||||||
+ "." + 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[] {
|
|
||||||
KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0
|
KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0
|
||||||
UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1
|
UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1
|
||||||
}, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] {
|
});
|
||||||
"" + Id.database.type_public
|
qParams.put("key_type", Id.database.type_public);
|
||||||
}, null, null, orderBy);
|
|
||||||
|
Cursor mCursor = get_key_entries(qParams);
|
||||||
|
|
||||||
Log.v(TAG, "going through installed user keys");
|
Log.v(TAG, "going through installed user keys");
|
||||||
ArrayList<Long> _master_keys = new ArrayList<Long>();
|
ArrayList<Long> _master_keys = new ArrayList<Long>();
|
||||||
@ -235,6 +253,8 @@ public class ApgService extends Service {
|
|||||||
* the bundle to add default parameters to if missing
|
* the bundle to add default parameters to if missing
|
||||||
*/
|
*/
|
||||||
private void add_default_arguments(String call, Bundle args) {
|
private void add_default_arguments(String call, Bundle args) {
|
||||||
|
// check whether there are optional elements defined for that call
|
||||||
|
if (FUNCTIONS_OPTIONAL_ARGS.containsKey(call)) {
|
||||||
Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true);
|
Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true);
|
||||||
|
|
||||||
Iterator<arg> _iter = FUNCTIONS_DEFAULTS.keySet().iterator();
|
Iterator<arg> _iter = FUNCTIONS_DEFAULTS.keySet().iterator();
|
||||||
@ -260,6 +280,7 @@ public class ApgService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates a Bundle with default return values
|
* updates a Bundle with default return values
|
||||||
@ -286,6 +307,7 @@ public class ApgService extends Service {
|
|||||||
* the bundle to write errors to
|
* the bundle to write errors to
|
||||||
*/
|
*/
|
||||||
private void check_required_args(String function, Bundle pArgs, Bundle pReturn) {
|
private void check_required_args(String function, Bundle pArgs, Bundle pReturn) {
|
||||||
|
if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) {
|
||||||
Iterator<arg> _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator();
|
Iterator<arg> _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator();
|
||||||
while (_iter.hasNext()) {
|
while (_iter.hasNext()) {
|
||||||
String _cur_arg = _iter.next().name();
|
String _cur_arg = _iter.next().name();
|
||||||
@ -294,6 +316,7 @@ public class ApgService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks for unknown arguments and add them to warning if found
|
* checks for unknown arguments and add them to warning if found
|
||||||
@ -306,8 +329,14 @@ public class ApgService extends Service {
|
|||||||
* the bundle to write warnings to
|
* the bundle to write warnings to
|
||||||
*/
|
*/
|
||||||
private void check_unknown_args(String function, Bundle pArgs, Bundle pReturn) {
|
private void check_unknown_args(String function, Bundle pArgs, Bundle pReturn) {
|
||||||
HashSet<arg> all_args = new HashSet<arg>(FUNCTIONS_REQUIRED_ARGS.get(function));
|
|
||||||
|
HashSet<arg> all_args = new HashSet<arg>();
|
||||||
|
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));
|
all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function));
|
||||||
|
}
|
||||||
|
|
||||||
ArrayList<String> _unknown_args = new ArrayList<String>();
|
ArrayList<String> _unknown_args = new ArrayList<String>();
|
||||||
Iterator<String> _iter = pArgs.keySet().iterator();
|
Iterator<String> _iter = pArgs.keySet().iterator();
|
||||||
@ -415,6 +444,32 @@ public class ApgService extends Service {
|
|||||||
|
|
||||||
private final IApgService.Stub mBinder = new IApgService.Stub() {
|
private final IApgService.Stub mBinder = new IApgService.Stub() {
|
||||||
|
|
||||||
|
public boolean get_keys(Bundle pArgs, Bundle pReturn) {
|
||||||
|
|
||||||
|
prepare_args("get_keys", pArgs, pReturn);
|
||||||
|
|
||||||
|
HashMap<String, Object> qParams = new HashMap<String, Object>();
|
||||||
|
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<String> fprints = new ArrayList<String>();
|
||||||
|
ArrayList<String> ids = new ArrayList<String>();
|
||||||
|
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) {
|
public boolean encrypt_with_public_key(Bundle pArgs, Bundle pReturn) {
|
||||||
if (!prepare_args("encrypt_with_public_key", pArgs, pReturn)) {
|
if (!prepare_args("encrypt_with_public_key", pArgs, pReturn)) {
|
||||||
return false;
|
return false;
|
||||||
@ -468,5 +523,6 @@ public class ApgService extends Service {
|
|||||||
pReturn.putString(ret.RESULT.name(), out.toString());
|
pReturn.putString(ret.RESULT.name(), out.toString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,12 @@ interface IApgService {
|
|||||||
* 104: Private key's passphrase missing
|
* 104: Private key's passphrase missing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Encryption function's arguments
|
/* *******************************************************
|
||||||
|
* Encrypting and decrypting
|
||||||
|
* ********************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* All encryption function's arguments
|
||||||
*
|
*
|
||||||
* Bundle params' keys:
|
* Bundle params' keys:
|
||||||
* (optional/required)
|
* (optional/required)
|
||||||
@ -82,5 +87,27 @@ interface IApgService {
|
|||||||
* Bundle return_vals:
|
* Bundle return_vals:
|
||||||
* String "RESULT" = Decrypted message
|
* String "RESULT" = Decrypted message
|
||||||
*/
|
*/
|
||||||
|
|
||||||
boolean decrypt(in Bundle params, out Bundle return_vals);
|
boolean decrypt(in Bundle params, out Bundle return_vals);
|
||||||
|
|
||||||
|
|
||||||
|
/* *******************************************************
|
||||||
|
* Get key information
|
||||||
|
* ********************************************************/
|
||||||
|
|
||||||
|
/* Get info about all available keys
|
||||||
|
*
|
||||||
|
* Bundle params:
|
||||||
|
* (required)
|
||||||
|
* int "KEY_TYPE" = info about what type of keys to return
|
||||||
|
* 0: public keys
|
||||||
|
* 1: private keys
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* StringArrayList "FINGERPRINTS" = Short fingerprints of keys
|
||||||
|
*
|
||||||
|
* StringArrayList "USER_IDS" = User ids of corrosponding fingerprints (order is the same)
|
||||||
|
*/
|
||||||
|
boolean get_keys(in Bundle params, out Bundle return_vals);
|
||||||
|
|
||||||
}
|
}
|
@ -327,6 +327,10 @@ public class ApgCon {
|
|||||||
new call_async().execute(function);
|
new call_async().execute(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean call(String function, Bundle pReturn) {
|
||||||
|
return call(function, args, pReturn);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean call(String function, Bundle pArgs, Bundle pReturn) {
|
private boolean call(String function, Bundle pArgs, Bundle pReturn) {
|
||||||
|
|
||||||
if (!initialize()) {
|
if (!initialize()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user