/* * Copyright (C) 2017 Schürmann & Breitmoser GbR * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package org.sufficientlysecure.keychain.remote.ui; import java.io.Serializable; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import org.sufficientlysecure.keychain.pgp.DecryptVerifySecurityProblem; import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureBitStrength; import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureSigningAlgorithm; import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureEncryptionAlgorithm; import org.sufficientlysecure.keychain.pgp.SecurityProblem.KeySecurityProblem; import org.sufficientlysecure.keychain.pgp.SecurityProblem.MissingMdc; import org.sufficientlysecure.keychain.pgp.SecurityProblem.NotSecureCurve; import org.sufficientlysecure.keychain.pgp.SecurityProblem.EncryptionAlgorithmProblem; import org.sufficientlysecure.keychain.pgp.SecurityProblem.UnidentifiedKeyProblem; import org.sufficientlysecure.keychain.daos.OverriddenWarningsDao; import org.sufficientlysecure.keychain.ui.keyview.ViewKeyActivity; class SecurityProblemPresenter { private static final int OVERRIDE_REQUIRED_COUNT = 3; private final Context context; private final PackageManager packageManager; private final OverriddenWarningsDao overriddenWarningsDao; private RemoteSecurityProblemView view; private Long viewKeyMasterKeyId; private int overrideCounter; private String securityProblemIdentifier; private String packageName; private Serializable securityProblem; private boolean supportOverride; SecurityProblemPresenter(Context context) { this.context = context; packageManager = context.getPackageManager(); overriddenWarningsDao = OverriddenWarningsDao.create(context); } public void setView(RemoteSecurityProblemView view) { this.view = view; } void setupFromIntentData(String packageName, Serializable securityProblem, boolean supportOverride) { this.packageName = packageName; this.securityProblem = securityProblem; this.supportOverride = supportOverride; refreshSecurityProblemDisplay(); refreshPackageInfo(); } private void refreshSecurityProblemDisplay() { if (securityProblem instanceof DecryptVerifySecurityProblem) { setupFromDecryptVerifySecurityProblem((DecryptVerifySecurityProblem) securityProblem); } else { throw new IllegalArgumentException("Unhandled security problem type!"); } } private void setupFromDecryptVerifySecurityProblem(DecryptVerifySecurityProblem securityProblem) { 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) { InsecureBitStrength problem = (InsecureBitStrength) keySecurityProblem; view.showLayoutEncryptInsecureBitsize(problem.algorithm, problem.bitStrength); } else if (keySecurityProblem instanceof NotSecureCurve) { NotSecureCurve problem = (NotSecureCurve) keySecurityProblem; view.showLayoutEncryptNotSecureCurve(problem.curveOid); } else if (keySecurityProblem instanceof UnidentifiedKeyProblem) { view.showLayoutEncryptUnidentifiedKeyProblem(); } else { throw new IllegalArgumentException("Unhandled key security problem type!"); } if (keySecurityProblem.isIdentifiable()) { securityProblemIdentifier = keySecurityProblem.getIdentifier(); refreshOverrideStatusView(); } } 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 NotSecureCurve) { NotSecureCurve problem = (NotSecureCurve) keySecurityProblem; view.showLayoutSignNotSecureCurve(problem.curveOid); } else if (keySecurityProblem instanceof UnidentifiedKeyProblem) { view.showLayoutSignUnidentifiedKeyProblem(); } else { throw new IllegalArgumentException("Unhandled key security problem type!"); } if (keySecurityProblem.isIdentifiable()) { securityProblemIdentifier = keySecurityProblem.getIdentifier(); refreshOverrideStatusView(); } } private void setupFromEncryptionAlgorithmSecurityProblem(EncryptionAlgorithmProblem securityProblem) { if (securityProblem instanceof MissingMdc) { view.showLayoutMissingMdc(); } else if (securityProblem instanceof InsecureEncryptionAlgorithm) { InsecureEncryptionAlgorithm insecureSymmetricAlgorithm = (InsecureEncryptionAlgorithm) securityProblem; view.showLayoutInsecureSymmetric(insecureSymmetricAlgorithm.symmetricAlgorithm); } else { throw new IllegalArgumentException("Unhandled symmetric algorithm problem type!"); } if (securityProblem.isIdentifiable()) { securityProblemIdentifier = securityProblem.getIdentifier(); refreshOverrideStatusView(); } } private void refreshOverrideStatusView() { if (supportOverride) { if (overriddenWarningsDao.isWarningOverridden(securityProblemIdentifier)) { view.showOverrideUndoButton(); } else { view.showOverrideButton(); } } } private void setupFromSignatureSecurityProblem(InsecureSigningAlgorithm signatureSecurityProblem) { view.showLayoutInsecureHashAlgorithm(signatureSecurityProblem.hashAlgorithm); } private void refreshPackageInfo() { ApplicationInfo applicationInfo; try { applicationInfo = packageManager.getApplicationInfo(packageName, 0); } catch (NameNotFoundException e) { throw new IllegalStateException("Could not retrieve package info!"); } Drawable appIcon = packageManager.getApplicationIcon(applicationInfo); // CharSequence appName = packageManager.getApplicationLabel(applicationInfo); view.setTitleClientIcon(appIcon); } private void incrementOverrideAndDisplayOrTrigger() { int overrideCountLeft = OVERRIDE_REQUIRED_COUNT - overrideCounter; if (overrideCountLeft > 0) { overrideCounter++; view.showOverrideMessage(overrideCountLeft); } else { overriddenWarningsDao.putOverride(securityProblemIdentifier); view.finishAsSuppressed(); } } private void resetOverrideStatus() { overrideCounter = 0; overriddenWarningsDao.deleteOverride(securityProblemIdentifier); } void onClickGotIt() { view.finishAsCancelled(); } void onClickViewKey() { Intent intent = new Intent(context, ViewKeyActivity.class); intent.putExtra(ViewKeyActivity.EXTRA_MASTER_KEY_ID, viewKeyMasterKeyId); context.startActivity(intent); } void onClickOverride() { incrementOverrideAndDisplayOrTrigger(); } void onClickOverrideUndo() { resetOverrideStatus(); refreshSecurityProblemDisplay(); } void onClickOverrideBack() { resetOverrideStatus(); refreshSecurityProblemDisplay(); } void onClickOverrideConfirm() { incrementOverrideAndDisplayOrTrigger(); } void onCancel() { view.finishAsCancelled(); } interface RemoteSecurityProblemView { void finishAsCancelled(); void finishAsSuppressed(); void setTitleClientIcon(Drawable drawable); void showLayoutEncryptInsecureBitsize(int algorithmId, int bitStrength); void showLayoutEncryptNotSecureCurve(String curveOid); void showLayoutEncryptUnidentifiedKeyProblem(); void showLayoutSignInsecureBitsize(int algorithmId, int bitStrength); void showLayoutSignNotSecureCurve(String curveOid); void showLayoutSignUnidentifiedKeyProblem(); void showLayoutMissingMdc(); void showLayoutInsecureSymmetric(int symmetricAlgorithm); void showLayoutInsecureHashAlgorithm(int hashAlgorithm); void showOverrideMessage(int countdown); void showViewKeyButton(); void showOverrideButton(); void showOverrideUndoButton(); } }