aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2015-03-23 01:44:14 +0100
committerVincent Breitmoser <valodim@mugenguild.com>2015-03-23 01:48:44 +0100
commitc694d73cab1edf91cb94d53cc8352ca93f0eb6ce (patch)
treeb4d36dc8de526a81cfa1a530d50ce909b58b0243 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain
parent3bb194fc080e5945dc8bdbeea9b91cf801406c32 (diff)
downloadopen-keychain-c694d73cab1edf91cb94d53cc8352ca93f0eb6ce.tar.gz
open-keychain-c694d73cab1edf91cb94d53cc8352ca93f0eb6ce.tar.bz2
open-keychain-c694d73cab1edf91cb94d53cc8352ca93f0eb6ce.zip
further improve yubikey error handling
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java40
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java22
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java35
4 files changed, 77 insertions, 24 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
index ee481ad31..5e8ad96cd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
@@ -124,7 +124,7 @@ public class PassphraseCacheService extends Service {
public static void addCachedPassphrase(Context context, long masterKeyId, long subKeyId,
Passphrase passphrase,
String primaryUserId) {
- Log.d(Constants.TAG, "PassphraseCacheService.cacheNewPassphrase() for " + masterKeyId);
+ Log.d(Constants.TAG, "PassphraseCacheService.addCachedPassphrase() for " + masterKeyId);
Intent intent = new Intent(context, PassphraseCacheService.class);
intent.setAction(ACTION_PASSPHRASE_CACHE_ADD);
@@ -138,6 +138,19 @@ public class PassphraseCacheService extends Service {
context.startService(intent);
}
+ public static void clearCachedPassphrase(Context context, long masterKeyId, long subKeyId) {
+ Log.d(Constants.TAG, "PassphraseCacheService.clearCachedPassphrase() for " + masterKeyId);
+
+ Intent intent = new Intent(context, PassphraseCacheService.class);
+ intent.setAction(ACTION_PASSPHRASE_CACHE_CLEAR);
+
+ intent.putExtra(EXTRA_KEY_ID, masterKeyId);
+ intent.putExtra(EXTRA_SUBKEY_ID, subKeyId);
+
+ context.startService(intent);
+ }
+
+
/**
* Gets a cached passphrase from memory by sending an intent to the service. This method is
* designed to wait until the service returns the passphrase.
@@ -395,12 +408,27 @@ public class PassphraseCacheService extends Service {
} else if (ACTION_PASSPHRASE_CACHE_CLEAR.equals(intent.getAction())) {
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
- // Stop all ttl alarms
- for (int i = 0; i < mPassphraseCache.size(); i++) {
- am.cancel(buildIntent(this, mPassphraseCache.keyAt(i)));
- }
+ if (intent.hasExtra(EXTRA_SUBKEY_ID) && intent.hasExtra(EXTRA_KEY_ID)) {
- mPassphraseCache.clear();
+ long keyId;
+ if (Preferences.getPreferences(mContext).getPassphraseCacheSubs()) {
+ keyId = intent.getLongExtra(EXTRA_KEY_ID, 0L);
+ } else {
+ keyId = intent.getLongExtra(EXTRA_SUBKEY_ID, 0L);
+ }
+ // Stop specific ttl alarm and
+ am.cancel(buildIntent(this, keyId));
+ mPassphraseCache.delete(keyId);
+
+ } else {
+
+ // Stop all ttl alarms
+ for (int i = 0; i < mPassphraseCache.size(); i++) {
+ am.cancel(buildIntent(this, mPassphraseCache.keyAt(i)));
+ }
+ mPassphraseCache.clear();
+
+ }
updateService();
} else {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java
index d8d87114e..471fc0ec9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java
@@ -56,6 +56,10 @@ public class RequiredInputParcel implements Parcelable {
}
+ public long getMasterKeyId() {
+ return mMasterKeyId;
+ }
+
public long getSubKeyId() {
return mSubKeyId;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
index 549d9ece7..511183b04 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
@@ -14,10 +14,12 @@ import android.view.WindowManager;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
@@ -89,4 +91,24 @@ public class NfcOperationActivity extends BaseNfcActivity {
finish();
}
+
+ @Override
+ public void handlePinError() {
+
+ // avoid a loop
+ Preferences prefs = Preferences.getPreferences(this);
+ if (prefs.useDefaultYubikeyPin()) {
+ toast(getString(R.string.error_pin_nodefault));
+ setResult(RESULT_CANCELED);
+ finish();
+ return;
+ }
+
+ // clear (invalid) passphrase
+ PassphraseCacheService.clearCachedPassphrase(
+ this, mRequiredInput.getMasterKeyId(), mRequiredInput.getSubKeyId());
+
+ obtainYubikeyPin(RequiredInputParcel.createRequiredPassphrase(mRequiredInput));
+
+ }
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java
index 365d32918..a8a5a1f28 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java
@@ -79,6 +79,12 @@ public abstract class BaseNfcActivity extends BaseActivity {
}
+ public void handlePinError() {
+ toast("Wrong PIN!");
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+
/**
* Called when the system is about to start resuming a previous activity,
* disables NFC Foreground Dispatch
@@ -170,10 +176,7 @@ public abstract class BaseNfcActivity extends BaseActivity {
+ "D27600012401" // Data (6 bytes)
+ "00"; // Le
if ( ! nfcCommunicate(opening).equals(accepted)) { // activate connection
- toast("Opening Error!");
- setResult(RESULT_CANCELED);
- finish();
- return;
+ throw new IOException("Initialization failed!");
}
if (mPin != null) {
@@ -189,9 +192,7 @@ public abstract class BaseNfcActivity extends BaseActivity {
+ String.format("%02x", pin.length) // Lc
+ Hex.toHexString(pin);
if (!nfcCommunicate(login).equals(accepted)) { // login
- toast("Wrong PIN!");
- setResult(RESULT_CANCELED);
- finish();
+ handlePinError();
return;
}
@@ -321,7 +322,7 @@ public abstract class BaseNfcActivity extends BaseActivity {
switch (hashAlgo) {
case HashAlgorithmTags.SHA1:
if (hash.length != 20) {
- throw new RuntimeException("Bad hash length (" + hash.length + ", expected 10!");
+ throw new IOException("Bad hash length (" + hash.length + ", expected 10!");
}
dsi = "23" // Lc
+ "3021" // Tag/Length of Sequence, the 0x21 includes all following 33 bytes
@@ -332,36 +333,36 @@ public abstract class BaseNfcActivity extends BaseActivity {
break;
case HashAlgorithmTags.RIPEMD160:
if (hash.length != 20) {
- throw new RuntimeException("Bad hash length (" + hash.length + ", expected 20!");
+ throw new IOException("Bad hash length (" + hash.length + ", expected 20!");
}
dsi = "233021300906052B2403020105000414" + getHex(hash);
break;
case HashAlgorithmTags.SHA224:
if (hash.length != 28) {
- throw new RuntimeException("Bad hash length (" + hash.length + ", expected 28!");
+ throw new IOException("Bad hash length (" + hash.length + ", expected 28!");
}
dsi = "2F302D300D06096086480165030402040500041C" + getHex(hash);
break;
case HashAlgorithmTags.SHA256:
if (hash.length != 32) {
- throw new RuntimeException("Bad hash length (" + hash.length + ", expected 32!");
+ throw new IOException("Bad hash length (" + hash.length + ", expected 32!");
}
dsi = "333031300D060960864801650304020105000420" + getHex(hash);
break;
case HashAlgorithmTags.SHA384:
if (hash.length != 48) {
- throw new RuntimeException("Bad hash length (" + hash.length + ", expected 48!");
+ throw new IOException("Bad hash length (" + hash.length + ", expected 48!");
}
dsi = "433041300D060960864801650304020205000430" + getHex(hash);
break;
case HashAlgorithmTags.SHA512:
if (hash.length != 64) {
- throw new RuntimeException("Bad hash length (" + hash.length + ", expected 64!");
+ throw new IOException("Bad hash length (" + hash.length + ", expected 64!");
}
dsi = "533051300D060960864801650304020305000440" + getHex(hash);
break;
default:
- throw new RuntimeException("Not supported hash algo!");
+ throw new IOException("Not supported hash algo!");
}
// Command APDU for PERFORM SECURITY OPERATION: COMPUTE DIGITAL SIGNATURE (page 37)
@@ -388,14 +389,12 @@ public abstract class BaseNfcActivity extends BaseActivity {
Log.d(Constants.TAG, "final response:" + status);
if ( ! "9000".equals(status)) {
- toast("Bad NFC response code: " + status);
- return null;
+ throw new IOException("Bad NFC response code: " + status);
}
// Make sure the signature we received is actually the expected number of bytes long!
if (signature.length() != 256 && signature.length() != 512) {
- toast("Bad signature length! Expected 128 or 256 bytes, got " + signature.length() / 2);
- return null;
+ throw new IOException("Bad signature length! Expected 128 or 256 bytes, got " + signature.length() / 2);
}
return Hex.decode(signature);