pass all subkeys to request permission activity, select best out of these there

This commit is contained in:
Vincent Breitmoser 2017-02-08 02:10:04 +01:00
parent eb349eb80f
commit 1ae3ba9b72
5 changed files with 84 additions and 42 deletions

View file

@ -209,7 +209,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
int symmetricEncryptionAlgo = 0;
HashSet<Long> skippedDisallowedKeys = new HashSet<>();
HashSet<Long> skippedDisallowedEncryptionKeys = new HashSet<>();
boolean insecureEncryptionKey = false;
// convenience method to return with error
@ -608,7 +608,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
if (!input.getAllowedKeyIds().contains(masterKeyId)) {
// this key is in our db, but NOT allowed!
// continue with the next packet in the while loop
result.skippedDisallowedKeys.add(masterKeyId);
result.skippedDisallowedEncryptionKeys.add(subKeyId);
log.add(LogType.MSG_DC_ASKIP_NOT_ALLOWED, indent + 1);
continue;
}
@ -817,10 +817,12 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_NO_DATA, log));
}
// there was data but key wasn't allowed
if (!result.skippedDisallowedKeys.isEmpty()) {
if (!result.skippedDisallowedEncryptionKeys.isEmpty()) {
log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
long[] skippedDisallowedKeys = KeyFormattingUtils.getUnboxedLongArray(result.skippedDisallowedKeys);
return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_KEY_DISALLOWED, log, skippedDisallowedKeys));
long[] skippedDisallowedEncryptionKeys =
KeyFormattingUtils.getUnboxedLongArray(result.skippedDisallowedEncryptionKeys);
return result.with(new DecryptVerifyResult(
DecryptVerifyResult.RESULT_KEY_DISALLOWED, log, skippedDisallowedEncryptionKeys));
}
// no packet has been found where we have the corresponding secret key in our db
log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);

View file

