combine autocrypt peer state and hand to client app
This commit is contained in:
@@ -75,6 +75,7 @@ import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.OverriddenWarningsRepository;
|
||||
import org.sufficientlysecure.keychain.remote.OpenPgpServiceKeyIdExtractor.AutocryptState;
|
||||
import org.sufficientlysecure.keychain.remote.OpenPgpServiceKeyIdExtractor.KeyIdResult;
|
||||
import org.sufficientlysecure.keychain.remote.OpenPgpServiceKeyIdExtractor.KeyIdResultStatus;
|
||||
import org.sufficientlysecure.keychain.service.BackupKeyringParcel;
|
||||
@@ -306,24 +307,27 @@ public class OpenPgpService extends Service {
|
||||
Intent result = new Intent();
|
||||
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
|
||||
|
||||
switch (keyIdResult.getStatus()) {
|
||||
case MISSING: {
|
||||
result.putExtra(OpenPgpApi.RESULT_AUTOCRYPT_STATUS, OpenPgpApi.AUTOCRYPT_STATUS_UNAVAILABLE);
|
||||
break;
|
||||
}
|
||||
case NO_KEYS:
|
||||
case NO_KEYS_ERROR: {
|
||||
result.putExtra(OpenPgpApi.RESULT_AUTOCRYPT_STATUS, OpenPgpApi.AUTOCRYPT_STATUS_UNAVAILABLE);
|
||||
break;
|
||||
}
|
||||
case DUPLICATE: {
|
||||
AutocryptState combinedAutocryptState = keyIdResult.getCombinedAutocryptState();
|
||||
if (combinedAutocryptState == null) {
|
||||
result.putExtra(OpenPgpApi.RESULT_AUTOCRYPT_STATUS, OpenPgpApi.AUTOCRYPT_STATUS_UNAVAILABLE);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
switch (combinedAutocryptState) {
|
||||
case GOSSIP:
|
||||
case RESET: {
|
||||
result.putExtra(OpenPgpApi.RESULT_AUTOCRYPT_STATUS, OpenPgpApi.AUTOCRYPT_STATUS_DISCOURAGE);
|
||||
break;
|
||||
}
|
||||
case OK: {
|
||||
case AVAILABLE: {
|
||||
result.putExtra(OpenPgpApi.RESULT_AUTOCRYPT_STATUS, OpenPgpApi.AUTOCRYPT_STATUS_AVAILABLE);
|
||||
break;
|
||||
}
|
||||
case MUTUAL: {
|
||||
result.putExtra(OpenPgpApi.RESULT_AUTOCRYPT_STATUS, OpenPgpApi.AUTOCRYPT_STATUS_RECOMMEND);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new IllegalStateException("unhandled case!");
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import org.openintents.openpgp.util.OpenPgpApi;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainExternalContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAutocryptPeer;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainExternalContract.EmailStatus;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
@@ -65,7 +65,7 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
for (long keyId : data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS_SELECTED)) {
|
||||
encryptKeyIds.add(keyId);
|
||||
}
|
||||
result = createKeysOkResult(encryptKeyIds, false);
|
||||
result = createKeysOkResult(encryptKeyIds, false, null);
|
||||
} else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS) || askIfNoUserIdsProvided) {
|
||||
String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
|
||||
result = returnKeyIdsFromEmails(data, userIds, callingPackageName);
|
||||
@@ -92,6 +92,7 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
HashSet<Long> keyIds = new HashSet<>();
|
||||
ArrayList<String> missingEmails = new ArrayList<>();
|
||||
ArrayList<String> duplicateEmails = new ArrayList<>();
|
||||
AutocryptState combinedAutocryptState = null;
|
||||
|
||||
if (hasAddresses) {
|
||||
HashMap<String, AddressQueryResult> userIdEntries = getStatusMapForQueriedAddresses(
|
||||
@@ -104,20 +105,37 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
throw new IllegalStateException("No result for address - shouldn't happen!");
|
||||
}
|
||||
|
||||
if (addressQueryResult.autocryptMasterKeyId != null) {
|
||||
keyIds.add(addressQueryResult.autocryptMasterKeyId);
|
||||
|
||||
if (addressQueryResult.autocryptKeyStatus != EmailStatus.KEY_STATUS_VERIFIED) {
|
||||
anyKeyNotVerified = true;
|
||||
}
|
||||
|
||||
if (combinedAutocryptState == null) {
|
||||
combinedAutocryptState = addressQueryResult.autocryptState;
|
||||
} else {
|
||||
combinedAutocryptState = combinedAutocryptState.combineWith(addressQueryResult.autocryptState);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addressQueryResult.uidMasterKeyId != null) {
|
||||
keyIds.add(addressQueryResult.uidMasterKeyId);
|
||||
|
||||
if (addressQueryResult.uidHasMultipleCandidates) {
|
||||
duplicateEmails.add(queriedAddress);
|
||||
}
|
||||
} else {
|
||||
missingEmails.add(queriedAddress);
|
||||
|
||||
if (addressQueryResult.uidKeyStatus != EmailStatus.KEY_STATUS_VERIFIED) {
|
||||
anyKeyNotVerified = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addressQueryResult.uidKeyStatus != EmailStatus.KEY_STATUS_VERIFIED) {
|
||||
anyKeyNotVerified = true;
|
||||
}
|
||||
missingEmails.add(queriedAddress);
|
||||
}
|
||||
|
||||
if (userIdEntries.size() != encryptionAddresses.length) {
|
||||
@@ -139,7 +157,7 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
return createNoKeysResult(data, keyIds, missingEmails, duplicateEmails);
|
||||
}
|
||||
|
||||
return createKeysOkResult(keyIds, allKeysConfirmed);
|
||||
return createKeysOkResult(keyIds, allKeysConfirmed, combinedAutocryptState);
|
||||
}
|
||||
|
||||
/** This method queries the KeychainExternalProvider for all addresses given in encryptionUserIds.
|
||||
@@ -169,9 +187,9 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
int autocryptKeyStatus = cursor.getInt(INDEX_AUTOCRYPT_KEY_STATUS);
|
||||
int autocryptPeerStatus = cursor.getInt(INDEX_AUTOCRYPT_PEER_STATE);
|
||||
|
||||
AddressQueryResult
|
||||
status = new AddressQueryResult(uidMasterKeyId, uidKeyStatus, uidHasMultipleCandidates,
|
||||
autocryptMasterKeyId, autocryptKeyStatus, autocryptPeerStatus);
|
||||
AddressQueryResult status = new AddressQueryResult(
|
||||
uidMasterKeyId, uidKeyStatus, uidHasMultipleCandidates, autocryptMasterKeyId,
|
||||
autocryptKeyStatus, AutocryptState.fromDbValue(autocryptPeerStatus));
|
||||
|
||||
keyRows.put(queryAddress, status);
|
||||
}
|
||||
@@ -187,11 +205,10 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
private boolean uidHasMultipleCandidates;
|
||||
private final Long autocryptMasterKeyId;
|
||||
private final int autocryptKeyStatus;
|
||||
private final int autocryptState;
|
||||
private final AutocryptState autocryptState;
|
||||
|
||||
AddressQueryResult(Long uidMasterKeyId, int uidKeyStatus, boolean uidHasMultipleCandidates, Long autocryptMasterKeyId,
|
||||
int autocryptKeyStatus,
|
||||
int autocryptState) {
|
||||
int autocryptKeyStatus, AutocryptState autocryptState) {
|
||||
this.uidMasterKeyId = uidMasterKeyId;
|
||||
this.uidKeyStatus = uidKeyStatus;
|
||||
this.uidHasMultipleCandidates = uidHasMultipleCandidates;
|
||||
@@ -202,7 +219,38 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
}
|
||||
|
||||
enum AutocryptState {
|
||||
UNAVAILABLE, DISCOURAGE, AVAILABLE, MUTUAL
|
||||
RESET, GOSSIP, AVAILABLE, MUTUAL;
|
||||
|
||||
static AutocryptState fromDbValue(int state) {
|
||||
switch (state) {
|
||||
case ApiAutocryptPeer.RESET:
|
||||
return RESET;
|
||||
case ApiAutocryptPeer.AVAILABLE:
|
||||
return AVAILABLE;
|
||||
case ApiAutocryptPeer.GOSSIP:
|
||||
return GOSSIP;
|
||||
case ApiAutocryptPeer.MUTUAL:
|
||||
return MUTUAL;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
public AutocryptState combineWith(AutocryptState other) {
|
||||
if (this == RESET || other == RESET) {
|
||||
return RESET;
|
||||
}
|
||||
if (this == GOSSIP || other == GOSSIP) {
|
||||
return GOSSIP;
|
||||
}
|
||||
if (this == AVAILABLE || other == AVAILABLE) {
|
||||
return AVAILABLE;
|
||||
}
|
||||
if (this == MUTUAL && other == MUTUAL) {
|
||||
return MUTUAL;
|
||||
}
|
||||
throw new IllegalStateException("Bug: autocrypt states can't be combined!");
|
||||
}
|
||||
}
|
||||
|
||||
static class KeyIdResult {
|
||||
@@ -211,6 +259,7 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
private final HashSet<Long> mExplicitKeyIds;
|
||||
private final KeyIdResultStatus mStatus;
|
||||
private final boolean mAllKeysConfirmed;
|
||||
private final AutocryptState mCombinedAutocryptState;
|
||||
|
||||
private KeyIdResult(PendingIntent keySelectionPendingIntent, KeyIdResultStatus keyIdResultStatus) {
|
||||
mKeySelectionPendingIntent = keySelectionPendingIntent;
|
||||
@@ -218,13 +267,17 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
mAllKeysConfirmed = false;
|
||||
mStatus = keyIdResultStatus;
|
||||
mExplicitKeyIds = null;
|
||||
mCombinedAutocryptState = null;
|
||||
}
|
||||
private KeyIdResult(HashSet<Long> keyIds, boolean allKeysConfirmed, KeyIdResultStatus keyIdResultStatus) {
|
||||
|
||||
private KeyIdResult(HashSet<Long> keyIds, boolean allKeysConfirmed, KeyIdResultStatus keyIdResultStatus,
|
||||
AutocryptState combinedAutocryptState) {
|
||||
mKeySelectionPendingIntent = null;
|
||||
mUserKeyIds = keyIds;
|
||||
mAllKeysConfirmed = allKeysConfirmed;
|
||||
mStatus = keyIdResultStatus;
|
||||
mExplicitKeyIds = null;
|
||||
mCombinedAutocryptState = combinedAutocryptState;
|
||||
}
|
||||
|
||||
private KeyIdResult(KeyIdResult keyIdResult, HashSet<Long> explicitKeyIds) {
|
||||
@@ -233,6 +286,7 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
mAllKeysConfirmed = keyIdResult.mAllKeysConfirmed;
|
||||
mStatus = keyIdResult.mStatus;
|
||||
mExplicitKeyIds = explicitKeyIds;
|
||||
mCombinedAutocryptState = keyIdResult.mCombinedAutocryptState;
|
||||
}
|
||||
|
||||
boolean hasKeySelectionPendingIntent() {
|
||||
@@ -274,14 +328,19 @@ class OpenPgpServiceKeyIdExtractor {
|
||||
KeyIdResultStatus getStatus() {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
public AutocryptState getCombinedAutocryptState() {
|
||||
return mCombinedAutocryptState;
|
||||
}
|
||||
}
|
||||
|
||||
enum KeyIdResultStatus {
|
||||
OK, MISSING, DUPLICATE, NO_KEYS, NO_KEYS_ERROR
|
||||
}
|
||||
|
||||
private KeyIdResult createKeysOkResult(HashSet<Long> encryptKeyIds, boolean allKeysConfirmed) {
|
||||
return new KeyIdResult(encryptKeyIds, allKeysConfirmed, KeyIdResultStatus.OK);
|
||||
private KeyIdResult createKeysOkResult(HashSet<Long> encryptKeyIds, boolean allKeysConfirmed,
|
||||
AutocryptState combinedAutocryptState) {
|
||||
return new KeyIdResult(encryptKeyIds, allKeysConfirmed, KeyIdResultStatus.OK, combinedAutocryptState);
|
||||
}
|
||||
|
||||
private KeyIdResult createNoKeysResult(Intent data,
|
||||
|
||||
Reference in New Issue
Block a user