improve presentation of security problems

This commit is contained in:
Vincent Breitmoser
2017-04-27 21:48:54 +02:00
parent 1868aed53b
commit 78c3e17d0a
4 changed files with 129 additions and 65 deletions

View File

@@ -83,6 +83,7 @@ public class RemoteSecurityProblemDialogActivity extends FragmentActivity {
private RemoteSecurityProblemView mvpView; private RemoteSecurityProblemView mvpView;
private Button buttonGotIt; private Button buttonGotIt;
private Button buttonViewKey;
@NonNull @NonNull
@Override @Override
@@ -97,6 +98,7 @@ public class RemoteSecurityProblemDialogActivity extends FragmentActivity {
alert.setView(view); alert.setView(view);
buttonGotIt = (Button) view.findViewById(R.id.button_allow); buttonGotIt = (Button) view.findViewById(R.id.button_allow);
buttonViewKey = (Button) view.findViewById(R.id.button_view_key);
setupListenersForPresenter(); setupListenersForPresenter();
mvpView = createMvpView(view); mvpView = createMvpView(view);
@@ -168,6 +170,11 @@ public class RemoteSecurityProblemDialogActivity extends FragmentActivity {
recommendLayout.setVisibility(View.GONE); recommendLayout.setVisibility(View.GONE);
} }
private void showGeneric(String explanationString) {
explanationText.setText(explanationString);
recommendLayout.setVisibility(View.GONE);
}
private void showGenericWithRecommendation( private void showGenericWithRecommendation(
@StringRes int explanationStringRes, @StringRes int recommendationStringRes) { @StringRes int explanationStringRes, @StringRes int recommendationStringRes) {
explanationText.setText(explanationStringRes); explanationText.setText(explanationStringRes);
@@ -175,59 +182,73 @@ public class RemoteSecurityProblemDialogActivity extends FragmentActivity {
recommendLayout.setVisibility(View.VISIBLE); recommendLayout.setVisibility(View.VISIBLE);
} }
private void showGenericWithRecommendation(
String explanationString, @StringRes int recommendationStringRes) {
explanationText.setText(explanationString);
recommendText.setText(recommendationStringRes);
recommendLayout.setVisibility(View.VISIBLE);
}
@Override @Override
public void showLayoutMissingMdc() { public void showLayoutMissingMdc() {
showGenericWithRecommendation(R.string.insecure_msg_mdc, R.string.insecure_recom_mdc); showGenericWithRecommendation(R.string.insecure_mdc, R.string.insecure_mdc_suggestion);
} }
@Override @Override
public void showLayoutInsecureSymmetric(int symmetricAlgorithm) { public void showLayoutInsecureSymmetric(int symmetricAlgorithm) {
showGeneric(R.string.insecure_msg_unidentified_key); showGeneric(R.string.insecure_symmetric_algo);
} }
@Override @Override
public void showLayoutInsecureHashAlgorithm(int hashAlgorithm) { public void showLayoutInsecureHashAlgorithm(int hashAlgorithm) {
showGeneric(R.string.insecure_msg_unidentified_key); showGeneric(R.string.insecure_hash_algo);
} }
@Override @Override
public void showLayoutEncryptInsecureBitsize(int algorithmId, int bitStrength) { public void showLayoutEncryptInsecureBitsize(int algorithmId, int bitStrength) {
String algorithmName = KeyFormattingUtils.getAlgorithmInfo(algorithmId, null, null); String algorithmName = KeyFormattingUtils.getAlgorithmInfo(algorithmId, null, null);
explanationText.setText(
getString(R.string.insecure_msg_bitstrength, algorithmName, showGenericWithRecommendation(
Integer.toString(bitStrength), "2010")); getString(R.string.insecure_encrypt_bitstrength, algorithmName,
recommendText.setText(R.string.insecure_recom_new_key); Integer.toString(bitStrength), "2010"),
recommendText.setVisibility(View.VISIBLE); R.string.insecure_sign_bitstrength_suggestion);
} }
@Override @Override
public void showLayoutSignInsecureBitsize(int algorithmId, int bitStrength) { public void showLayoutSignInsecureBitsize(int algorithmId, int bitStrength) {
String algorithmName = KeyFormattingUtils.getAlgorithmInfo(algorithmId, null, null); String algorithmName = KeyFormattingUtils.getAlgorithmInfo(algorithmId, null, null);
explanationText.setText(
getString(R.string.insecure_msg_bitstrength, algorithmName, showGenericWithRecommendation(
Integer.toString(bitStrength), "2010")); getString(R.string.insecure_sign_bitstrength, algorithmName,
recommendText.setText(R.string.insecure_recom_new_key); Integer.toString(bitStrength), "2010"),
recommendText.setVisibility(View.VISIBLE); R.string.insecure_sign_bitstrength_suggestion);
} }
@Override @Override
public void showLayoutEncryptNotWhitelistedCurve(String curveOid) { public void showLayoutEncryptNotWhitelistedCurve(String curveOid) {
showGeneric(R.string.insecure_msg_not_whitelisted_curve); showGeneric(getString(R.string.insecure_encrypt_not_whitelisted_curve,
KeyFormattingUtils.getCurveInfo(getContext(), curveOid)));
} }
@Override @Override
public void showLayoutSignNotWhitelistedCurve(String curveOid) { public void showLayoutSignNotWhitelistedCurve(String curveOid) {
showGeneric(R.string.insecure_msg_not_whitelisted_curve); showGeneric(getString(R.string.insecure_sign_not_whitelisted_curve,
KeyFormattingUtils.getCurveInfo(getContext(), curveOid)));
} }
@Override @Override
public void showLayoutEncryptUnidentifiedKeyProblem() { public void showLayoutEncryptUnidentifiedKeyProblem() {
showGeneric(R.string.insecure_msg_unidentified_key); showGeneric(R.string.insecure_encrypt_unidentified);
} }
@Override @Override
public void showLayoutSignUnidentifiedKeyProblem() { public void showLayoutSignUnidentifiedKeyProblem() {
showGeneric(R.string.insecure_msg_unidentified_key); showGeneric(R.string.insecure_sign_unidentified);
}
@Override
public void showViewKeyButton() {
buttonViewKey.setVisibility(View.VISIBLE);
} }
}; };
} }
@@ -239,6 +260,12 @@ public class RemoteSecurityProblemDialogActivity extends FragmentActivity {
presenter.onClickGotIt(); presenter.onClickGotIt();
} }
}); });
buttonViewKey.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
presenter.onClickViewKey();
}
});
} }
} }

