Merge pull request #1980 from open-keychain/fix-duplicate-keys

fix loop bug in key selection
This commit is contained in:
Dominik Schürmann
2017-01-05 17:10:34 +01:00
committed by GitHub
4 changed files with 33 additions and 29 deletions

View File

@@ -131,49 +131,51 @@ public class OpenPgpService extends Service {
}
private KeyIdResult returnKeyIdsFromEmails(Intent data, String[] encryptionUserIds, boolean isOpportunistic) {
boolean noUserIdsCheck = (encryptionUserIds == null || encryptionUserIds.length == 0);
boolean missingUserIdsCheck = false;
boolean duplicateUserIdsCheck = false;
boolean hasUserIds = (encryptionUserIds != null && encryptionUserIds.length > 0);
HashSet<Long> keyIds = new HashSet<>();
ArrayList<String> missingEmails = new ArrayList<>();
ArrayList<String> duplicateEmails = new ArrayList<>();
if (!noUserIdsCheck) {
if (hasUserIds) {
for (String rawUserId : encryptionUserIds) {
OpenPgpUtils.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, KEY_SEARCH_PROJECTION, KEY_SEARCH_WHERE, null, null);
if (cursor == null) {
throw new IllegalStateException("Internal error, received null cursor!");
}
try {
// result should be one entry containing the key id
if (cursor != null && cursor.moveToFirst()) {
if (cursor.moveToFirst()) {
long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
keyIds.add(id);
// another entry for this email -> two keys with the same email inside user id
if (!cursor.isLast()) {
Log.d(Constants.TAG, "more than one user id with the same email");
duplicateEmails.add(email);
// also pre-select
while (cursor.moveToNext()) {
long duplicateId = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
keyIds.add(duplicateId);
}
}
} else {
missingUserIdsCheck = true;
missingEmails.add(email);
Log.d(Constants.TAG, "user id missing");
}
// another entry for this email -> two keys with the same email inside user id
if (cursor != null && cursor.moveToNext()) {
duplicateUserIdsCheck = true;
duplicateEmails.add(email);
// also pre-select
long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
keyIds.add(id);
Log.d(Constants.TAG, "more than one user id with the same email");
}
} finally {
if (cursor != null) {
cursor.close();
}
cursor.close();
}
}
}
if (isOpportunistic && (noUserIdsCheck || missingUserIdsCheck)) {
boolean hasMissingUserIds = !missingEmails.isEmpty();
boolean hasDuplicateUserIds = !duplicateEmails.isEmpty();
if (isOpportunistic && (!hasUserIds || hasMissingUserIds)) {
Intent result = new Intent();
result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.OPPORTUNISTIC_MISSING_KEYS, "missing keys in opportunistic mode"));
@@ -181,12 +183,12 @@ public class OpenPgpService extends Service {
return new KeyIdResult(result);
}
if (noUserIdsCheck || missingUserIdsCheck || duplicateUserIdsCheck) {
if (!hasUserIds || hasMissingUserIds || hasDuplicateUserIds) {
// convert ArrayList<Long> to long[]
long[] keyIdsArray = getUnboxedLongArray(keyIds);
ApiPendingIntentFactory piFactory = new ApiPendingIntentFactory(getBaseContext());
PendingIntent pi = piFactory.createSelectPublicKeyPendingIntent(data, keyIdsArray,
missingEmails, duplicateEmails, noUserIdsCheck);
missingEmails, duplicateEmails, hasUserIds);
// return PendingIntent to be executed by client
Intent result = new Intent();
@@ -197,7 +199,7 @@ public class OpenPgpService extends Service {
// everything was easy, we have exactly one key for every email
if (keyIds.isEmpty()) {
Log.e(Constants.TAG, "keyIdsArray.length == 0, should never happen!");
throw new AssertionError("keyIdsArray.length == 0, should never happen!");
}
return new KeyIdResult(keyIds);
@@ -321,9 +323,12 @@ public class OpenPgpService extends Service {
long[] keyIds;
{
HashSet<Long> encryptKeyIds = new HashSet<>();
// get key ids based on given user ids
if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) {
boolean hasKeysFromSelectPubkeyActivity = data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS_SELECTED);
if (hasKeysFromSelectPubkeyActivity) {
for (long keyId : data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS_SELECTED)) {
encryptKeyIds.add(keyId);
}
} else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) {
String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
boolean isOpportunistic = data.getBooleanExtra(OpenPgpApi.EXTRA_OPPORTUNISTIC_ENCRYPTION, false);
// give params through to activity...

View File

@@ -103,7 +103,7 @@ public class RemoteSelectPubKeyActivity extends BaseActivity {
public void onClick(View v) {
// add key ids to params Bundle for new request
Intent resultData = extras.getParcelable(EXTRA_DATA);
resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS,
resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS_SELECTED,
mSelectFragment.getSelectedMasterKeyIds());
RemoteSelectPubKeyActivity.this.setResult(RESULT_OK, resultData);

View File

@@ -24,7 +24,6 @@ import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;