Key selection implies permission to OpenKeychain access
This commit is contained in:
@@ -90,16 +90,6 @@ public class ApiPendingIntentFactory {
|
||||
return createInternal(data, intent);
|
||||
}
|
||||
|
||||
PendingIntent createSelectIdentityKeyPendingIntent(
|
||||
String packageName, String apiIdentity, Long currentMasterKeyId) {
|
||||
Intent intent = new Intent(mContext, RemoteSelectIdKeyActivity.class);
|
||||
intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_PACKAGE_NAME, packageName);
|
||||
intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_USER_ID, apiIdentity);
|
||||
intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_CURRENT_MASTER_KEY_ID, currentMasterKeyId);
|
||||
|
||||
return createInternal(null, intent);
|
||||
}
|
||||
|
||||
PendingIntent createSelectPublicKeyPendingIntent(Intent data, long[] keyIdsArray, ArrayList<String> missingEmails,
|
||||
ArrayList<String> duplicateEmails, boolean noUserIdsCheck) {
|
||||
Intent intent = new Intent(mContext, RemoteSelectPubKeyActivity.class);
|
||||
@@ -147,16 +137,17 @@ public class ApiPendingIntentFactory {
|
||||
PendingIntent createSelectSignKeyIdLegacyPendingIntent(Intent data, String packageName, String preferredUserId) {
|
||||
Intent intent = new Intent(mContext, SelectSignKeyIdActivity.class);
|
||||
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(packageName));
|
||||
intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_PACKAGE_NAME, packageName);
|
||||
intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_USER_ID, preferredUserId);
|
||||
intent.putExtra(SelectSignKeyIdActivity.EXTRA_USER_ID, preferredUserId);
|
||||
|
||||
return createInternal(data, intent);
|
||||
}
|
||||
|
||||
PendingIntent createSelectSignKeyIdPendingIntent(Intent data, String packageName, String preferredUserId) {
|
||||
PendingIntent createSelectSignKeyIdPendingIntent(Intent data, String packageName,
|
||||
byte[] packageSignature, String preferredUserId) {
|
||||
Intent intent = new Intent(mContext, RemoteSelectIdKeyActivity.class);
|
||||
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(packageName));
|
||||
intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_PACKAGE_NAME, packageName);
|
||||
intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
|
||||
intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_USER_ID, preferredUserId);
|
||||
|
||||
return createInternal(data, intent);
|
||||
|
||||
@@ -124,6 +124,14 @@ public class ApiPermissionHelper {
|
||||
}
|
||||
}
|
||||
|
||||
byte[] getPackageCertificateOrError(String packageName) {
|
||||
try {
|
||||
return getPackageCertificate(packageName);
|
||||
} catch (NameNotFoundException e) {
|
||||
throw new AssertionError("Package signature must be retrievable");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getPackageCertificate(String packageName) throws NameNotFoundException {
|
||||
@SuppressLint("PackageManagerGetSignatures") // we do check the byte array of *all* signatures
|
||||
PackageInfo pkgInfo = mContext.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
||||
|
||||
@@ -722,7 +722,9 @@ public class OpenPgpService extends Service {
|
||||
if (preferredUserId == null) {
|
||||
pi = mApiPendingIntentFactory.createSelectSignKeyIdLegacyPendingIntent(data, currentPkg, null);
|
||||
} else {
|
||||
pi = mApiPendingIntentFactory.createSelectSignKeyIdPendingIntent(data, currentPkg, preferredUserId);
|
||||
byte[] packageSignature = mApiPermissionHelper.getPackageCertificateOrError(currentPkg);
|
||||
pi = mApiPendingIntentFactory.createSelectSignKeyIdPendingIntent(
|
||||
data, currentPkg, packageSignature, preferredUserId);
|
||||
}
|
||||
result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
|
||||
}
|
||||
@@ -899,6 +901,11 @@ public class OpenPgpService extends Service {
|
||||
return result;
|
||||
}
|
||||
|
||||
// special exception: getting a sign key id will also register the app
|
||||
if (OpenPgpApi.ACTION_GET_SIGN_KEY_ID.equals(data.getAction())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// check if caller is allowed to access OpenKeychain
|
||||
Intent result = mApiPermissionHelper.isAllowedOrReturnIntent(data);
|
||||
if (result != null) {
|
||||
|
||||
@@ -74,6 +74,7 @@ import timber.log.Timber;
|
||||
|
||||
public class RemoteSelectIdKeyActivity extends FragmentActivity {
|
||||
public static final String EXTRA_PACKAGE_NAME = "package_name";
|
||||
public static final String EXTRA_PACKAGE_SIGNATURE = "package_signature";
|
||||
public static final String EXTRA_USER_ID = "user_id";
|
||||
public static final String EXTRA_CURRENT_MASTER_KEY_ID = "current_master_key_id";
|
||||
|
||||
@@ -106,8 +107,9 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
|
||||
Intent intent = getIntent();
|
||||
String userId = intent.getStringExtra(EXTRA_USER_ID);
|
||||
String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
|
||||
byte[] packageSignature = intent.getByteArrayExtra(EXTRA_PACKAGE_SIGNATURE);
|
||||
|
||||
presenter.setupFromIntentData(packageName, userId);
|
||||
presenter.setupFromIntentData(packageName, packageSignature, userId);
|
||||
}
|
||||
|
||||
public static class RemoteSelectIdentityKeyDialogFragment extends DialogFragment {
|
||||
|
||||
@@ -37,7 +37,9 @@ import org.sufficientlysecure.keychain.livedata.KeyInfoInteractor.KeySelector;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.ApiDataAccessObject;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.remote.AppSettings;
|
||||
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import timber.log.Timber;
|
||||
@@ -55,11 +57,14 @@ class RemoteSelectIdentityKeyPresenter {
|
||||
private UserId userId;
|
||||
private long selectedMasterKeyId;
|
||||
private byte[] generatedKeyData;
|
||||
private ApiDataAccessObject apiDao;
|
||||
private AppSettings appSettings;
|
||||
|
||||
|
||||
RemoteSelectIdentityKeyPresenter(Context context, RemoteSelectIdViewModel viewModel, LifecycleOwner lifecycleOwner) {
|
||||
this.context = context;
|
||||
this.viewModel = viewModel;
|
||||
this.apiDao = new ApiDataAccessObject(context);
|
||||
|
||||
packageManager = context.getPackageManager();
|
||||
|
||||
@@ -71,9 +76,9 @@ class RemoteSelectIdentityKeyPresenter {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
void setupFromIntentData(String packageName, String rawUserId) {
|
||||
void setupFromIntentData(String packageName, byte[] packageSignature, String rawUserId) {
|
||||
try {
|
||||
setPackageInfo(packageName);
|
||||
setPackageInfo(packageName, packageSignature);
|
||||
} catch (NameNotFoundException e) {
|
||||
Timber.e(e, "Unable to find info of calling app!");
|
||||
view.finishAsCancelled();
|
||||
@@ -92,11 +97,13 @@ class RemoteSelectIdentityKeyPresenter {
|
||||
viewModel.getKeyInfo(context).setKeySelector(KeySelector.createOnlySecret(listedKeyRingUri, null));
|
||||
}
|
||||
|
||||
private void setPackageInfo(String packageName) throws NameNotFoundException {
|
||||
private void setPackageInfo(String packageName, byte[] packageSignature) throws NameNotFoundException {
|
||||
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
|
||||
Drawable appIcon = packageManager.getApplicationIcon(applicationInfo);
|
||||
CharSequence appLabel = packageManager.getApplicationLabel(applicationInfo);
|
||||
|
||||
appSettings = new AppSettings(packageName, packageSignature);
|
||||
|
||||
view.setTitleClientIconAndName(appIcon, appLabel);
|
||||
}
|
||||
|
||||
@@ -192,11 +199,15 @@ class RemoteSelectIdentityKeyPresenter {
|
||||
}
|
||||
|
||||
void onHighlightFinished() {
|
||||
apiDao.insertApiApp(appSettings);
|
||||
apiDao.addAllowedKeyIdForApp(appSettings.getPackageName(), selectedMasterKeyId);
|
||||
view.finishAndReturn(selectedMasterKeyId);
|
||||
}
|
||||
|
||||
void onImportOpSuccess(ImportKeyResult result) {
|
||||
long importedMasterKeyId = result.getImportedMasterKeyIds()[0];
|
||||
apiDao.insertApiApp(appSettings);
|
||||
apiDao.addAllowedKeyIdForApp(appSettings.getPackageName(), selectedMasterKeyId);
|
||||
view.finishAndReturn(importedMasterKeyId);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user