wip
This commit is contained in:
parent
31b27e59ee
commit
6a853f4c84
|
@ -18,6 +18,17 @@
|
|||
|
||||
package org.sufficientlysecure.keychain.remote;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
|
@ -42,6 +53,8 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
|||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
|
||||
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing.UserId;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants;
|
||||
|
@ -60,18 +73,9 @@ import org.sufficientlysecure.keychain.util.InputData;
|
|||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class OpenPgpService extends Service {
|
||||
|
||||
static final String[] EMAIL_SEARCH_PROJECTION = new String[]{
|
||||
static final String[] KEY_SEARCH_PROJECTION = new String[]{
|
||||
KeyRings._ID,
|
||||
KeyRings.MASTER_KEY_ID,
|
||||
KeyRings.IS_EXPIRED,
|
||||
|
@ -79,7 +83,7 @@ public class OpenPgpService extends Service {
|
|||
};
|
||||
|
||||
// do not pre-select revoked or expired keys
|
||||
static final String EMAIL_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED
|
||||
static final String KEY_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED
|
||||
+ " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0";
|
||||
|
||||
private ApiPermissionHelper mApiPermissionHelper;
|
||||
|
@ -94,22 +98,35 @@ public class OpenPgpService extends Service {
|
|||
mApiDao = new ApiDataAccessObject(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search database for key ids based on emails.
|
||||
*/
|
||||
private Intent returnKeyIdsFromEmails(Intent data, String[] encryptionUserIds) {
|
||||
private static class KeyIdResult {
|
||||
final Intent mRequiredUserInteraction;
|
||||
final HashSet<Long> mKeyIds;
|
||||
|
||||
KeyIdResult(Intent requiredUserInteraction) {
|
||||
mRequiredUserInteraction = requiredUserInteraction;
|
||||
mKeyIds = null;
|
||||
}
|
||||
KeyIdResult(HashSet<Long> keyIds) {
|
||||
mRequiredUserInteraction = null;
|
||||
mKeyIds = keyIds;
|
||||
}
|
||||
}
|
||||
|
||||
private KeyIdResult returnKeyIdsFromEmails(Intent data, String[] encryptionUserIds) {
|
||||
boolean noUserIdsCheck = (encryptionUserIds == null || encryptionUserIds.length == 0);
|
||||
boolean missingUserIdsCheck = false;
|
||||
boolean duplicateUserIdsCheck = false;
|
||||
|
||||
ArrayList<Long> keyIds = new ArrayList<>();
|
||||
HashSet<Long> keyIds = new HashSet<>();
|
||||
ArrayList<String> missingEmails = new ArrayList<>();
|
||||
ArrayList<String> duplicateEmails = new ArrayList<>();
|
||||
if (!noUserIdsCheck) {
|
||||
for (String email : encryptionUserIds) {
|
||||
for (String rawUserId : encryptionUserIds) {
|
||||
UserId userId = KeyRing.splitUserId(rawUserId);
|
||||
String email = userId.email != null ? userId.email : rawUserId;
|
||||
// try to find the key for this specific email
|
||||
Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email);
|
||||
Cursor cursor = getContentResolver().query(uri, EMAIL_SEARCH_PROJECTION, EMAIL_SEARCH_WHERE, null, null);
|
||||
Cursor cursor = getContentResolver().query(uri, KEY_SEARCH_PROJECTION, KEY_SEARCH_WHERE, null, null);
|
||||
try {
|
||||
// result should be one entry containing the key id
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
|
@ -138,15 +155,11 @@ public class OpenPgpService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
// convert ArrayList<Long> to long[]
|
||||
long[] keyIdsArray = new long[keyIds.size()];
|
||||
for (int i = 0; i < keyIdsArray.length; i++) {
|
||||
keyIdsArray[i] = keyIds.get(i);
|
||||
}
|
||||
|
||||
if (noUserIdsCheck || missingUserIdsCheck || duplicateUserIdsCheck) {
|
||||
// allow the user to verify pub key selection
|
||||
|
||||
// convert ArrayList<Long> to long[]
|
||||
long[] keyIdsArray = getUnboxedLongArray(keyIds);
|
||||
ApiPendingIntentFactory piFactory = new ApiPendingIntentFactory(getBaseContext());
|
||||
PendingIntent pi = piFactory.createSelectPublicKeyPendingIntent(data, keyIdsArray,
|
||||
missingEmails, duplicateEmails, noUserIdsCheck);
|
||||
|
@ -155,18 +168,15 @@ public class OpenPgpService extends Service {
|
|||
Intent result = new Intent();
|
||||
result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
|
||||
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
|
||||
return result;
|
||||
return new KeyIdResult(result);
|
||||
} else {
|
||||
// everything was easy, we have exactly one key for every email
|
||||
|
||||
if (keyIdsArray.length == 0) {
|
||||
if (keyIds.isEmpty()) {
|
||||
Log.e(Constants.TAG, "keyIdsArray.length == 0, should never happen!");
|
||||
}
|
||||
|
||||
Intent result = new Intent();
|
||||
result.putExtra(OpenPgpApi.RESULT_KEY_IDS, keyIdsArray);
|
||||
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
|
||||
return result;
|
||||
return new KeyIdResult(keyIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,20 +291,31 @@ public class OpenPgpService extends Service {
|
|||
compressionId = PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED;
|
||||
}
|
||||
|
||||
// first try to get key ids from non-ambiguous key id extra
|
||||
long[] keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
|
||||
if (keyIds == null) {
|
||||
// get key ids based on given user ids
|
||||
String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
|
||||
// give params through to activity...
|
||||
Intent result = returnKeyIdsFromEmails(data, userIds);
|
||||
long[] keyIds;
|
||||
{
|
||||
HashSet<Long> encryptKeyIds = new HashSet<>();
|
||||
|
||||
if (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0) == OpenPgpApi.RESULT_CODE_SUCCESS) {
|
||||
keyIds = result.getLongArrayExtra(OpenPgpApi.RESULT_KEY_IDS);
|
||||
} else {
|
||||
// if not success -> result contains a PendingIntent for user interaction
|
||||
return result;
|
||||
// get key ids based on given user ids
|
||||
if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) {
|
||||
String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
|
||||
data.removeExtra(OpenPgpApi.EXTRA_USER_IDS);
|
||||
// give params through to activity...
|
||||
KeyIdResult result = returnKeyIdsFromEmails(data, userIds);
|
||||
|
||||
if (result.mRequiredUserInteraction != null) {
|
||||
return result.mRequiredUserInteraction;
|
||||
}
|
||||
encryptKeyIds.addAll(result.mKeyIds);
|
||||
}
|
||||
|
||||
// add key ids from non-ambiguous key id extra
|
||||
if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) {
|
||||
for (long keyId : data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS)) {
|
||||
encryptKeyIds.add(keyId);
|
||||
}
|
||||
}
|
||||
|
||||
keyIds = getUnboxedLongArray(encryptKeyIds);
|
||||
}
|
||||
|
||||
// TODO this is not correct!
|
||||
|
@ -670,10 +691,35 @@ public class OpenPgpService extends Service {
|
|||
} else {
|
||||
// get key ids based on given user ids
|
||||
String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
|
||||
return returnKeyIdsFromEmails(data, userIds);
|
||||
data.removeExtra(OpenPgpApi.EXTRA_USER_IDS);
|
||||
KeyIdResult keyResult = returnKeyIdsFromEmails(data, userIds);
|
||||
if (keyResult.mRequiredUserInteraction != null) {
|
||||
return keyResult.mRequiredUserInteraction;
|
||||
}
|
||||
|
||||
if (keyResult.mKeyIds == null) {
|
||||
throw new AssertionError("one of requiredUserInteraction and keyIds must be non-null, this is a bug!");
|
||||
}
|
||||
|
||||
long[] keyIds = getUnboxedLongArray(keyResult.mKeyIds);
|
||||
|
||||
Intent resultIntent = new Intent();
|
||||
resultIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
|
||||
resultIntent.putExtra(OpenPgpApi.RESULT_KEY_IDS, keyIds);
|
||||
return resultIntent;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static long[] getUnboxedLongArray(@NonNull Collection<Long> arrayList) {
|
||||
long[] result = new long[arrayList.size()];
|
||||
int i = 0;
|
||||
for (Long e : arrayList) {
|
||||
result[i++] = e;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Intent checkPermissionImpl(@NonNull Intent data) {
|
||||
Intent permissionIntent = mApiPermissionHelper.isAllowedOrReturnIntent(data);
|
||||
if (permissionIntent != null) {
|
||||
|
|
Loading…
Reference in a new issue