combine autocrypt peer state and hand to client app

This commit is contained in:
Vincent Breitmoser
2017-06-21 20:52:17 +02:00
parent 5e01e41bcd
commit 4cf4981f1b
2 changed files with 93 additions and 30 deletions

View File

@@ -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!");
}

View File

@@ -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,