pass all subkeys to request permission activity, select best out of these there
This commit is contained in:
@@ -209,7 +209,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||||||
|
|
||||||
int symmetricEncryptionAlgo = 0;
|
int symmetricEncryptionAlgo = 0;
|
||||||
|
|
||||||
HashSet<Long> skippedDisallowedKeys = new HashSet<>();
|
HashSet<Long> skippedDisallowedEncryptionKeys = new HashSet<>();
|
||||||
boolean insecureEncryptionKey = false;
|
boolean insecureEncryptionKey = false;
|
||||||
|
|
||||||
// convenience method to return with error
|
// convenience method to return with error
|
||||||
@@ -608,7 +608,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||||||
if (!input.getAllowedKeyIds().contains(masterKeyId)) {
|
if (!input.getAllowedKeyIds().contains(masterKeyId)) {
|
||||||
// this key is in our db, but NOT allowed!
|
// this key is in our db, but NOT allowed!
|
||||||
// continue with the next packet in the while loop
|
// 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);
|
log.add(LogType.MSG_DC_ASKIP_NOT_ALLOWED, indent + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -817,10 +817,12 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||||||
return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_NO_DATA, log));
|
return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_NO_DATA, log));
|
||||||
}
|
}
|
||||||
// there was data but key wasn't allowed
|
// 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);
|
log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
|
||||||
long[] skippedDisallowedKeys = KeyFormattingUtils.getUnboxedLongArray(result.skippedDisallowedKeys);
|
long[] skippedDisallowedEncryptionKeys =
|
||||||
return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_KEY_DISALLOWED, log, skippedDisallowedKeys));
|
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
|
// 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);
|
log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.remote;
|
package org.sufficientlysecure.keychain.remote;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
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.service.input.RequiredInputParcel;
|
||||||
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
|
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class ApiPendingIntentFactory {
|
public class ApiPendingIntentFactory {
|
||||||
|
|
||||||
Context mContext;
|
Context mContext;
|
||||||
@@ -103,10 +104,10 @@ public class ApiPendingIntentFactory {
|
|||||||
return createInternal(data, intent);
|
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 intent = new Intent(mContext, RequestKeyPermissionActivity.class);
|
||||||
intent.putExtra(RequestKeyPermissionActivity.EXTRA_PACKAGE_NAME, packageName);
|
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);
|
return createInternal(data, intent);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,15 @@
|
|||||||
package org.sufficientlysecure.keychain.remote;
|
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.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
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.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
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 class OpenPgpService extends Service {
|
||||||
public static final int API_VERSION_WITH_RESULT_METADATA = 4;
|
public static final int API_VERSION_WITH_RESULT_METADATA = 4;
|
||||||
public static final int API_VERSION_WITH_KEY_REVOKED_EXPIRED = 5;
|
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);
|
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
long[] skippedDisallowedKeys = pgpResult.getSkippedDisallowedKeys();
|
long[] skippedDisallowedEncryptionKeys = pgpResult.getSkippedDisallowedKeys();
|
||||||
if (pgpResult.isKeysDisallowed() && skippedDisallowedKeys.length > 0) {
|
if (pgpResult.isKeysDisallowed() &&
|
||||||
long masterKeyId = skippedDisallowedKeys[0];
|
skippedDisallowedEncryptionKeys != null && skippedDisallowedEncryptionKeys.length > 0) {
|
||||||
|
|
||||||
// allow user to select allowed keys
|
// allow user to select allowed keys
|
||||||
Intent result = new Intent();
|
Intent result = new Intent();
|
||||||
String packageName = mApiPermissionHelper.getCurrentCallingPackage();
|
String packageName = mApiPermissionHelper.getCurrentCallingPackage();
|
||||||
result.putExtra(OpenPgpApi.RESULT_INTENT,
|
result.putExtra(OpenPgpApi.RESULT_INTENT,
|
||||||
mApiPendingIntentFactory.createRequestKeyPermissionPendingIntent(
|
mApiPendingIntentFactory.createRequestKeyPermissionPendingIntent(
|
||||||
data, packageName, masterKeyId));
|
data, packageName, skippedDisallowedEncryptionKeys));
|
||||||
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
|
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.openintents.openpgp.util.OpenPgpUtils.UserId;
|
import org.openintents.openpgp.util.OpenPgpUtils.UserId;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.remote.ui.RequestKeyPermissionPresenter.RequestKeyPermissionMvpView;
|
import org.sufficientlysecure.keychain.remote.ui.RequestKeyPermissionPresenter.RequestKeyPermissionMvpView;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
|
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
|
||||||
@@ -46,7 +45,7 @@ import org.sufficientlysecure.keychain.ui.util.ThemeChanger;
|
|||||||
|
|
||||||
public class RequestKeyPermissionActivity extends FragmentActivity {
|
public class RequestKeyPermissionActivity extends FragmentActivity {
|
||||||
public static final String EXTRA_PACKAGE_NAME = "package_name";
|
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;
|
private RequestKeyPermissionPresenter presenter;
|
||||||
@@ -70,9 +69,9 @@ public class RequestKeyPermissionActivity extends FragmentActivity {
|
|||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
|
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 {
|
public static class RequestKeyPermissionFragment extends DialogFragment {
|
||||||
|
|||||||
@@ -6,14 +6,18 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.openintents.openpgp.util.OpenPgpUtils.UserId;
|
import org.openintents.openpgp.util.OpenPgpUtils.UserId;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
|
||||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||||
import org.sufficientlysecure.keychain.provider.ApiDataAccessObject;
|
import org.sufficientlysecure.keychain.provider.ApiDataAccessObject;
|
||||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
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;
|
||||||
|
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
|
||||||
import org.sufficientlysecure.keychain.remote.ApiPermissionHelper;
|
import org.sufficientlysecure.keychain.remote.ApiPermissionHelper;
|
||||||
import org.sufficientlysecure.keychain.remote.ApiPermissionHelper.WrongPackageCertificateException;
|
import org.sufficientlysecure.keychain.remote.ApiPermissionHelper.WrongPackageCertificateException;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
@@ -29,29 +33,33 @@ class RequestKeyPermissionPresenter {
|
|||||||
|
|
||||||
private String packageName;
|
private String packageName;
|
||||||
private long masterKeyId;
|
private long masterKeyId;
|
||||||
|
private ProviderHelper providerHelper;
|
||||||
|
|
||||||
|
|
||||||
static RequestKeyPermissionPresenter createRequestKeyPermissionPresenter(Context context) {
|
static RequestKeyPermissionPresenter createRequestKeyPermissionPresenter(Context context) {
|
||||||
PackageManager packageManager = context.getPackageManager();
|
PackageManager packageManager = context.getPackageManager();
|
||||||
ApiDataAccessObject apiDataAccessObject = new ApiDataAccessObject(context);
|
ApiDataAccessObject apiDataAccessObject = new ApiDataAccessObject(context);
|
||||||
ApiPermissionHelper apiPermissionHelper = new ApiPermissionHelper(context, apiDataAccessObject);
|
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,
|
private RequestKeyPermissionPresenter(Context context, ApiDataAccessObject apiDataAccessObject,
|
||||||
ApiPermissionHelper apiPermissionHelper, PackageManager packageManager) {
|
ApiPermissionHelper apiPermissionHelper, PackageManager packageManager, ProviderHelper providerHelper) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.apiDataAccessObject = apiDataAccessObject;
|
this.apiDataAccessObject = apiDataAccessObject;
|
||||||
this.apiPermissionHelper = apiPermissionHelper;
|
this.apiPermissionHelper = apiPermissionHelper;
|
||||||
this.packageManager = packageManager;
|
this.packageManager = packageManager;
|
||||||
|
this.providerHelper = providerHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setView(RequestKeyPermissionMvpView view) {
|
void setView(RequestKeyPermissionMvpView view) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupFromIntentData(String packageName, long masterKeyId) {
|
void setupFromIntentData(String packageName, long[] masterKeyIds) {
|
||||||
checkPackageAllowed(packageName);
|
checkPackageAllowed(packageName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -62,25 +70,58 @@ class RequestKeyPermissionPresenter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.packageName = packageName;
|
|
||||||
this.masterKeyId = masterKeyId;
|
|
||||||
try {
|
try {
|
||||||
CachedPublicKeyRing cachedPublicKeyRing = new ProviderHelper(context).getCachedPublicKeyRing(masterKeyId);
|
setRequestedMasterKeyId(masterKeyIds);
|
||||||
|
|
||||||
UserId userId = cachedPublicKeyRing.getSplitPrimaryUserIdWithFallback();
|
|
||||||
view.displayKeyInfo(userId);
|
|
||||||
|
|
||||||
if (cachedPublicKeyRing.hasAnySecret()) {
|
|
||||||
view.switchToLayoutRequestKeyChoice();
|
|
||||||
} else {
|
|
||||||
view.switchToLayoutNoSecret();
|
|
||||||
}
|
|
||||||
} catch (PgpKeyNotFoundException e) {
|
} catch (PgpKeyNotFoundException e) {
|
||||||
view.finishAsCancelled();
|
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 {
|
private void setPackageInfo(String packageName) throws NameNotFoundException {
|
||||||
|
this.packageName = packageName;
|
||||||
|
|
||||||
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
|
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
|
||||||
Drawable appIcon = packageManager.getApplicationIcon(applicationInfo);
|
Drawable appIcon = packageManager.getApplicationIcon(applicationInfo);
|
||||||
CharSequence appName = packageManager.getApplicationLabel(applicationInfo);
|
CharSequence appName = packageManager.getApplicationLabel(applicationInfo);
|
||||||
|
|||||||
Reference in New Issue
Block a user