View File

@@ -4,32 +4,36 @@ package org.sufficientlysecure.keychain.remote.ui;
import java.io.Serializable; import java.io.Serializable;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo; 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 org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.DecryptVerifySecurityProblem;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureBitStrength; import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureBitStrength;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureHashAlgorithm; import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureSigningAlgorithm;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureSymmetricAlgorithm; import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureEncryptionAlgorithm;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.KeySecurityProblem; import org.sufficientlysecure.keychain.pgp.SecurityProblem.KeySecurityProblem;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.MissingMdc; import org.sufficientlysecure.keychain.pgp.SecurityProblem.MissingMdc;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.NotWhitelistedCurve; import org.sufficientlysecure.keychain.pgp.SecurityProblem.NotWhitelistedCurve;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.SymmetricAlgorithmProblem; import org.sufficientlysecure.keychain.pgp.SecurityProblem.EncryptionAlgorithmProblem;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.UnidentifiedKeyProblem; import org.sufficientlysecure.keychain.pgp.SecurityProblem.UnidentifiedKeyProblem;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.UsageType; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
class SecurityProblemPresenter { class SecurityProblemPresenter {
private final Context context;
private final PackageManager packageManager; private final PackageManager packageManager;
private RemoteSecurityProblemView view; private RemoteSecurityProblemView view;
private Long viewKeyMasterKeyId;
SecurityProblemPresenter(Context context) { SecurityProblemPresenter(Context context) {
this.context = context;
packageManager = context.getPackageManager(); packageManager = context.getPackageManager();
} }
@@ -38,13 +42,8 @@ class SecurityProblemPresenter {
} }
void setupFromIntentData(String packageName, Serializable securityProblem) { void setupFromIntentData(String packageName, Serializable securityProblem) {
if (securityProblem instanceof DecryptVerifySecurityProblem) {
if (securityProblem instanceof KeySecurityProblem) { setupFromDecryptVerifySecurityProblem((DecryptVerifySecurityProblem) securityProblem);
// setupFromKeySecurityProblem((KeySecurityProblem) securityProblem);
} else if (securityProblem instanceof SymmetricAlgorithmProblem) {
setupFromNonKeySecurityProblem((SymmetricAlgorithmProblem) securityProblem);
} else if (securityProblem instanceof InsecureHashAlgorithm) {
setupFromInsecureHashAlgorithm((InsecureHashAlgorithm) securityProblem);
} else { } else {
throw new IllegalArgumentException("Unhandled security problem type!"); throw new IllegalArgumentException("Unhandled security problem type!");
} }
@@ -56,53 +55,65 @@ class SecurityProblemPresenter {
} }
} }
/* private void setupFromDecryptVerifySecurityProblem(DecryptVerifySecurityProblem securityProblem) {
private void setupFromKeySecurityProblem(KeySecurityProblem keySecurityProblem) { if (securityProblem.encryptionKeySecurityProblem != null) {
setupFromEncryptionKeySecurityProblem(securityProblem.encryptionKeySecurityProblem);
} else if (securityProblem.signingKeySecurityProblem != null) {
setupFromSigningKeySecurityProblem(securityProblem.signingKeySecurityProblem);
} else if (securityProblem.symmetricSecurityProblem != null) {
setupFromEncryptionAlgorithmSecurityProblem(securityProblem.symmetricSecurityProblem);
} else if (securityProblem.signatureSecurityProblem != null) {
setupFromSignatureSecurityProblem(securityProblem.signatureSecurityProblem);
}
}
private void setupFromEncryptionKeySecurityProblem(KeySecurityProblem keySecurityProblem) {
viewKeyMasterKeyId = keySecurityProblem.masterKeyId;
view.showViewKeyButton();
if (keySecurityProblem instanceof InsecureBitStrength) { if (keySecurityProblem instanceof InsecureBitStrength) {
InsecureBitStrength problem = (InsecureBitStrength) keySecurityProblem; InsecureBitStrength problem = (InsecureBitStrength) keySecurityProblem;
if (problem.usageType == UsageType.ENCRYPT) { view.showLayoutEncryptInsecureBitsize(problem.algorithm, problem.bitStrength);
view.showLayoutEncryptInsecureBitsize(problem.algorithm, problem.bitStrength);
} else if (problem.usageType == UsageType.SIGN) {
view.showLayoutSignInsecureBitsize(problem.algorithm, problem.bitStrength);
} else {
throw new IllegalStateException("Should never happen here!");
}
} else if (keySecurityProblem instanceof NotWhitelistedCurve) { } else if (keySecurityProblem instanceof NotWhitelistedCurve) {
NotWhitelistedCurve problem = (NotWhitelistedCurve) keySecurityProblem; NotWhitelistedCurve problem = (NotWhitelistedCurve) keySecurityProblem;
if (problem.usageType == UsageType.ENCRYPT) { view.showLayoutEncryptNotWhitelistedCurve(problem.curveOid);
view.showLayoutEncryptNotWhitelistedCurve(problem.curveOid);
} else if (problem.usageType == UsageType.SIGN) {
view.showLayoutSignNotWhitelistedCurve(problem.curveOid);
} else {
throw new IllegalStateException("Should never happen here!");
}
} else if (keySecurityProblem instanceof UnidentifiedKeyProblem) { } else if (keySecurityProblem instanceof UnidentifiedKeyProblem) {
if (keySecurityProblem.usageType == UsageType.ENCRYPT) { view.showLayoutEncryptUnidentifiedKeyProblem();
view.showLayoutEncryptUnidentifiedKeyProblem();
} else if (keySecurityProblem.usageType == UsageType.SIGN) {
view.showLayoutSignUnidentifiedKeyProblem();
} else {
throw new IllegalStateException("Should never happen here!");
}
} else { } else {
throw new IllegalArgumentException("Unhandled key security problem type!"); throw new IllegalArgumentException("Unhandled key security problem type!");
} }
} }
*/
private void setupFromNonKeySecurityProblem(SymmetricAlgorithmProblem securityProblem) { private void setupFromSigningKeySecurityProblem(KeySecurityProblem keySecurityProblem) {
viewKeyMasterKeyId = keySecurityProblem.masterKeyId;
view.showViewKeyButton();
if (keySecurityProblem instanceof InsecureBitStrength) {
InsecureBitStrength problem = (InsecureBitStrength) keySecurityProblem;
view.showLayoutSignInsecureBitsize(problem.algorithm, problem.bitStrength);
} else if (keySecurityProblem instanceof NotWhitelistedCurve) {
NotWhitelistedCurve problem = (NotWhitelistedCurve) keySecurityProblem;
view.showLayoutSignNotWhitelistedCurve(problem.curveOid);
} else if (keySecurityProblem instanceof UnidentifiedKeyProblem) {
view.showLayoutSignUnidentifiedKeyProblem();
} else {
throw new IllegalArgumentException("Unhandled key security problem type!");
}
}
private void setupFromEncryptionAlgorithmSecurityProblem(EncryptionAlgorithmProblem securityProblem) {
if (securityProblem instanceof MissingMdc) { if (securityProblem instanceof MissingMdc) {
view.showLayoutMissingMdc(); view.showLayoutMissingMdc();
} else if (securityProblem instanceof InsecureSymmetricAlgorithm) { } else if (securityProblem instanceof InsecureEncryptionAlgorithm) {
InsecureSymmetricAlgorithm insecureSymmetricAlgorithm = (InsecureSymmetricAlgorithm) securityProblem; InsecureEncryptionAlgorithm insecureSymmetricAlgorithm = (InsecureEncryptionAlgorithm) securityProblem;
view.showLayoutInsecureSymmetric(insecureSymmetricAlgorithm.symmetricAlgorithm); view.showLayoutInsecureSymmetric(insecureSymmetricAlgorithm.symmetricAlgorithm);
} else { } else {
throw new IllegalArgumentException("Unhandled symmetric algorithm problem type!"); throw new IllegalArgumentException("Unhandled symmetric algorithm problem type!");
} }
} }
private void setupFromInsecureHashAlgorithm(InsecureHashAlgorithm securityProblem) { private void setupFromSignatureSecurityProblem(InsecureSigningAlgorithm signatureSecurityProblem) {
view.showLayoutInsecureHashAlgorithm(securityProblem.hashAlgorithm); view.showLayoutInsecureHashAlgorithm(signatureSecurityProblem.hashAlgorithm);
} }
private void setPackageInfo(String packageName) throws NameNotFoundException { private void setPackageInfo(String packageName) throws NameNotFoundException {
@@ -117,6 +128,12 @@ class SecurityProblemPresenter {
view.finishAsCancelled(); view.finishAsCancelled();
} }
void onClickViewKey() {
Intent viewKeyIntent = new Intent(context, ViewKeyActivity.class);
viewKeyIntent.setData(KeyRings.buildGenericKeyRingUri(viewKeyMasterKeyId));
context.startActivity(viewKeyIntent);
}
void onCancel() { void onCancel() {
view.finishAsCancelled(); view.finishAsCancelled();
} }
@@ -136,5 +153,7 @@ class SecurityProblemPresenter {
void showLayoutInsecureSymmetric(int symmetricAlgorithm); void showLayoutInsecureSymmetric(int symmetricAlgorithm);
void showLayoutInsecureHashAlgorithm(int hashAlgorithm); void showLayoutInsecureHashAlgorithm(int hashAlgorithm);
void showViewKeyButton();
} }
} }

