Better error handling for generic IOException
This commit is contained in:
committed by
Vincent Breitmoser
parent
0920d97572
commit
ed4e21957c
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user