From 65362beaf9f976d6d6e6da6a4ef41adeec8ca43b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 7 Jul 2015 22:19:20 +0200 Subject: move queued action handling from prev commit into onActivityCreated --- .../keychain/ui/CreateKeyFinalFragment.java | 58 ++++++++++------------ 1 file changed, 27 insertions(+), 31 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index a997dc545..6e41e97a8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -225,6 +225,33 @@ public class CreateKeyFinalFragment extends Fragment { } } } + + // handle queued actions + + if (mQueuedFinishResult != null) { + finishWithResult(mQueuedFinishResult); + return; + } + + if (mQueuedDisplayResult != null) { + try { + displayResult(mQueuedDisplayResult); + } finally { + // clear after operation, note that this may drop the operation if it didn't + // work when called from here! + mQueuedDisplayResult = null; + } + } + + if (mQueuedSaveKeyResult != null) { + try { + uploadKey(mQueuedSaveKeyResult); + } finally { + // see above + mQueuedSaveKeyResult = null; + } + } + } private void createKey() { @@ -433,35 +460,4 @@ public class CreateKeyFinalFragment extends Fragment { activity.finish(); } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - // there may be queued actions from when we weren't attached to an activity! - - if (mQueuedFinishResult != null) { - finishWithResult(mQueuedFinishResult); - return; - } - - if (mQueuedDisplayResult != null) { - try { - displayResult(mQueuedDisplayResult); - } finally { - // clear after operation, note that this may drop the operation if it didn't - // work when called from here! - mQueuedDisplayResult = null; - } - } - - if (mQueuedSaveKeyResult != null) { - try { - uploadKey(mQueuedSaveKeyResult); - } finally { - // see above - mQueuedSaveKeyResult = null; - } - } - } - } -- cgit v1.2.3 From 895d1fbef65b1247ac9f08ccb50d1a42b0ca86a4 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 7 Jul 2015 23:41:44 +0200 Subject: try cache in certify operation (fixes #1242) --- .../keychain/operations/CertifyOperation.java | 15 ++- .../keychain/ui/CertifyKeyFragment.java | 5 - .../keychain/ui/ViewKeyActivity.java | 106 +++++++++------------ .../keychain/ui/base/CryptoOperationHelper.java | 7 +- OpenKeychain/src/main/res/values/strings.xml | 2 + 5 files changed, 61 insertions(+), 74 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java index 318eee6ba..d0377cc24 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -29,6 +29,7 @@ import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; +import org.sufficientlysecure.keychain.pgp.PassphraseCacheInterface; import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation; import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult; import org.sufficientlysecure.keychain.pgp.Progressable; @@ -90,14 +91,21 @@ public class CertifyOperation extends BaseOperation { case PIN: case PATTERN: case PASSPHRASE: - if (!cryptoInput.hasPassphrase()) { + passphrase = cryptoInput.getPassphrase(); + if (passphrase == null) { + try { + passphrase = getCachedPassphrase(certificationKey.getKeyId(), certificationKey.getKeyId()); + } catch (PassphraseCacheInterface.NoSecretKeyException ignored) { + // treat as a cache miss for error handling purposes + } + } + + if (passphrase == null) { return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase( certificationKey.getKeyId(), certificationKey.getKeyId(), null) ); } - // certification is always with the master key id, so use that one - passphrase = cryptoInput.getPassphrase(); break; case PASSPHRASE_EMPTY: @@ -105,6 +113,7 @@ public class CertifyOperation extends BaseOperation { break; case DIVERT_TO_CARD: + // the unlock operation will succeed for passphrase == null in a divertToCard key passphrase = null; break; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index ab631c6fe..9d6e7d096 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -331,9 +331,4 @@ public class CertifyKeyFragment getActivity().finish(); } - @Override - public void onCryptoOperationCancelled() { - super.onCryptoOperationCancelled(); - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index da3aae123..a50696cf3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -31,7 +31,6 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.os.Handler.Callback; import android.os.Message; import android.os.Messenger; import android.provider.ContactsContract; @@ -57,7 +56,6 @@ import com.getbase.floatingactionbutton.FloatingActionButton; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.operations.results.CertifyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; @@ -67,10 +65,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; @@ -102,6 +97,8 @@ public class ViewKeyActivity extends BaseNfcActivity implements static final int REQUEST_QR_FINGERPRINT = 1; static final int REQUEST_DELETE = 2; static final int REQUEST_EXPORT = 3; + static final int REQUEST_CERTIFY = 4; + public static final String EXTRA_DISPLAY_RESULT = "display_result"; ProviderHelper mProviderHelper; @@ -158,6 +155,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements super.onCreate(savedInstanceState); mProviderHelper = new ProviderHelper(this); + mOperationHelper = new CryptoOperationHelper<>(this, this, null); setTitle(null); @@ -382,37 +380,14 @@ public class ViewKeyActivity extends BaseNfcActivity implements Intent intent = new Intent(this, CertifyFingerprintActivity.class); intent.setData(dataUri); - startCertifyIntent(intent); + startActivityForResult(intent, REQUEST_CERTIFY); } private void certifyImmediate() { Intent intent = new Intent(this, CertifyKeyActivity.class); intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{mMasterKeyId}); - startCertifyIntent(intent); - } - - private void startCertifyIntent(Intent intent) { - // Message is received after signing is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler(this) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - Bundle data = message.getData(); - CertifyResult result = data.getParcelable(CertifyResult.EXTRA_RESULT); - - result.createNotify(ViewKeyActivity.this).show(); - } - } - }; - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - startActivityForResult(intent, 0); + startActivityForResult(intent, REQUEST_CERTIFY); } private void showQrCodeDialog() { @@ -482,49 +457,58 @@ public class ViewKeyActivity extends BaseNfcActivity implements @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (mOperationHelper != null) { - mOperationHelper.handleActivityResult(requestCode, resultCode, data); + if (mOperationHelper.handleActivityResult(requestCode, resultCode, data)) { + return; + } + + if (resultCode != Activity.RESULT_OK) { + return; } - if (requestCode == REQUEST_QR_FINGERPRINT && resultCode == Activity.RESULT_OK) { + switch (requestCode) { + case REQUEST_QR_FINGERPRINT: { + + // If there is an EXTRA_RESULT, that's an error. Just show it. + if (data.hasExtra(OperationResult.EXTRA_RESULT)) { + OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT); + result.createNotify(this).show(); + return; + } - // If there is an EXTRA_RESULT, that's an error. Just show it. - if (data.hasExtra(OperationResult.EXTRA_RESULT)) { - OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT); - result.createNotify(this).show(); + String fp = data.getStringExtra(ImportKeysProxyActivity.EXTRA_FINGERPRINT); + if (fp == null) { + Notify.create(this, R.string.error_scan_fp, Notify.LENGTH_LONG, Style.ERROR).show(); + return; + } + if (mFingerprint.equalsIgnoreCase(fp)) { + certifyImmediate(); + } else { + Notify.create(this, R.string.error_scan_match, Notify.LENGTH_LONG, Style.ERROR).show(); + } return; } - String fp = data.getStringExtra(ImportKeysProxyActivity.EXTRA_FINGERPRINT); - if (fp == null) { - Notify.create(this, "Error scanning fingerprint!", - Notify.LENGTH_LONG, Notify.Style.ERROR).show(); + case REQUEST_DELETE: { + deleteKey(); return; } - if (mFingerprint.equalsIgnoreCase(fp)) { - certifyImmediate(); - } else { - Notify.create(this, "Fingerprints did not match!", - Notify.LENGTH_LONG, Notify.Style.ERROR).show(); - } - return; - } + case REQUEST_EXPORT: { + exportToFile(mDataUri, mProviderHelper); + return; + } - if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK) { - deleteKey(); + case REQUEST_CERTIFY: { + if (data.hasExtra(OperationResult.EXTRA_RESULT)) { + OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT); + result.createNotify(this).show(); + } + return; + } } - if (requestCode == REQUEST_EXPORT && resultCode == Activity.RESULT_OK) { - exportToFile(mDataUri, mProviderHelper); - } + super.onActivityResult(requestCode, resultCode, data); - if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) { - OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT); - result.createNotify(this).show(); - } else { - super.onActivityResult(requestCode, resultCode, data); - } } @Override @@ -863,6 +847,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements mActionNfc.setVisibility(View.GONE); } mFab.setVisibility(View.VISIBLE); + // noinspection deprecation (no getDrawable with theme at current minApi level 15!) mFab.setIconDrawable(getResources().getDrawable(R.drawable.ic_repeat_white_24dp)); } else { mActionEncryptFile.setVisibility(View.VISIBLE); @@ -952,7 +937,6 @@ public class ViewKeyActivity extends BaseNfcActivity implements mKeyserver = cloudPrefs.keyserver; } - mOperationHelper = new CryptoOperationHelper<>(this, this, null); mOperationHelper.cryptoOperation(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java index 0db46a585..f72e87ca7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java @@ -208,12 +208,9 @@ public class CryptoOperationHelper"Original file could not be deleted!" "Clipboard is empty!" "Error copying data to clipboard!" + Error scanning fingerprint! + Fingerprints did not match! -- cgit v1.2.3 From 310228f6ba4898916d900e052947986525d706d3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 7 Jul 2015 23:43:23 +0200 Subject: introduce QueueingCryptoOperationFragment to queue result handling in detached state --- .../keychain/ui/CertifyKeyFragment.java | 10 ++- .../keychain/ui/EncryptFilesFragment.java | 7 +-- .../keychain/ui/EncryptTextFragment.java | 2 +- .../ui/base/CachingCryptoOperationFragment.java | 9 +-- .../ui/base/QueueingCryptoOperationFragment.java | 72 ++++++++++++++++++++++ 5 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/QueueingCryptoOperationFragment.java (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index 9d6e7d096..467eab785 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -324,11 +324,15 @@ public class CertifyKeyFragment } @Override - public void onCryptoOperationSuccess(CertifyResult result) { + public void onQueuedOperationSuccess(CertifyResult result) { + // protected by Queueing*Fragment + Activity activity = getActivity(); + Intent intent = new Intent(); intent.putExtra(CertifyResult.EXTRA_RESULT, result); - getActivity().setResult(Activity.RESULT_OK, intent); - getActivity().finish(); + activity.setResult(Activity.RESULT_OK, intent); + activity.finish(); + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java index b382e31d0..7b2796c69 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -387,13 +387,10 @@ public class EncryptFilesFragment } @Override - public void onCryptoOperationSuccess(final SignEncryptResult result) { + public void onQueuedOperationSuccess(final SignEncryptResult result) { + // protected by Queueing*Fragment FragmentActivity activity = getActivity(); - if (activity == null) { - // it's gone, there's nothing we can do here - return; - } if (mDeleteAfterEncrypt) { // TODO make behavior coherent here diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java index 8d3738fbd..e307a85f8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -331,7 +331,7 @@ public class EncryptTextFragment } @Override - public void onCryptoOperationSuccess(SignEncryptResult result) { + public void onQueuedOperationSuccess(SignEncryptResult result) { if (mShareAfterEncrypt) { // Share encrypted message/file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java index 38b7075f2..9ce33f5a6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java @@ -4,12 +4,11 @@ package org.sufficientlysecure.keychain.ui.base; import android.os.Bundle; import android.os.Parcelable; -import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult; public abstract class CachingCryptoOperationFragment - extends CryptoOperationFragment { + extends QueueingCryptoOperationFragment { public static final String ARG_CACHED_ACTIONS = "cached_actions"; @@ -32,12 +31,14 @@ public abstract class CachingCryptoOperationFragment + extends CryptoOperationFragment { + + public static final String ARG_QUEUED_RESULT = "queued_result"; + private S mQueuedResult; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (mQueuedResult != null) { + try { + if (mQueuedResult.success()) { + onQueuedOperationSuccess(mQueuedResult); + } else { + onQueuedOperationError(mQueuedResult); + } + } finally { + mQueuedResult = null; + } + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + outState.putParcelable(ARG_QUEUED_RESULT, mQueuedResult); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (savedInstanceState != null) { + mQueuedResult = savedInstanceState.getParcelable(ARG_QUEUED_RESULT); + } + } + + public abstract void onQueuedOperationSuccess(S result); + + public void onQueuedOperationError(S result) { + super.onCryptoOperationError(result); + } + + @Override + final public void onCryptoOperationSuccess(S result) { + if (getActivity() == null) { + mQueuedResult = result; + return; + } + onQueuedOperationSuccess(result); + } + + @Override + final public void onCryptoOperationError(S result) { + if (getActivity() == null) { + mQueuedResult = result; + return; + } + onQueuedOperationError(result); + } +} -- cgit v1.2.3 From 587e7d088b3f3d2d57231a91e2e5c2c0c0f97983 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 7 Jul 2015 23:57:12 +0200 Subject: use QueueingCryptoOperationFragment in all other places --- .../keychain/ui/DecryptListFragment.java | 17 ++++------------- .../keychain/ui/EditKeyFragment.java | 15 +++++++++------ .../keychain/ui/ViewKeyYubiKeyFragment.java | 6 ++++-- .../keychain/ui/base/CryptoOperationFragment.java | 2 +- .../ui/base/QueueingCryptoOperationFragment.java | 20 ++++++++++++++++++++ 5 files changed, 38 insertions(+), 22 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index da6dfcbd0..b38968753 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -66,10 +66,10 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider; // this import NEEDS to be above the ViewModel one, or it won't compile! (as of 06/06/15) +import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.StatusHolder; import org.sufficientlysecure.keychain.ui.DecryptListFragment.DecryptFilesAdapter.ViewModel; import org.sufficientlysecure.keychain.ui.adapter.SpacesItemDecoration; -import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; @@ -80,7 +80,7 @@ import org.sufficientlysecure.keychain.util.ParcelableHashMap; public class DecryptListFragment - extends CryptoOperationFragment + extends QueueingCryptoOperationFragment implements OnMenuItemClickListener { public static final String ARG_INPUT_URIS = "input_uris"; @@ -195,15 +195,6 @@ public class DecryptListFragment cryptoOperation(); } - private String removeEncryptedAppend(String name) { - if (name.endsWith(Constants.FILE_EXTENSION_ASC) - || name.endsWith(Constants.FILE_EXTENSION_PGP_MAIN) - || name.endsWith(Constants.FILE_EXTENSION_PGP_ALTERNATE)) { - return name.substring(0, name.length() - 4); - } - return name; - } - private void askForOutputFilename(Uri inputUri, String originalFilename, String mimeType) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { File file = new File(inputUri.getPath()); @@ -257,7 +248,7 @@ public class DecryptListFragment return true; } @Override - public void onCryptoOperationError(DecryptVerifyResult result) { + public void onQueuedOperationError(DecryptVerifyResult result) { final Uri uri = mCurrentInputUri; mCurrentInputUri = null; @@ -267,7 +258,7 @@ public class DecryptListFragment } @Override - public void onCryptoOperationSuccess(DecryptVerifyResult result) { + public void onQueuedOperationSuccess(DecryptVerifyResult result) { Uri uri = mCurrentInputUri; mCurrentInputUri = null; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index b9f961d70..4e9c5a836 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -57,7 +57,7 @@ import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter; import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter; -import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; +import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.dialog.AddSubkeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.AddUserIdDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment; @@ -68,7 +68,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; -public class EditKeyFragment extends CryptoOperationFragment +public class EditKeyFragment extends QueueingCryptoOperationFragment implements LoaderManager.LoaderCallbacks { public static final String ARG_DATA_URI = "uri"; @@ -192,7 +192,7 @@ public class EditKeyFragment extends CryptoOperationFragment finish, return result to showkey and display there! Intent intent = new Intent(); intent.putExtra(OperationResult.EXTRA_RESULT, result); - getActivity().setResult(EditKeyActivity.RESULT_OK, intent); - getActivity().finish(); + activity.setResult(EditKeyActivity.RESULT_OK, intent); + activity.finish(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java index 116d082d0..b788e8899 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java @@ -40,11 +40,12 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.service.PromoteKeyringParcel; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; +import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; public class ViewKeyYubiKeyFragment - extends CryptoOperationFragment + extends QueueingCryptoOperationFragment implements LoaderCallbacks { public static final String ARG_MASTER_KEY_ID = "master_key_id"; @@ -214,7 +215,8 @@ public class ViewKeyYubiKeyFragment } @Override - public void onCryptoOperationSuccess(PromoteKeyResult result) { + public void onQueuedOperationSuccess(PromoteKeyResult result) { result.createNotify(getActivity()).show(); } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java index bb0af5830..e77a05dc2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java @@ -46,7 +46,7 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; * @see KeychainService * */ -public abstract class CryptoOperationFragment +abstract class CryptoOperationFragment extends Fragment implements CryptoOperationHelper.Callback { final private CryptoOperationHelper mOperationHelper; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/QueueingCryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/QueueingCryptoOperationFragment.java index a8acaad4c..65b0ac0de 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/QueueingCryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/QueueingCryptoOperationFragment.java @@ -7,12 +7,32 @@ import android.os.Parcelable; import org.sufficientlysecure.keychain.operations.results.OperationResult; +/** CryptoOperationFragment which calls crypto operation results only while + * attached to Activity. + * + * This subclass of CryptoOperationFragment substitutes the onCryptoOperation* + * methods for onQueuedOperation* ones, which are ensured to be called while + * the fragment is attached to an Activity, possibly delaying the call until + * the Fragment is re-attached. + * + * TODO merge this functionality into CryptoOperationFragment? + * + * @see CryptoOperationFragment + */ public abstract class QueueingCryptoOperationFragment extends CryptoOperationFragment { public static final String ARG_QUEUED_RESULT = "queued_result"; private S mQueuedResult; + public QueueingCryptoOperationFragment() { + super(); + } + + public QueueingCryptoOperationFragment(Integer initialProgressMsg) { + super(initialProgressMsg); + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); -- cgit v1.2.3 From ac2c8f994e42f063ad9229c2ea511599b6adb70f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 8 Jul 2015 00:01:39 +0200 Subject: (missed a couple files in last commit) --- .../keychain/ui/CreateYubiKeyImportFragment.java | 14 +++++++++----- .../keychain/ui/ViewKeyYubiKeyFragment.java | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java index 9e3dce28f..e0adf0b93 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.ui; + import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -39,7 +40,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.NfcListenerFragment; -import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; +import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.Preferences; @@ -47,7 +48,7 @@ import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; public class CreateYubiKeyImportFragment - extends CryptoOperationFragment + extends QueueingCryptoOperationFragment implements NfcListenerFragment { private static final String ARG_FINGERPRINT = "fingerprint"; @@ -246,14 +247,17 @@ public class CreateYubiKeyImportFragment } @Override - public void onCryptoOperationSuccess(ImportKeyResult result) { + public void onQueuedOperationSuccess(ImportKeyResult result) { long[] masterKeyIds = result.getImportedMasterKeyIds(); if (masterKeyIds.length == 0) { super.onCryptoOperationError(result); return; } - Intent intent = new Intent(getActivity(), ViewKeyActivity.class); + // null-protected from Queueing*Fragment + Activity activity = getActivity(); + + Intent intent = new Intent(activity, ViewKeyActivity.class); // use the imported masterKeyId, not the one from the yubikey, because // that one might* just have been a subkey of the imported key intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyIds[0])); @@ -262,6 +266,6 @@ public class CreateYubiKeyImportFragment intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId); intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints); startActivity(intent); - getActivity().finish(); + activity.finish(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java index b788e8899..eeb0cff38 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; + import java.nio.ByteBuffer; import java.util.Arrays; @@ -39,7 +40,6 @@ import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.service.PromoteKeyringParcel; -import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -- cgit v1.2.3 From 642f83c1f4a69e513334321f7f5810bdfc7f1ad2 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 8 Jul 2015 01:41:55 +0200 Subject: better handling of divert-to-card keys for subkey modifications --- .../operations/results/OperationResult.java | 1 + .../keychain/pgp/PgpKeyOperation.java | 75 ++++++++++++++-------- OpenKeychain/src/main/res/values/strings.xml | 1 + .../keychain/pgp/PgpKeyOperationTest.java | 34 ++++++++-- .../pgp/UncachedKeyringCanonicalizeTest.java | 5 +- 5 files changed, 81 insertions(+), 35 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index 5ae068b35..a54ddff68 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -499,6 +499,7 @@ public abstract class OperationResult implements Parcelable { MSG_MF_ERROR_RESTRICTED(LogLevel.ERROR, R.string.msg_mf_error_restricted), MSG_MF_ERROR_REVOKED_PRIMARY (LogLevel.ERROR, R.string.msg_mf_error_revoked_primary), MSG_MF_ERROR_SIG (LogLevel.ERROR, R.string.msg_mf_error_sig), + MSG_MF_ERROR_SUB_STRIPPED(LogLevel.ERROR, R.string.msg_mf_error_sub_stripped), MSG_MF_ERROR_SUBKEY_MISSING(LogLevel.ERROR, R.string.msg_mf_error_subkey_missing), MSG_MF_ERROR_CONFLICTING_NFC_COMMANDS(LogLevel.ERROR, R.string.msg_mf_error_conflicting_nfc_commands), MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT(LogLevel.ERROR, R.string.msg_mf_error_duplicate_keytocard_for_slot), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 8445272fc..414ed1f62 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -897,18 +897,35 @@ public class PgpKeyOperation { pKey = PGPPublicKey.removeCertification(pKey, sig); } - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - cryptoInput.getPassphrase().getCharArray()); - PGPPrivateKey subPrivateKey = sKey.extractPrivateKey(keyDecryptor); - PGPSignature sig = generateSubkeyBindingSignature( - getSignatureGenerator(masterSecretKey, cryptoInput), - cryptoInput.getSignatureTime(), - masterPublicKey, masterPrivateKey, subPrivateKey, pKey, flags, expiry); + PGPPrivateKey subPrivateKey; + if (!isDivertToCard(sKey)) { + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + cryptoInput.getPassphrase().getCharArray()); + subPrivateKey = sKey.extractPrivateKey(keyDecryptor); + // super special case: subkey is allowed to sign, but isn't available + if (subPrivateKey == null) { + log.add(LogType.MSG_MF_ERROR_SUB_STRIPPED, + indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); + } + } else { + subPrivateKey = null; + } + try { + PGPSignature sig = generateSubkeyBindingSignature( + getSignatureGenerator(masterSecretKey, cryptoInput), + cryptoInput.getSignatureTime(), masterPublicKey, masterPrivateKey, + getSignatureGenerator(sKey, cryptoInput), subPrivateKey, + pKey, flags, expiry); + + // generate and add new signature + pKey = PGPPublicKey.addCertification(pKey, sig); + sKR = PGPSecretKeyRing.insertSecretKey(sKR, PGPSecretKey.replacePublicKey(sKey, pKey)); + } catch (NfcInteractionNeeded e) { + nfcSignOps.addHash(e.hashToSign, e.hashAlgo); + } - // generate and add new signature - pKey = PGPPublicKey.addCertification(pKey, sig); - sKR = PGPSecretKeyRing.insertSecretKey(sKR, PGPSecretKey.replacePublicKey(sKey, pKey)); } subProgressPop(); @@ -987,7 +1004,8 @@ public class PgpKeyOperation { PGPSignature cert = generateSubkeyBindingSignature( getSignatureGenerator(masterSecretKey, cryptoInput), cryptoInput.getSignatureTime(), - masterPublicKey, masterPrivateKey, keyPair.getPrivateKey(), pKey, + masterPublicKey, masterPrivateKey, + getSignatureGenerator(pKey, cryptoInput, false), keyPair.getPrivateKey(), pKey, add.mFlags, add.mExpiry); pKey = PGPPublicKey.addSubkeyBindingCertification(pKey, cert); } catch (NfcInteractionNeeded e) { @@ -1002,7 +1020,8 @@ public class PgpKeyOperation { PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - cryptoInput.getPassphrase().getCharArray()); + cryptoInput.hasPassphrase() + ? cryptoInput.getPassphrase().getCharArray() : new char[]{} ); PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder() .build().get(PgpConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO); @@ -1402,22 +1421,27 @@ public class PgpKeyOperation { static PGPSignatureGenerator getSignatureGenerator( PGPSecretKey secretKey, CryptoInputParcel cryptoInput) { - PGPContentSignerBuilder builder; - S2K s2k = secretKey.getS2K(); - if (s2k != null && s2k.getType() == S2K.GNU_DUMMY_S2K - && s2k.getProtectionMode() == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD) { + boolean isDivertToCard = s2k != null && s2k.getType() == S2K.GNU_DUMMY_S2K + && s2k.getProtectionMode() == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD; + + return getSignatureGenerator(secretKey.getPublicKey(), cryptoInput, isDivertToCard); + } + + static PGPSignatureGenerator getSignatureGenerator( + PGPPublicKey pKey, CryptoInputParcel cryptoInput, boolean divertToCard) { + + PGPContentSignerBuilder builder; + if (divertToCard) { // use synchronous "NFC based" SignerBuilder builder = new NfcSyncPGPContentSignerBuilder( - secretKey.getPublicKey().getAlgorithm(), - PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO, - secretKey.getKeyID(), cryptoInput.getCryptoData()) + pKey.getAlgorithm(), PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO, + pKey.getKeyID(), cryptoInput.getCryptoData()) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); } else { // content signer based on signing key algorithm and chosen hash algorithm builder = new JcaPGPContentSignerBuilder( - secretKey.getPublicKey().getAlgorithm(), - PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO) + pKey.getAlgorithm(), PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); } @@ -1524,7 +1548,8 @@ public class PgpKeyOperation { static PGPSignature generateSubkeyBindingSignature( PGPSignatureGenerator sGen, Date creationTime, PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey, - PGPPrivateKey subPrivateKey, PGPPublicKey pKey, int flags, long expiry) + PGPSignatureGenerator subSigGen, PGPPrivateKey subPrivateKey, PGPPublicKey pKey, + int flags, long expiry) throws IOException, PGPException, SignatureException { PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); @@ -1534,10 +1559,6 @@ public class PgpKeyOperation { // cross-certify signing keys PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); subHashedPacketsGen.setSignatureCreationTime(false, creationTime); - PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - pKey.getAlgorithm(), PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureGenerator subSigGen = new PGPSignatureGenerator(signerBuilder); subSigGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey); subSigGen.setHashedSubpackets(subHashedPacketsGen.generate()); PGPSignature certification = subSigGen.generateCertification(masterPublicKey, pKey); diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index cae2faef2..1be726447 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -991,6 +991,7 @@ "Fatal error decrypting master key! This is likely a programming error, please file a bug report!" "Internal OpenPGP error!" "Signature exception!" + "Cannot modify stripped subkey %s!" "Tried to operate on missing subkey %s!" "Cannot move key to smart card in same operation that creates an on-card signature." "Smart card supports only one slot per key type." diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index f32730b47..c0e28cd4b 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -94,11 +94,11 @@ public class PgpKeyOperationTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.DSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -821,6 +821,15 @@ public class PgpKeyOperationTest { Assert.assertEquals("new packet should have GNU_DUMMY protection mode stripped", S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY, ((SecretKeyPacket) p).getS2K().getProtectionMode()); } + + { // trying to edit a subkey with signing capability should fail + parcel.reset(); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true)); + + assertModifyFailure("subkey modification for signing-enabled but stripped subkey should fail", + modified, parcel, LogType.MSG_MF_ERROR_SUB_STRIPPED); + } + } @Test @@ -829,7 +838,7 @@ public class PgpKeyOperationTest { UncachedKeyRing modified; { // keytocard should fail with BAD_NFC_SIZE when presented with the RSA-1024 key - long keyId = KeyringTestingHelper.getSubkeyId(ring, 0); + long keyId = KeyringTestingHelper.getSubkeyId(ring, 2); parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); @@ -838,7 +847,7 @@ public class PgpKeyOperationTest { } { // keytocard should fail with BAD_NFC_ALGO when presented with the DSA-1024 key - long keyId = KeyringTestingHelper.getSubkeyId(ring, 1); + long keyId = KeyringTestingHelper.getSubkeyId(ring, 0); parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); @@ -846,9 +855,10 @@ public class PgpKeyOperationTest { parcel, cryptoInput, LogType.MSG_MF_ERROR_BAD_NFC_ALGO); } + long keyId = KeyringTestingHelper.getSubkeyId(ring, 1); + { // keytocard should return a pending NFC_MOVE_KEY_TO_CARD result when presented with the RSA-2048 // key, and then make key divert-to-card when it gets a serial in the cryptoInputParcel. - long keyId = KeyringTestingHelper.getSubkeyId(ring, 2); parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); @@ -880,7 +890,19 @@ public class PgpKeyOperationTest { S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD, ((SecretKeyPacket) p).getS2K().getProtectionMode()); Assert.assertArrayEquals("new packet should have correct serial number as iv", serial, ((SecretKeyPacket) p).getIV()); + } + + { // editing a signing subkey requires a primary key binding sig -> pendinginput + parcel.reset(); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true)); + CanonicalizedSecretKeyRing secretRing = + new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0); + PgpKeyOperation op = new PgpKeyOperation(null); + PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcel); + Assert.assertTrue("keytocard operation should be pending", result.isPending()); + Assert.assertEquals("required input should be RequiredInputType.NFC_SIGN", + RequiredInputType.NFC_SIGN, result.getRequiredInputParcel().mType); } } diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 0143ae289..ad4c1fb75 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -558,8 +558,9 @@ public class UncachedKeyringCanonicalizeTest { PGPSignature cert = PgpKeyOperation.generateSubkeyBindingSignature( PgpKeyOperation.getSignatureGenerator(masterSecretKey.getSecretKey(), cryptoInput), cryptoInput.getSignatureTime(), - masterPublicKey, masterSecretKey.getPrivateKey(), masterSecretKey.getPrivateKey(), - masterPublicKey, masterSecretKey.getKeyUsage(), 0); + masterPublicKey, masterSecretKey.getPrivateKey(), + PgpKeyOperation.getSignatureGenerator(masterSecretKey.getSecretKey(), null), + masterSecretKey.getPrivateKey(), masterPublicKey, masterSecretKey.getKeyUsage(), 0); PGPPublicKey subPubKey = PGPPublicKey.addSubkeyBindingCertification(masterPublicKey, cert); PGPSecretKey sKey; -- cgit v1.2.3 From d9b07625e8b492d2d3b0ee5b0c898c3315b31439 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 8 Jul 2015 01:42:13 +0200 Subject: addition of subkeys for divert-to-card primary keys is not supported --- .../keychain/operations/results/OperationResult.java | 1 + .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 8 ++++++-- OpenKeychain/src/main/res/values/strings.xml | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index a54ddff68..9da3b94af 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -482,6 +482,7 @@ public abstract class OperationResult implements Parcelable { // secret key modify MSG_MF (LogLevel.START, R.string.msg_mr), MSG_MF_DIVERT (LogLevel.DEBUG, R.string.msg_mf_divert), + MSG_MF_ERROR_DIVERT_NEWSUB (LogLevel.ERROR, R.string.msg_mf_error_divert_newsub), MSG_MF_ERROR_DIVERT_SERIAL (LogLevel.ERROR, R.string.msg_mf_error_divert_serial), MSG_MF_ERROR_ENCODE (LogLevel.ERROR, R.string.msg_mf_error_encode), MSG_MF_ERROR_FINGERPRINT (LogLevel.ERROR, R.string.msg_mf_error_fingerprint), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 414ed1f62..440d57d36 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -976,6 +976,11 @@ public class PgpKeyOperation { log.add(LogType.MSG_MF_SUBKEY_NEW, indent, KeyFormattingUtils.getAlgorithmInfo(add.mAlgorithm, add.mKeySize, add.mCurve) ); + if (isDivertToCard(masterSecretKey)) { + log.add(LogType.MSG_MF_ERROR_DIVERT_NEWSUB, indent +1); + return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null); + } + if (add.mExpiry == null) { log.add(LogType.MSG_MF_ERROR_NULL_EXPIRY, indent +1); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); @@ -1020,8 +1025,7 @@ public class PgpKeyOperation { PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - cryptoInput.hasPassphrase() - ? cryptoInput.getPassphrase().getCharArray() : new char[]{} ); + cryptoInput.getPassphrase().getCharArray()); PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder() .build().get(PgpConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO); diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 1be726447..5918d9e96 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -976,6 +976,7 @@ "Modifying keyring %s" "Will divert to smart card for crypto operations" + "Creation of new subkeys is not supported for 'divert-to-card' primary keys!" "The serial number of a 'divert-to-card' key must be 16 bytes! This is a programming error, please file a bug report!" "Encoding exception!" "Actual key fingerprint does not match the expected one!" -- cgit v1.2.3 From 510999c3a2de2475f7828e283d4f01e46a4fe9f7 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 8 Jul 2015 02:28:05 +0200 Subject: fix result type for divert-to-card new subkey error --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 440d57d36..5eaa03394 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -978,7 +978,7 @@ public class PgpKeyOperation { if (isDivertToCard(masterSecretKey)) { log.add(LogType.MSG_MF_ERROR_DIVERT_NEWSUB, indent +1); - return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null); + return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } if (add.mExpiry == null) { -- cgit v1.2.3 From 3af97bf0e6a711679343a86823b6639917787218 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 8 Jul 2015 02:29:04 +0200 Subject: some cleanup and fix for back button in ImportKeysActivity (fixes #1372) --- .../sufficientlysecure/keychain/ui/DecryptActivity.java | 8 +------- .../keychain/ui/DisplayTextActivity.java | 8 +------- .../keychain/ui/EncryptFilesActivity.java | 8 ++------ .../keychain/ui/EncryptTextActivity.java | 8 ++------ .../keychain/ui/ImportKeysActivity.java | 3 +++ .../keychain/ui/ImportKeysProxyActivity.java | 1 - .../sufficientlysecure/keychain/ui/base/BaseActivity.java | 15 ++++++++++++--- 7 files changed, 21 insertions(+), 30 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 04f54f151..2f75e4a9c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -49,13 +49,7 @@ public class DecryptActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setFullScreenDialogClose(new View.OnClickListener() { - @Override - public void onClick(View v) { - setResult(Activity.RESULT_CANCELED); - finish(); - } - }, false); + setFullScreenDialogClose(Activity.RESULT_CANCELED, false); // Handle intent actions handleActions(savedInstanceState, getIntent()); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DisplayTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DisplayTextActivity.java index be21cdde1..3c8e972b9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DisplayTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DisplayTextActivity.java @@ -41,13 +41,7 @@ public class DisplayTextActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setFullScreenDialogClose(new View.OnClickListener() { - @Override - public void onClick(View v) { - setResult(Activity.RESULT_CANCELED); - finish(); - } - }, false); + setFullScreenDialogClose(Activity.RESULT_CANCELED, false); // Handle intent actions handleActions(savedInstanceState, getIntent()); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java index d51b6e0ff..136787984 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; +import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -41,12 +42,7 @@ public class EncryptFilesActivity extends EncryptActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setFullScreenDialogClose(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }, false); + setFullScreenDialogClose(Activity.RESULT_OK, false); Intent intent = getIntent(); String action = intent.getAction(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java index cb26ea452..a849cdf12 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; +import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.FragmentTransaction; @@ -39,12 +40,7 @@ public class EncryptTextActivity extends EncryptActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setFullScreenDialogClose(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }, false); + setFullScreenDialogClose(Activity.RESULT_OK, false); Intent intent = getIntent(); String action = intent.getAction(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 2e8e6f6bd..076d6aed3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.ui; +import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -95,6 +96,8 @@ public class ImportKeysActivity extends BaseNfcActivity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setFullScreenDialogClose(Activity.RESULT_CANCELED, true); + mProxyPrefs = Preferences.getPreferences(this).getProxyPrefs(); mImportButton = findViewById(R.id.import_import); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java index f45f1b350..663ac3311 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java @@ -257,7 +257,6 @@ public class ImportKeysProxyActivity extends FragmentActivity Intent data = new Intent(); data.putExtras(returnData); returnResult(data); - return; } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java index 847d76f30..9529d8689 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java @@ -87,9 +87,7 @@ public abstract class BaseActivity extends AppCompatActivity { mToolbar.setNavigationOnClickListener(cancelOnClickListener); } - /** - * Close button only - */ + /** Close button only */ protected void setFullScreenDialogClose(View.OnClickListener cancelOnClickListener, boolean white) { if (white) { setActionBarIcon(R.drawable.ic_close_white_24dp); @@ -104,6 +102,17 @@ public abstract class BaseActivity extends AppCompatActivity { setFullScreenDialogClose(cancelOnClickListener, true); } + /** Close button only, with finish-action and given return status, white. */ + protected void setFullScreenDialogClose(final int result, boolean white) { + setFullScreenDialogClose(new View.OnClickListener() { + @Override + public void onClick(View v) { + setResult(result); + finish(); + } + }, white); + } + /** * Inflate custom design with two buttons using drawables. * This does not conform to the Material Design Guidelines, but we deviate here as this is used -- cgit v1.2.3 From c01c71ba687b1cfee8084be9e6cbdf54bcbc8a41 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 8 Jul 2015 02:30:06 +0200 Subject: no progress dialog for bind action in view key / yubikey fragment --- .../java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java index eeb0cff38..f980f297b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java @@ -77,7 +77,7 @@ public class ViewKeyYubiKeyFragment } public ViewKeyYubiKeyFragment() { - super(R.string.progress_processing); + super(null); } @Override -- cgit v1.2.3 From dad2ba0db8d1d5d9d3a0e37990073e39d51f77c9 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 8 Jul 2015 02:34:03 +0200 Subject: fix expiry check in edit key ui --- .../ui/dialog/EditSubkeyExpiryDialogFragment.java | 20 ++++++++++++++------ OpenKeychain/src/main/res/values/strings.xml | 5 +++-- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java index 37e05a61d..f24df4f39 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java @@ -24,6 +24,7 @@ import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; +import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.text.format.DateFormat; import android.view.LayoutInflater; @@ -36,6 +37,8 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.util.Notify; +import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.Log; import java.util.Calendar; @@ -72,16 +75,18 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { /** * Creates dialog */ + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - final Activity activity = getActivity(); + Activity activity = getActivity(); + mMessenger = getArguments().getParcelable(ARG_MESSENGER); long creation = getArguments().getLong(ARG_CREATION); long expiry = getArguments().getLong(ARG_EXPIRY); - Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + final Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); creationCal.setTime(new Date(creation * 1000)); - final Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); expiryCal.setTime(new Date(expiry * 1000)); // date picker works with default time zone, we need to convert from UTC to default timezone @@ -175,10 +180,13 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); long numDays = (selectedCal.getTimeInMillis() / 86400000) - - (expiryCal.getTimeInMillis() / 86400000); + - (creationCal.getTimeInMillis() / 86400000); if (numDays <= 0) { - Log.e(Constants.TAG, "Should not happen! Expiry num of days <= 0!"); - throw new RuntimeException(); + Activity activity = getActivity(); + if (activity != null) { + Notify.create(activity, R.string.error_expiry_past, Style.ERROR).show(); + } + return; } expiry = selectedCal.getTime().getTime() / 1000; } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 5918d9e96..ae56f5dba 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1434,7 +1434,8 @@ "Original file could not be deleted!" "Clipboard is empty!" "Error copying data to clipboard!" - Error scanning fingerprint! - Fingerprints did not match! + "Error scanning fingerprint!" + "Fingerprints did not match!" + "Expiry date is in the past!" -- cgit v1.2.3 From af546ae10190ac076cd7b091cd064fb8a5c03519 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 8 Jul 2015 02:55:35 +0200 Subject: apply database fix for bogus rows introduced by issue #1402 --- .../keychain/provider/KeychainDatabase.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 3346926ec..92ad7372a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -53,7 +53,7 @@ import java.io.IOException; */ public class KeychainDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "openkeychain.db"; - private static final int DATABASE_VERSION = 10; + private static final int DATABASE_VERSION = 11; static Boolean apgHack = false; private Context mContext; @@ -274,6 +274,12 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL(CREATE_CERTS); case 10: // do nothing here, just consolidate + case 11: + db.execSQL("DELETE FROM api_accounts WHERE key_id BETWEEN 0 AND 3"); + if (oldVersion == 10) { + // no consolidate if we are updating from 10, we're just here for the api_accounts fix + return; + } } @@ -297,10 +303,11 @@ public class KeychainDatabase extends SQLiteOpenHelper { // It's the Java way =( String[] dbs = context.databaseList(); for (String db : dbs) { - if (db.equals("apg.db")) { + if ("apg.db".equals(db)) { hasApgDb = true; - } else if (db.equals("apg_old.db")) { + } else if ("apg_old.db".equals(db)) { Log.d(Constants.TAG, "Found apg_old.db, delete it!"); + // noinspection ResultOfMethodCallIgnored - if it doesn't happen, it doesn't happen. context.getDatabasePath("apg_old.db").delete(); } } @@ -384,7 +391,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { } } - // delete old database + // noinspection ResultOfMethodCallIgnored - not much we can do if this doesn't work context.getDatabasePath("apg.db").delete(); } @@ -416,6 +423,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { } else { in = context.getDatabasePath(DATABASE_NAME); out = context.getDatabasePath("debug_backup.db"); + // noinspection ResultOfMethodCallIgnored - this is a pure debug feature, anyways out.createNewFile(); } if (!in.canRead()) { -- cgit v1.2.3