try cache in certify operation (fixes #1242)

This commit is contained in:
Vincent Breitmoser
2015-07-07 23:41:44 +02:00
parent 65362beaf9
commit 895d1fbef6
5 changed files with 67 additions and 80 deletions

View File

@@ -29,6 +29,7 @@ import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.PassphraseCacheInterface;
import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation; import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation;
import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult; import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult;
import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.Progressable;
@@ -90,14 +91,21 @@ public class CertifyOperation extends BaseOperation<CertifyActionsParcel> {
case PIN: case PIN:
case PATTERN: case PATTERN:
case PASSPHRASE: 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, return new CertifyResult(log,
RequiredInputParcel.createRequiredSignPassphrase( RequiredInputParcel.createRequiredSignPassphrase(
certificationKey.getKeyId(), certificationKey.getKeyId(), null) certificationKey.getKeyId(), certificationKey.getKeyId(), null)
); );
} }
// certification is always with the master key id, so use that one
passphrase = cryptoInput.getPassphrase();
break; break;
case PASSPHRASE_EMPTY: case PASSPHRASE_EMPTY:
@@ -105,6 +113,7 @@ public class CertifyOperation extends BaseOperation<CertifyActionsParcel> {
break; break;
case DIVERT_TO_CARD: case DIVERT_TO_CARD:
// the unlock operation will succeed for passphrase == null in a divertToCard key
passphrase = null; passphrase = null;
break; break;

View File

@@ -331,9 +331,4 @@ public class CertifyKeyFragment
getActivity().finish(); getActivity().finish();
} }
@Override
public void onCryptoOperationCancelled() {
super.onCryptoOperationCancelled();
}
} }

View File

@@ -31,7 +31,6 @@ import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.provider.ContactsContract; import android.provider.ContactsContract;
@@ -57,7 +56,6 @@ import com.getbase.floatingactionbutton.FloatingActionButton;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; 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.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.KeyRing; 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.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel; 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.ServiceProgressHandler.MessageStatus;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity; import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; 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_QR_FINGERPRINT = 1;
static final int REQUEST_DELETE = 2; static final int REQUEST_DELETE = 2;
static final int REQUEST_EXPORT = 3; static final int REQUEST_EXPORT = 3;
static final int REQUEST_CERTIFY = 4;
public static final String EXTRA_DISPLAY_RESULT = "display_result"; public static final String EXTRA_DISPLAY_RESULT = "display_result";
ProviderHelper mProviderHelper; ProviderHelper mProviderHelper;
@@ -158,6 +155,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mProviderHelper = new ProviderHelper(this); mProviderHelper = new ProviderHelper(this);
mOperationHelper = new CryptoOperationHelper<>(this, this, null);
setTitle(null); setTitle(null);
@@ -382,37 +380,14 @@ public class ViewKeyActivity extends BaseNfcActivity implements
Intent intent = new Intent(this, CertifyFingerprintActivity.class); Intent intent = new Intent(this, CertifyFingerprintActivity.class);
intent.setData(dataUri); intent.setData(dataUri);
startCertifyIntent(intent); startActivityForResult(intent, REQUEST_CERTIFY);
} }
private void certifyImmediate() { private void certifyImmediate() {
Intent intent = new Intent(this, CertifyKeyActivity.class); Intent intent = new Intent(this, CertifyKeyActivity.class);
intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{mMasterKeyId}); intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{mMasterKeyId});
startCertifyIntent(intent); startActivityForResult(intent, REQUEST_CERTIFY);
}
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);
} }
private void showQrCodeDialog() { private void showQrCodeDialog() {
@@ -482,49 +457,58 @@ public class ViewKeyActivity extends BaseNfcActivity implements
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mOperationHelper != null) { if (mOperationHelper.handleActivityResult(requestCode, resultCode, data)) {
mOperationHelper.handleActivityResult(requestCode, resultCode, data);
}
if (requestCode == REQUEST_QR_FINGERPRINT && resultCode == Activity.RESULT_OK) {
// 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;
}
String fp = data.getStringExtra(ImportKeysProxyActivity.EXTRA_FINGERPRINT);
if (fp == null) {
Notify.create(this, "Error scanning fingerprint!",
Notify.LENGTH_LONG, Notify.Style.ERROR).show();
return;
}
if (mFingerprint.equalsIgnoreCase(fp)) {
certifyImmediate();
} else {
Notify.create(this, "Fingerprints did not match!",
Notify.LENGTH_LONG, Notify.Style.ERROR).show();
}
return; return;
} }
if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK) { if (resultCode != Activity.RESULT_OK) {
deleteKey(); return;
} }
if (requestCode == REQUEST_EXPORT && resultCode == Activity.RESULT_OK) { switch (requestCode) {
exportToFile(mDataUri, mProviderHelper); 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;
}
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;
}
case REQUEST_DELETE: {
deleteKey();
return;
}
case REQUEST_EXPORT: {
exportToFile(mDataUri, mProviderHelper);
return;
}
case REQUEST_CERTIFY: {
if (data.hasExtra(OperationResult.EXTRA_RESULT)) {
OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
result.createNotify(this).show();
}
return;
}
} }
if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) { super.onActivityResult(requestCode, resultCode, data);
OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
result.createNotify(this).show();
} else {
super.onActivityResult(requestCode, resultCode, data);
}
} }
@Override @Override
@@ -863,6 +847,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements
mActionNfc.setVisibility(View.GONE); mActionNfc.setVisibility(View.GONE);
} }
mFab.setVisibility(View.VISIBLE); 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)); mFab.setIconDrawable(getResources().getDrawable(R.drawable.ic_repeat_white_24dp));
} else { } else {
mActionEncryptFile.setVisibility(View.VISIBLE); mActionEncryptFile.setVisibility(View.VISIBLE);
@@ -952,7 +937,6 @@ public class ViewKeyActivity extends BaseNfcActivity implements
mKeyserver = cloudPrefs.keyserver; mKeyserver = cloudPrefs.keyserver;
} }
mOperationHelper = new CryptoOperationHelper<>(this, this, null);
mOperationHelper.cryptoOperation(); mOperationHelper.cryptoOperation();
} }

View File

@@ -208,12 +208,9 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
return true; return true;
} }
} }
default: {
return false;
}
} }
return true;
return false;
} }
protected void dismissProgress() { protected void dismissProgress() {

View File

@@ -1432,5 +1432,7 @@
<string name="file_delete_exception">"Original file could not be deleted!"</string> <string name="file_delete_exception">"Original file could not be deleted!"</string>
<string name="error_clipboard_empty">"Clipboard is empty!"</string> <string name="error_clipboard_empty">"Clipboard is empty!"</string>
<string name="error_clipboard_copy">"Error copying data to clipboard!"</string> <string name="error_clipboard_copy">"Error copying data to clipboard!"</string>
<string name="error_scan_fp">Error scanning fingerprint!</string>
<string name="error_scan_match">Fingerprints did not match!</string>
</resources> </resources>