extract ResetAndWipeUseCase

This commit is contained in:
Vincent Breitmoser
2018-01-12 15:51:27 +01:00
parent bb2b37cff6
commit 4cbdad7cb8
3 changed files with 70 additions and 47 deletions

View File

@@ -0,0 +1,68 @@
package org.sufficientlysecure.keychain.securitytoken;
import java.io.IOException;
public class ResetAndWipeUseCase {
private final SecurityTokenConnection connection;
public static ResetAndWipeUseCase create(SecurityTokenConnection connection) {
return new ResetAndWipeUseCase(connection);
}
private ResetAndWipeUseCase(SecurityTokenConnection connection) {
this.connection = connection;
}
/**
* Resets security token, which deletes all keys and data objects.
* This works by entering a wrong PIN and then Admin PIN 4 times respectively.
* Afterwards, the token is reactivated.
*/
public void resetAndWipeToken() throws IOException {
// try wrong PIN 4 times until counter goes to C0
byte[] pin = "XXXXXX".getBytes();
CommandApdu verifyPw1ForSignatureCommand =
connection.getCommandFactory().createVerifyPw1ForSignatureCommand(pin);
for (int i = 0; i <= 4; i++) {
// Command APDU for VERIFY command (page 32)
ResponseApdu response = connection.communicate(verifyPw1ForSignatureCommand);
if (response.isSuccess()) {
throw new CardException("Should never happen, XXXXXX has been accepted!", response.getSw());
}
}
// try wrong Admin PIN 4 times until counter goes to C0
byte[] adminPin = "XXXXXXXX".getBytes();
CommandApdu verifyPw3Command = connection.getCommandFactory().createVerifyPw3Command(adminPin);
for (int i = 0; i <= 4; i++) {
// Command APDU for VERIFY command (page 32)
ResponseApdu response = connection.communicate(
verifyPw3Command);
if (response.isSuccess()) { // Should NOT accept!
throw new CardException("Should never happen, XXXXXXXX has been accepted", response.getSw());
}
}
// secure messaging must be disabled before reactivation
connection.clearSecureMessaging();
// reactivate token!
// NOTE: keep the order here! First execute _both_ reactivate commands. Before checking _both_ responses
// If a token is in a bad state and reactivate1 fails, it could still be reactivated with reactivate2
CommandApdu reactivate1 = connection.getCommandFactory().createReactivate1Command();
ResponseApdu response1 = connection.communicate(reactivate1);
if (!response1.isSuccess()) {
throw new CardException("Reactivating failed!", response1.getSw());
}
CommandApdu reactivate2 = connection.getCommandFactory().createReactivate2Command();
ResponseApdu response2 = connection.communicate(reactivate2);
if (!response2.isSuccess()) {
throw new CardException("Reactivating failed!", response2.getSw());
}
connection.refreshConnectionCapabilities();
}
}

View File

@@ -448,52 +448,6 @@ public class SecurityTokenConnection {
return response.getData(); return response.getData();
} }
/**
* Resets security token, which deletes all keys and data objects.
* This works by entering a wrong PIN and then Admin PIN 4 times respectively.
* Afterwards, the token is reactivated.
*/
public void resetAndWipeToken() throws IOException {
// try wrong PIN 4 times until counter goes to C0
byte[] pin = "XXXXXX".getBytes();
for (int i = 0; i <= 4; i++) {
// Command APDU for VERIFY command (page 32)
ResponseApdu response = communicate(commandFactory.createVerifyPw1ForSignatureCommand(pin));
if (response.isSuccess()) {
throw new CardException("Should never happen, XXXXXX has been accepted!", response.getSw());
}
}
// try wrong Admin PIN 4 times until counter goes to C0
byte[] adminPin = "XXXXXXXX".getBytes();
for (int i = 0; i <= 4; i++) {
// Command APDU for VERIFY command (page 32)
ResponseApdu response = communicate(commandFactory.createVerifyPw3Command(adminPin));
if (response.isSuccess()) { // Should NOT accept!
throw new CardException("Should never happen, XXXXXXXX has been accepted", response.getSw());
}
}
// secure messaging must be disabled before reactivation
clearSecureMessaging();
// reactivate token!
// NOTE: keep the order here! First execute _both_ reactivate commands. Before checking _both_ responses
// If a token is in a bad state and reactivate1 fails, it could still be reactivated with reactivate2
CommandApdu reactivate1 = commandFactory.createReactivate1Command();
CommandApdu reactivate2 = commandFactory.createReactivate2Command();
ResponseApdu response1 = communicate(reactivate1);
ResponseApdu response2 = communicate(reactivate2);
if (!response1.isSuccess()) {
throw new CardException("Reactivating failed!", response1.getSw());
}
if (!response2.isSuccess()) {
throw new CardException("Reactivating failed!", response2.getSw());
}
refreshConnectionCapabilities();
}
/** /**
* Return the fingerprint from application specific data stored on tag, or * Return the fingerprint from application specific data stored on tag, or
* null if it doesn't exist. * null if it doesn't exist.

View File

@@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo;
import org.sufficientlysecure.keychain.securitytoken.PsoDecryptUseCase; import org.sufficientlysecure.keychain.securitytoken.PsoDecryptUseCase;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenPsoSignUseCase; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenPsoSignUseCase;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenChangeKeyUseCase; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenChangeKeyUseCase;
import org.sufficientlysecure.keychain.securitytoken.ResetAndWipeUseCase;
import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
@@ -306,7 +307,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
break; break;
} }
case SECURITY_TOKEN_RESET_CARD: { case SECURITY_TOKEN_RESET_CARD: {
stConnection.resetAndWipeToken(); ResetAndWipeUseCase.create(stConnection).resetAndWipeToken();
mResultTokenInfo = stConnection.getTokenInfo(); mResultTokenInfo = stConnection.getTokenInfo();
break; break;