Merge branch 'master' of github.com:open-keychain/open-keychain

This commit is contained in:
Dominik Schürmann
2016-12-04 20:13:19 +01:00
2 changed files with 136 additions and 77 deletions

View File

@@ -35,12 +35,10 @@ import android.app.Service;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -84,6 +82,13 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase;
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;
public static final int API_VERSION_HIGHEST_WITH_ACCOUNTS = 6;
public static final int API_VERSION_WITH_KEY_INVALID_INSECURE = 8;
public static final int API_VERSION_WITHOUT_SIGNATURE_ONLY_FLAG = 8;
public static final int API_VERSION_WITH_DECRYPTION_RESULT = 8;
public static final int API_VERSION_WITH_RESULT_NO_SIGNATURE = 8;
public static final List<Integer> SUPPORTED_VERSIONS =
Collections.unmodifiableList(Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10, 11));
@@ -453,7 +458,8 @@ public class OpenPgpService extends Service {
HashSet<Long> allowedKeyIds = mApiDao.getAllowedKeyIdsForApp(
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) {
int targetApiVersion = data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1);
if (targetApiVersion <= API_VERSION_HIGHEST_WITH_ACCOUNTS) {
allowedKeyIds.addAll(mApiDao.getAllKeyIdsForApp(
ApiAccounts.buildBaseUri(currentPkg)));
}
@@ -509,81 +515,10 @@ public class OpenPgpService extends Service {
} else if (pgpResult.success()) {
Intent result = new Intent();
OpenPgpSignatureResult signatureResult = pgpResult.getSignatureResult();
processDecryptionResultForResultIntent(targetApiVersion, result, pgpResult.getDecryptionResult());
processMetadataForResultIntent(targetApiVersion, result, pgpResult.getDecryptionMetadata());
processSignatureResultForResultIntent(targetApiVersion, data, piFactory, result, pgpResult);
switch (signatureResult.getResult()) {
case OpenPgpSignatureResult.RESULT_KEY_MISSING: {
// If signature key is missing we return a PendingIntent to retrieve the key
result.putExtra(OpenPgpApi.RESULT_INTENT,
piFactory.createImportFromKeyserverPendingIntent(data,
signatureResult.getKeyId()));
break;
}
case OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED:
case OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED:
case OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED:
case OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED:
case OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE: {
// If signature key is known, return PendingIntent to show key
result.putExtra(OpenPgpApi.RESULT_INTENT,
piFactory.createShowKeyPendingIntent(data, signatureResult.getKeyId()));
break;
}
default:
case OpenPgpSignatureResult.RESULT_NO_SIGNATURE:
case OpenPgpSignatureResult.RESULT_INVALID_SIGNATURE: {
// no key id -> no PendingIntent
}
}
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 5) {
// RESULT_INVALID_KEY_REVOKED and RESULT_INVALID_KEY_EXPIRED have been added in version 5
if (signatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED
|| signatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED) {
signatureResult = OpenPgpSignatureResult.createWithInvalidSignature();
}
}
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 8) {
// RESULT_INVALID_INSECURE has been added in version 8, fallback to RESULT_INVALID_SIGNATURE
if (signatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE) {
signatureResult = OpenPgpSignatureResult.createWithInvalidSignature();
}
// RESULT_NO_SIGNATURE has been added in version 8, before the signatureResult was null
if (signatureResult.getResult() == OpenPgpSignatureResult.RESULT_NO_SIGNATURE) {
result.putExtra(OpenPgpApi.RESULT_SIGNATURE, (Parcelable[]) null);
}
}
boolean apiHasOpenPgpDecryptionResult = data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) >= 8;
if (apiHasOpenPgpDecryptionResult) {
OpenPgpDecryptionResult decryptionResult = pgpResult.getDecryptionResult();
if (decryptionResult != null) {
result.putExtra(OpenPgpApi.RESULT_DECRYPTION, decryptionResult);
}
} else {
// this info was kept in OpenPgpSignatureResult, so put it there for compatibility
OpenPgpDecryptionResult decryptionResult = pgpResult.getDecryptionResult();
boolean signatureOnly = decryptionResult.getResult() == OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED
&& signatureResult.getResult() != OpenPgpSignatureResult.RESULT_NO_SIGNATURE;
// noinspection deprecation, this is for backwards compatibility
signatureResult = signatureResult.withSignatureOnlyFlag(signatureOnly);
}
OpenPgpMetadata metadata = pgpResult.getDecryptionMetadata();
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) >= 4) {
if (metadata != null) {
result.putExtra(OpenPgpApi.RESULT_METADATA, metadata);
}
}
String charset = metadata != null ? metadata.getCharset() : null;
if (charset != null) {
result.putExtra(OpenPgpApi.RESULT_CHARSET, charset);
}
result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} else {
@@ -614,6 +549,103 @@ public class OpenPgpService extends Service {
}
}
private void processDecryptionResultForResultIntent(int targetApiVersion, Intent result,
OpenPgpDecryptionResult decryptionResult) {
if (targetApiVersion < API_VERSION_WITH_DECRYPTION_RESULT) {
return;
}
if (decryptionResult != null) {
result.putExtra(OpenPgpApi.RESULT_DECRYPTION, decryptionResult);
}
}
private OpenPgpSignatureResult getSignatureResultWithApiCompatibilityFallbacks(
int targetApiVersion, DecryptVerifyResult pgpResult) {
OpenPgpSignatureResult signatureResult = pgpResult.getSignatureResult();
if (targetApiVersion < API_VERSION_WITH_KEY_REVOKED_EXPIRED) {
// RESULT_INVALID_KEY_REVOKED and RESULT_INVALID_KEY_EXPIRED have been added in version 5
if (signatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED
|| signatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED) {
signatureResult = OpenPgpSignatureResult.createWithInvalidSignature();
}
}
if (targetApiVersion < API_VERSION_WITH_KEY_INVALID_INSECURE) {
// RESULT_INVALID_INSECURE has been added in version 8, fallback to RESULT_INVALID_SIGNATURE
if (signatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE) {
signatureResult = OpenPgpSignatureResult.createWithInvalidSignature();
}
}
if (targetApiVersion < API_VERSION_WITHOUT_SIGNATURE_ONLY_FLAG) {
// this info was kept in OpenPgpSignatureResult, so put it there for compatibility
OpenPgpDecryptionResult decryptionResult = pgpResult.getDecryptionResult();
boolean signatureOnly = decryptionResult.getResult() == OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED
&& signatureResult.getResult() != OpenPgpSignatureResult.RESULT_NO_SIGNATURE;
// noinspection deprecation, this is for backwards compatibility
signatureResult = signatureResult.withSignatureOnlyFlag(signatureOnly);
}
return signatureResult;
}
private void processMetadataForResultIntent(int targetApiVersion, Intent result, OpenPgpMetadata metadata) {
String charset = metadata != null ? metadata.getCharset() : null;
if (charset != null) {
result.putExtra(OpenPgpApi.RESULT_CHARSET, charset);
}
if (targetApiVersion < API_VERSION_WITH_RESULT_METADATA) {
return;
}
if (metadata != null) {
result.putExtra(OpenPgpApi.RESULT_METADATA, metadata);
}
}
private void processSignatureResultForResultIntent(int targetApiVersion, Intent data,
ApiPendingIntentFactory piFactory, Intent result, DecryptVerifyResult pgpResult) {
OpenPgpSignatureResult signatureResult =
getSignatureResultWithApiCompatibilityFallbacks(targetApiVersion, pgpResult);
switch (signatureResult.getResult()) {
case OpenPgpSignatureResult.RESULT_KEY_MISSING: {
// If signature key is missing we return a PendingIntent to retrieve the key
result.putExtra(OpenPgpApi.RESULT_INTENT,
piFactory.createImportFromKeyserverPendingIntent(data,
signatureResult.getKeyId()));
break;
}
case OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED:
case OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED:
case OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED:
case OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED:
case OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE: {
// If signature key is known, return PendingIntent to show key
result.putExtra(OpenPgpApi.RESULT_INTENT,
piFactory.createShowKeyPendingIntent(data, signatureResult.getKeyId()));
break;
}
default:
case OpenPgpSignatureResult.RESULT_NO_SIGNATURE: {
if (targetApiVersion < API_VERSION_WITH_RESULT_NO_SIGNATURE) {
// RESULT_NO_SIGNATURE has been added in version 8, before the signatureResult was null
signatureResult = null;
}
// otherwise, no pending intent
}
case OpenPgpSignatureResult.RESULT_INVALID_SIGNATURE: {
// no key id -> no PendingIntent
}
}
result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
}
private Intent getKeyImpl(Intent data, OutputStream outputStream) {
try {
ApiPendingIntentFactory piFactory = new ApiPendingIntentFactory(getBaseContext());

View File

@@ -23,6 +23,8 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.util.Linkify;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -31,6 +33,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
@@ -105,10 +108,34 @@ public class DisplayTextFragment extends DecryptFragment {
String plaintext = args.getString(ARG_PLAINTEXT);
DecryptVerifyResult result = args.getParcelable(ARG_DECRYPT_VERIFY_RESULT);
if (result == null) {
throw new IllegalStateException("Missing decryption result argument!");
}
// display signature result in activity
setAutoLinkFromSignatureResult(result.getSignatureResult());
mText.setText(plaintext);
loadVerifyResult(result);
}
private void setAutoLinkFromSignatureResult(@Nullable OpenPgpSignatureResult signatureResult) {
if (signatureResult == null) {
mText.setAutoLinkMask(0);
return;
}
switch (signatureResult.getResult()) {
case OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED:
case OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED: {
mText.setAutoLinkMask(Linkify.ALL);
break;
}
default: {
mText.setAutoLinkMask(0);
break;
}
}
}
@Override