From ed4e21957c49e07c9679854d59f1c53a5cc35dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 25 Oct 2017 15:46:46 +0200 Subject: [PATCH] Better error handling for generic IOException --- .../ui/base/BaseSecurityTokenActivity.java | 231 +++++++++--------- OpenKeychain/src/main/res/values/strings.xml | 1 + 2 files changed, 115 insertions(+), 117 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenActivity.java index 2f5da22de..756295f0e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenActivity.java @@ -233,6 +233,7 @@ public abstract class BaseSecurityTokenActivity extends BaseActivity } private void handleSecurityTokenError(SecurityTokenConnection stConnection, IOException e) { + Log.d(Constants.TAG, "Exception in handleSecurityTokenError", e); if (e instanceof TagLostException) { onSecurityTokenError(getString(R.string.security_token_error_tag_lost)); @@ -254,140 +255,136 @@ public abstract class BaseSecurityTokenActivity extends BaseActivity return; } - short status; if (e instanceof CardException) { - status = ((CardException) e).getResponseCode(); - } else { - status = -1; - } + short status = ((CardException) e).getResponseCode(); - // Wrong PIN, a status of 63CX indicates X attempts remaining. - // NOTE: Used in ykneo-openpgp version < 1.0.10, changed to 0x6982 in 1.0.11 - // https://github.com/Yubico/ykneo-openpgp/commit/90c2b91e86fb0e43ee234dd258834e75e3416410 - if ((status & (short) 0xFFF0) == 0x63C0) { - int tries = status & 0x000F; + // Wrong PIN, a status of 63CX indicates X attempts remaining. + // NOTE: Used in ykneo-openpgp version < 1.0.10, changed to 0x6982 in 1.0.11 + // https://github.com/Yubico/ykneo-openpgp/commit/90c2b91e86fb0e43ee234dd258834e75e3416410 + if ((status & (short) 0xFFF0) == 0x63C0) { + int tries = status & 0x000F; - SecurityTokenInfo tokeninfo = null; - try { - tokeninfo = stConnection.getTokenInfo(); - } catch (IOException e2) { - // don't care - } - // hook to do something different when PIN is wrong - onSecurityTokenPinError( - getResources().getQuantityString(R.plurals.security_token_error_pin, tries, tries), tokeninfo); - return; - } - - Log.d(Constants.TAG, "security token exception", e); - - // Otherwise, all status codes are fixed values. - switch (status) { - - // These error conditions are likely to be experienced by an end user. - - /* OpenPGP Card Spec: Security status not satisfied, PW wrong, - PW not checked (command not allowed), Secure messaging incorrect (checksum and/or cryptogram) */ - // NOTE: Used in ykneo-openpgp >= 1.0.11 for wrong PIN - case 0x6982: { SecurityTokenInfo tokeninfo = null; try { tokeninfo = stConnection.getTokenInfo(); } catch (IOException e2) { // don't care } + // hook to do something different when PIN is wrong + onSecurityTokenPinError( + getResources().getQuantityString(R.plurals.security_token_error_pin, tries, tries), tokeninfo); + return; + } - // hook to do something different when PIN is wrong - onSecurityTokenPinError(getString(R.string.security_token_error_security_not_satisfied), tokeninfo); - break; - } - /* OpenPGP Card Spec: Selected file in termination state */ - case 0x6285: { - onSecurityTokenError(getString(R.string.security_token_error_terminated)); - break; - } - /* OpenPGP Card Spec: Wrong length (Lc and/or Le) */ - // NOTE: Used in ykneo-openpgp < 1.0.10 for too short PIN, changed in 1.0.11 to 0x6A80 for too short PIN - // https://github.com/Yubico/ykneo-openpgp/commit/b49ce8241917e7c087a4dab7b2c755420ff4500f - case 0x6700: { - // hook to do something different when PIN is wrong - onSecurityTokenPinError(getString(R.string.security_token_error_wrong_length), null); - break; - } - /* OpenPGP Card Spec: Incorrect parameters in the data field */ - // NOTE: Used in ykneo-openpgp >= 1.0.11 for too short PIN - case 0x6A80: { - // hook to do something different when PIN is wrong - onSecurityTokenPinError(getString(R.string.security_token_error_bad_data), null); - break; - } - /* OpenPGP Card Spec: Authentication method blocked, PW blocked (error counter zero) */ - case 0x6983: { - onSecurityTokenError(getString(R.string.security_token_error_authentication_blocked)); - break; - } - /* OpenPGP Card Spec: Condition of use not satisfied */ - case 0x6985: { - onSecurityTokenError(getString(R.string.security_token_error_conditions_not_satisfied)); - break; - } - /* OpenPGP Card Spec: SM data objects incorrect (e.g. wrong TLV-structure in command data) */ - // NOTE: 6A88 is "Not Found" in the spec, but ykneo-openpgp also returns 6A83 for this in some cases. - case 0x6A88: - case 0x6A83: { - onSecurityTokenError(getString(R.string.security_token_error_data_not_found)); - break; - } - // 6F00 is a JavaCard proprietary status code, SW_UNKNOWN, and usually represents an - // unhandled exception on the security token. - case 0x6F00: { - onSecurityTokenError(getString(R.string.security_token_error_unknown)); - break; - } - // 6A82 app not installed on security token! - case 0x6A82: { - if (stConnection.isFidesmoToken()) { - // Check if the Fidesmo app is installed - if (isAndroidAppInstalled(FIDESMO_APP_PACKAGE)) { - promptFidesmoPgpInstall(); - } else { - promptFidesmoAppInstall(); + // Otherwise, all status codes are fixed values. + switch (status) { + /* OpenPGP Card Spec: Security status not satisfied, PW wrong, + PW not checked (command not allowed), Secure messaging incorrect (checksum and/or cryptogram) */ + // NOTE: Used in ykneo-openpgp >= 1.0.11 for wrong PIN + case 0x6982: { + SecurityTokenInfo tokeninfo = null; + try { + tokeninfo = stConnection.getTokenInfo(); + } catch (IOException e2) { + // don't care } - } else { // Other (possibly) compatible hardware - onSecurityTokenError(getString(R.string.security_token_error_pgp_app_not_installed)); + + // hook to do something different when PIN is wrong + onSecurityTokenPinError(getString(R.string.security_token_error_security_not_satisfied), tokeninfo); + break; + } + /* OpenPGP Card Spec: Selected file in termination state */ + case 0x6285: { + onSecurityTokenError(getString(R.string.security_token_error_terminated)); + break; + } + /* OpenPGP Card Spec: Wrong length (Lc and/or Le) */ + // NOTE: Used in ykneo-openpgp < 1.0.10 for too short PIN, changed in 1.0.11 to 0x6A80 for too short PIN + // https://github.com/Yubico/ykneo-openpgp/commit/b49ce8241917e7c087a4dab7b2c755420ff4500f + case 0x6700: { + // hook to do something different when PIN is wrong + onSecurityTokenPinError(getString(R.string.security_token_error_wrong_length), null); + break; + } + /* OpenPGP Card Spec: Incorrect parameters in the data field */ + // NOTE: Used in ykneo-openpgp >= 1.0.11 for too short PIN + case 0x6A80: { + // hook to do something different when PIN is wrong + onSecurityTokenPinError(getString(R.string.security_token_error_bad_data), null); + break; + } + /* OpenPGP Card Spec: Authentication method blocked, PW blocked (error counter zero) */ + case 0x6983: { + onSecurityTokenError(getString(R.string.security_token_error_authentication_blocked)); + break; + } + /* OpenPGP Card Spec: Condition of use not satisfied */ + case 0x6985: { + onSecurityTokenError(getString(R.string.security_token_error_conditions_not_satisfied)); + break; + } + /* OpenPGP Card Spec: SM data objects incorrect (e.g. wrong TLV-structure in command data) */ + // NOTE: 6A88 is "Not Found" in the spec, but ykneo-openpgp also returns 6A83 for this in some cases. + case 0x6A88: + case 0x6A83: { + onSecurityTokenError(getString(R.string.security_token_error_data_not_found)); + break; + } + // 6F00 is a JavaCard proprietary status code, SW_UNKNOWN, and usually represents an + // unhandled exception on the security token. + case 0x6F00: { + onSecurityTokenError(getString(R.string.security_token_error_unknown)); + break; + } + // 6A82 app not installed on security token! + case 0x6A82: { + if (stConnection.isFidesmoToken()) { + // Check if the Fidesmo app is installed + if (isAndroidAppInstalled(FIDESMO_APP_PACKAGE)) { + promptFidesmoPgpInstall(); + } else { + promptFidesmoAppInstall(); + } + } + break; } - break; - } - // These errors should not occur in everyday use; if they are returned, it means we - // made a mistake sending data to the token, or the token is misbehaving. + // These errors should not occur in everyday use; if they are returned, it means we + // made a mistake sending data to the token, or the token is misbehaving. - /* OpenPGP Card Spec: Last command of the chain expected */ - case 0x6883: { - onSecurityTokenError(getString(R.string.security_token_error_chaining_error)); - break; - } - /* OpenPGP Card Spec: Wrong parameters P1-P2 */ - case 0x6B00: { - onSecurityTokenError(getString(R.string.security_token_error_header, "P1/P2")); - break; - } - /* OpenPGP Card Spec: Instruction (INS) not supported */ - case 0x6D00: { - onSecurityTokenError(getString(R.string.security_token_error_header, "INS")); - break; - } - /* OpenPGP Card Spec: Class (CLA) not supported */ - case 0x6E00: { - onSecurityTokenError(getString(R.string.security_token_error_header, "CLA")); - break; - } - default: { - onSecurityTokenError(getString(R.string.security_token_error, e.getMessage())); - break; + /* OpenPGP Card Spec: Last command of the chain expected */ + case 0x6883: { + onSecurityTokenError(getString(R.string.security_token_error_chaining_error)); + break; + } + /* OpenPGP Card Spec: Wrong parameters P1-P2 */ + case 0x6B00: { + onSecurityTokenError(getString(R.string.security_token_error_header, "P1/P2")); + break; + } + /* OpenPGP Card Spec: Instruction (INS) not supported */ + case 0x6D00: { + onSecurityTokenError(getString(R.string.security_token_error_header, "INS")); + break; + } + /* OpenPGP Card Spec: Class (CLA) not supported */ + case 0x6E00: { + onSecurityTokenError(getString(R.string.security_token_error_header, "CLA")); + break; + } + default: { + onSecurityTokenError(getString(R.string.security_token_error, e.getMessage())); + break; + } } } + // fallback for generic IOException + if (e.getMessage() != null) { + onSecurityTokenError(getString(R.string.security_token_error, e.getMessage())); + } else { + onSecurityTokenError(getString(R.string.security_token_error_generic)); + } } /** diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 4326864fd..44be5ffd9 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1580,6 +1580,7 @@ "Security Token reported invalid %s byte." "Security Token has been taken off too early. Keep the Security Token at the back until the operation finishes." "Security Token does not support the required communication standard (ISO-DEP, ISO 14443-4)" + "Generic Error: Most probably, the Security Token has been taken off too early." "This Security Token is not supported by OpenKeychain." "Try again" Delete original file