View File

@@ -82,6 +82,15 @@
tools:layout_marginBottom="50dp" tools:layout_marginBottom="50dp"
style="?buttonBarStyle"> style="?buttonBarStyle">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View Key"
android:id="@+id/button_view_key"
android:visibility="gone"
tools:visibility="visible"
style="?buttonBarButtonStyle" />
<Button <Button
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -1855,10 +1855,19 @@
<string name="dialog_insecure_title">Security Warning</string> <string name="dialog_insecure_title">Security Warning</string>
<string name="dialog_insecure_recommend_title">Recommended Action</string> <string name="dialog_insecure_recommend_title">Recommended Action</string>
<string name="insecure_msg_bitstrength">"The key this message was sent from is using an outdated algorithm, that is no longer considered secure!\n\nThe algorithm in use is %1$s with %2$s bitstrength, which has been considered insecure since %3$s."</string> <string name="insecure_encrypt_bitstrength">"The key you used to receive this message is using an outdated algorithm!\n\nThe algorithm in use is %1$s with %2$s bitstrength, which has been considered insecure since %3$s."</string>
<string name="insecure_recom_new_key">The key in use is insecure, and cannot be updated. To communicate securely, the sender must create a new key!</string> <string name="insecure_encrypt_bitstrength_suggestion">The key in use is insecure, and cannot be updated. To communicate securely, the sender must create a new key!</string>
<string name="insecure_msg_not_whitelisted_curve">"This "</string> <string name="insecure_sign_bitstrength">"The key this message was sent from is using an outdated algorithm!\n\nThe algorithm in use is %1$s with %2$s bitstrength, which has been considered insecure since %3$s."</string>
<string name="insecure_msg_unidentified_key">"The key used to "</string> <string name="insecure_sign_bitstrength_suggestion">The key in use is insecure, and cannot be updated. To communicate securely, the sender must create a new key!</string>
<string name="insecure_recom_mdc">The sender of this message should update their OpenPGP software.</string> <string name="insecure_encrypt_not_whitelisted_curve">"The key used to receive this message is using an algorithm that is not considered secure!\n\nThe algorithm in use is %1$s, which has not received sufficient cryptanalysis to consider secure."</string>
<string name="insecure_msg_mdc">This message was encrypted with an insecure encryption mechanism. The encrypted message did not include a Modification Detection Code (MDC), which is necessary to ensure message integrity.</string> <string name="insecure_sign_not_whitelisted_curve">"The key this message was sent from is using an outdated algorithm!\n\nThe algorithm in use is %1$s, which has not received sufficient cryptanalysis to consider secure."</string>
<string name="insecure_encrypt_unidentified">"There is an unidentified security problem with the key used to receive (decrypyt) this message!"</string>
<string name="insecure_sign_unidentified">"There is an unidentified security problem with the key used to send (sign) this message!"</string>
<string name="insecure_mdc">"This message was not signed, and did also not contain a Modification Detection Code (MDC). It may have been modified by an attacker!"</string>
<string name="insecure_mdc_suggestion">"For secure end-to-end communication, messages should be signed by the sender."</string>
<string name="insecure_symmetric_algo">"This message was encrypted with an insecure algorithm."</string>
<string name="insecure_hash_algo">"This message was signed using an insecure algorithm."</string>
</resources> </resources>