@ -17,6 +17,9 @@
package org.sufficientlysecure.keychain.remote;
import java.util.ArrayList;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@ -37,8 +40,6 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
import java.util.ArrayList;
public class ApiPendingIntentFactory {
Context mContext;
@ -103,10 +104,10 @@ public class ApiPendingIntentFactory {
return createInternal(data, intent);
}
PendingIntent createRequestKeyPermissionPendingIntent(Intent data, String packageName, long masterKeyId) {
PendingIntent createRequestKeyPermissionPendingIntent(Intent data, String packageName, long[] masterKeyIds) {
Intent intent = new Intent(mContext, RequestKeyPermissionActivity.class);
intent.putExtra(RequestKeyPermissionActivity.EXTRA_PACKAGE_NAME, packageName);
intent.putExtra(RequestKeyPermissionActivity.EXTRA_REQUESTED_KEY_ID, masterKeyId);
intent.putExtra(RequestKeyPermissionActivity.EXTRA_REQUESTED_KEY_IDS, masterKeyIds);
return createInternal(data, intent);
}

View file

@ -19,6 +19,15 @@
package org.sufficientlysecure.keychain.remote;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
@ -66,15 +75,6 @@ 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.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
public class OpenPgpService extends Service {
public static final int API_VERSION_WITH_RESULT_METADATA = 4;
public static final int API_VERSION_WITH_KEY_REVOKED_EXPIRED = 5;
@ -393,16 +393,15 @@ public class OpenPgpService extends Service {
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} else {
long[] skippedDisallowedKeys = pgpResult.getSkippedDisallowedKeys();
if (pgpResult.isKeysDisallowed() && skippedDisallowedKeys.length > 0) {
long masterKeyId = skippedDisallowedKeys[0];
long[] skippedDisallowedEncryptionKeys = pgpResult.getSkippedDisallowedKeys();
if (pgpResult.isKeysDisallowed() &&
skippedDisallowedEncryptionKeys != null && skippedDisallowedEncryptionKeys.length > 0) {
// allow user to select allowed keys
Intent result = new Intent();
String packageName = mApiPermissionHelper.getCurrentCallingPackage();
result.putExtra(OpenPgpApi.RESULT_INTENT,
mApiPendingIntentFactory.createRequestKeyPermissionPendingIntent(
data, packageName, masterKeyId));
data, packageName, skippedDisallowedEncryptionKeys));
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
return result;
}

View file

@ -37,7 +37,6 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.openintents.openpgp.util.OpenPgpUtils.UserId;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.remote.ui.RequestKeyPermissionPresenter.RequestKeyPermissionMvpView;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
@ -46,7 +45,7 @@ import org.sufficientlysecure.keychain.ui.util.ThemeChanger;
public class RequestKeyPermissionActivity extends FragmentActivity {
public static final String EXTRA_PACKAGE_NAME = "package_name";
public static final String EXTRA_REQUESTED_KEY_ID = "requested_key_id";
public static final String EXTRA_REQUESTED_KEY_IDS = "requested_key_ids";
private RequestKeyPermissionPresenter presenter;
@ -70,9 +69,9 @@ public class RequestKeyPermissionActivity extends FragmentActivity {
Intent intent = getIntent();
String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
long masterKeyId = intent.getLongExtra(EXTRA_REQUESTED_KEY_ID, Constants.key.none);
long masterKeyIds[] = intent.getLongArrayExtra(EXTRA_REQUESTED_KEY_IDS);
presenter.setupFromIntentData(packageName, masterKeyId);
presenter.setupFromIntentData(packageName, masterKeyIds);
}
public static class RequestKeyPermissionFragment extends DialogFragment {

View file

@ -6,14 +6,18 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import org.openintents.openpgp.util.OpenPgpUtils.UserId;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.ApiDataAccessObject;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
import org.sufficientlysecure.keychain.remote.ApiPermissionHelper;
import org.sufficientlysecure.keychain.remote.ApiPermissionHelper.WrongPackageCertificateException;
import org.sufficientlysecure.keychain.util.Log;
@ -29,29 +33,33 @@ class RequestKeyPermissionPresenter {
private String packageName;
private long masterKeyId;
private ProviderHelper providerHelper;
static RequestKeyPermissionPresenter createRequestKeyPermissionPresenter(Context context) {
PackageManager packageManager = context.getPackageManager();
ApiDataAccessObject apiDataAccessObject = new ApiDataAccessObject(context);
ApiPermissionHelper apiPermissionHelper = new ApiPermissionHelper(context, apiDataAccessObject);
ProviderHelper providerHelper = new ProviderHelper(context);
return new RequestKeyPermissionPresenter(context, apiDataAccessObject, apiPermissionHelper, packageManager);
return new RequestKeyPermissionPresenter(context, apiDataAccessObject, apiPermissionHelper, packageManager,
providerHelper);
}
private RequestKeyPermissionPresenter(Context context, ApiDataAccessObject apiDataAccessObject,
ApiPermissionHelper apiPermissionHelper, PackageManager packageManager) {
ApiPermissionHelper apiPermissionHelper, PackageManager packageManager, ProviderHelper providerHelper) {
this.context = context;
this.apiDataAccessObject = apiDataAccessObject;
this.apiPermissionHelper = apiPermissionHelper;
this.packageManager = packageManager;
this.providerHelper = providerHelper;
}
void setView(RequestKeyPermissionMvpView view) {
this.view = view;
}
void setupFromIntentData(String packageName, long masterKeyId) {
void setupFromIntentData(String packageName, long[] masterKeyIds) {
checkPackageAllowed(packageName);
try {
@ -62,25 +70,58 @@ class RequestKeyPermissionPresenter {
return;
}
this.packageName = packageName;
this.masterKeyId = masterKeyId;
try {
CachedPublicKeyRing cachedPublicKeyRing = new ProviderHelper(context).getCachedPublicKeyRing(masterKeyId);
UserId userId = cachedPublicKeyRing.getSplitPrimaryUserIdWithFallback();
view.displayKeyInfo(userId);
if (cachedPublicKeyRing.hasAnySecret()) {
view.switchToLayoutRequestKeyChoice();
} else {
view.switchToLayoutNoSecret();
}
setRequestedMasterKeyId(masterKeyIds);
} catch (PgpKeyNotFoundException e) {
view.finishAsCancelled();
}
}
private void setRequestedMasterKeyId(long[] subKeyIds) throws PgpKeyNotFoundException {
CachedPublicKeyRing secretKeyRingOrPublicFallback = findSecretKeyRingOrPublicFallback(subKeyIds);
if (secretKeyRingOrPublicFallback == null) {
throw new PgpKeyNotFoundException("No key found among requested!");
}
this.masterKeyId = secretKeyRingOrPublicFallback.getMasterKeyId();
UserId userId = secretKeyRingOrPublicFallback.getSplitPrimaryUserIdWithFallback();
view.displayKeyInfo(userId);
if (secretKeyRingOrPublicFallback.hasAnySecret()) {
view.switchToLayoutRequestKeyChoice();
} else {
view.switchToLayoutNoSecret();
}
}
@Nullable
private CachedPublicKeyRing findSecretKeyRingOrPublicFallback(long[] subKeyIds) {
CachedPublicKeyRing publicFallbackRing = null;
for (long candidateSubKeyId : subKeyIds) {
try {
CachedPublicKeyRing cachedPublicKeyRing = providerHelper.getCachedPublicKeyRing(
KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(candidateSubKeyId)
);
SecretKeyType secretKeyType = cachedPublicKeyRing.getSecretKeyType(candidateSubKeyId);
if (secretKeyType.isUsable()) {
return cachedPublicKeyRing;
}
if (publicFallbackRing == null) {
publicFallbackRing = cachedPublicKeyRing;
}
} catch (PgpKeyNotFoundException | NotFoundException e) {
// no matter
}
}
return publicFallbackRing;
}
private void setPackageInfo(String packageName) throws NameNotFoundException {
this.packageName = packageName;
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
Drawable appIcon = packageManager.getApplicationIcon(applicationInfo);
CharSequence appName = packageManager.getApplicationLabel(applicationInfo);