Fix code style and documentation in BaseSecurityTokenNfcActivity

This commit is contained in:
Dominik Schürmann
2016-03-08 04:04:18 +01:00
parent 84fb5e45b1
commit d6520cde04
2 changed files with 45 additions and 40 deletions

View File

@@ -249,13 +249,13 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenNfcActivity
} }
// change PINs afterwards // change PINs afterwards
nfcModifyPIN(0x81, newPin); nfcModifyPin(0x81, newPin);
nfcModifyPIN(0x83, newAdminPin); nfcModifyPin(0x83, newAdminPin);
break; break;
} }
case NFC_RESET_CARD: { case NFC_RESET_CARD: {
nfcResetCard(); nfcReset();
break; break;
} }

View File

@@ -26,14 +26,11 @@ import java.nio.ByteBuffer;
import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateCrtKey;
import android.app.Activity; import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.nfc.NfcAdapter; import android.nfc.NfcAdapter;
import android.nfc.Tag; import android.nfc.Tag;
import android.nfc.TagLostException; import android.nfc.TagLostException;
import android.nfc.tech.IsoDep;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
@@ -319,7 +316,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
// 6A82 app not installed on security token! // 6A82 app not installed on security token!
case 0x6A82: { case 0x6A82: {
if (isFidesmoDevice()) { if (isFidesmoToken()) {
// Check if the Fidesmo app is installed // Check if the Fidesmo app is installed
if (isAndroidAppInstalled(FIDESMO_APP_PACKAGE)) { if (isAndroidAppInstalled(FIDESMO_APP_PACKAGE)) {
promptFidesmoPgpInstall(); promptFidesmoPgpInstall();
@@ -530,18 +527,18 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
public String nfcGetUserId() throws IOException { public String nfcGetUserId() throws IOException {
String info = "00CA006500"; String info = "00CA006500";
return nfcGetHolderName(nfcCommunicate(info)); return getHolderName(nfcCommunicate(info));
} }
/** /**
* Calls to calculate the signature and returns the MPI value * Call COMPUTE DIGITAL SIGNATURE command and returns the MPI value
* *
* @param hash the hash for signing * @param hash the hash for signing
* @return a big integer representing the MPI for the given hash * @return a big integer representing the MPI for the given hash
*/ */
public byte[] nfcCalculateSignature(byte[] hash, int hashAlgo) throws IOException { public byte[] nfcCalculateSignature(byte[] hash, int hashAlgo) throws IOException {
if (!mPw1ValidatedForSignature) { if (!mPw1ValidatedForSignature) {
nfcVerifyPIN(0x81); // (Verify PW1 with mode 81 for signing) nfcVerifyPin(0x81); // (Verify PW1 with mode 81 for signing)
} }
// dsi, including Lc // dsi, including Lc
@@ -634,14 +631,14 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
/** /**
* Calls to calculate the signature and returns the MPI value * Call DECIPHER command
* *
* @param encryptedSessionKey the encoded session key * @param encryptedSessionKey the encoded session key
* @return the decoded session key * @return the decoded session key
*/ */
public byte[] nfcDecryptSessionKey(byte[] encryptedSessionKey) throws IOException { public byte[] nfcDecryptSessionKey(byte[] encryptedSessionKey) throws IOException {
if (!mPw1ValidatedForDecrypt) { if (!mPw1ValidatedForDecrypt) {
nfcVerifyPIN(0x82); // (Verify PW1 with mode 82 for decryption) nfcVerifyPin(0x82); // (Verify PW1 with mode 82 for decryption)
} }
String firstApdu = "102a8086fe"; String firstApdu = "102a8086fe";
@@ -657,10 +654,10 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
two[i] = encryptedSessionKey[i + one.length + 1]; two[i] = encryptedSessionKey[i + one.length + 1];
} }
String first = nfcCommunicate(firstApdu + getHex(one)); nfcCommunicate(firstApdu + getHex(one));
String second = nfcCommunicate(secondApdu + getHex(two) + le); String second = nfcCommunicate(secondApdu + getHex(two) + le);
String decryptedSessionKey = nfcGetDataField(second); String decryptedSessionKey = getDataField(second);
return Hex.decode(decryptedSessionKey); return Hex.decode(decryptedSessionKey);
} }
@@ -670,7 +667,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
* @param mode For PW1, this is 0x81 for signing, 0x82 for everything else. * @param mode For PW1, this is 0x81 for signing, 0x82 for everything else.
* For PW3 (Admin PIN), mode is 0x83. * For PW3 (Admin PIN), mode is 0x83.
*/ */
public void nfcVerifyPIN(int mode) throws IOException { public void nfcVerifyPin(int mode) throws IOException {
if (mPin != null || mode == 0x83) { if (mPin != null || mode == 0x83) {
byte[] pin; byte[] pin;
@@ -683,7 +680,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
// SW1/2 0x9000 is the generic "ok" response, which we expect most of the time. // SW1/2 0x9000 is the generic "ok" response, which we expect most of the time.
// See specification, page 51 // See specification, page 51
String accepted = "9000"; String accepted = "9000";
String response = tryPin(mode, pin); // login String response = nfcTryPin(mode, pin); // login
if (!response.equals(accepted)) { if (!response.equals(accepted)) {
throw new CardException("Bad PIN!", parseCardStatus(response)); throw new CardException("Bad PIN!", parseCardStatus(response));
} }
@@ -698,13 +695,18 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
} }
public void nfcResetCard() throws IOException { /**
* 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 nfcReset() throws IOException {
String accepted = "9000"; String accepted = "9000";
// try wrong PIN 4 times until counter goes to C0 // try wrong PIN 4 times until counter goes to C0
byte[] pin = "XXXXXX".getBytes(); byte[] pin = "XXXXXX".getBytes();
for (int i = 0; i <= 4; i++) { for (int i = 0; i <= 4; i++) {
String response = tryPin(0x81, pin); String response = nfcTryPin(0x81, pin);
if (response.equals(accepted)) { // Should NOT accept! if (response.equals(accepted)) { // Should NOT accept!
throw new CardException("Should never happen, XXXXXX has been accepted!", parseCardStatus(response)); throw new CardException("Should never happen, XXXXXX has been accepted!", parseCardStatus(response));
} }
@@ -713,7 +715,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
// try wrong Admin PIN 4 times until counter goes to C0 // try wrong Admin PIN 4 times until counter goes to C0
byte[] adminPin = "XXXXXXXX".getBytes(); byte[] adminPin = "XXXXXXXX".getBytes();
for (int i = 0; i <= 4; i++) { for (int i = 0; i <= 4; i++) {
String response = tryPin(0x83, adminPin); String response = nfcTryPin(0x83, adminPin);
if (response.equals(accepted)) { // Should NOT accept! if (response.equals(accepted)) { // Should NOT accept!
throw new CardException("Should never happen, XXXXXXXX has been accepted", parseCardStatus(response)); throw new CardException("Should never happen, XXXXXXXX has been accepted", parseCardStatus(response));
} }
@@ -730,7 +732,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
private String tryPin(int mode, byte[] pin) throws IOException { private String nfcTryPin(int mode, byte[] pin) throws IOException {
// Command APDU for VERIFY command (page 32) // Command APDU for VERIFY command (page 32)
String login = String login =
"00" // CLA "00" // CLA
@@ -749,7 +751,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
* @param pw For PW1, this is 0x81. For PW3 (Admin PIN), mode is 0x83. * @param pw For PW1, this is 0x81. For PW3 (Admin PIN), mode is 0x83.
* @param newPin The new PW1 or PW3. * @param newPin The new PW1 or PW3.
*/ */
public void nfcModifyPIN(int pw, byte[] newPin) throws IOException { public void nfcModifyPin(int pw, byte[] newPin) throws IOException {
final int MAX_PW1_LENGTH_INDEX = 1; final int MAX_PW1_LENGTH_INDEX = 1;
final int MAX_PW3_LENGTH_INDEX = 3; final int MAX_PW3_LENGTH_INDEX = 3;
@@ -802,10 +804,10 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
if (dataObject == 0x0101 || dataObject == 0x0103) { if (dataObject == 0x0101 || dataObject == 0x0103) {
if (!mPw1ValidatedForDecrypt) { if (!mPw1ValidatedForDecrypt) {
nfcVerifyPIN(0x82); // (Verify PW1 for non-signing operations) nfcVerifyPin(0x82); // (Verify PW1 for non-signing operations)
} }
} else if (!mPw3Validated) { } else if (!mPw3Validated) {
nfcVerifyPIN(0x83); // (Verify PW3) nfcVerifyPin(0x83); // (Verify PW3)
} }
String putDataApdu = "00" // CLA String putDataApdu = "00" // CLA
@@ -854,7 +856,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
if (!mPw3Validated) { if (!mPw3Validated) {
nfcVerifyPIN(0x83); // (Verify PW3 with mode 83) nfcVerifyPin(0x83); // (Verify PW3 with mode 83)
} }
byte[] header= Hex.decode( byte[] header= Hex.decode(
@@ -947,13 +949,13 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
* @return the public key data objects, in TLV format. For RSA this will be the public modulus * @return the public key data objects, in TLV format. For RSA this will be the public modulus
* (0x81) and exponent (0x82). These may come out of order; proper TLV parsing is required. * (0x81) and exponent (0x82). These may come out of order; proper TLV parsing is required.
*/ */
public byte[] nfcGenerateOnCardKey(int slot) throws IOException { public byte[] nfcGenerateKey(int slot) throws IOException {
if (slot != 0xB6 && slot != 0xB8 && slot != 0xA4) { if (slot != 0xB6 && slot != 0xB8 && slot != 0xA4) {
throw new IOException("Invalid key slot"); throw new IOException("Invalid key slot");
} }
if (!mPw3Validated) { if (!mPw3Validated) {
nfcVerifyPIN(0x83); // (Verify PW3 with mode 83) nfcVerifyPin(0x83); // (Verify PW3 with mode 83)
} }
String generateKeyApdu = "0047800002" + String.format("%02x", slot) + "0000"; String generateKeyApdu = "0047800002" + String.format("%02x", slot) + "0000";
@@ -966,13 +968,20 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
throw new IOException("On-card key generation failed"); throw new IOException("On-card key generation failed");
} }
String publicKeyData = nfcGetDataField(first) + nfcGetDataField(second); String publicKeyData = getDataField(first) + getDataField(second);
Log.d(Constants.TAG, "Public Key Data Objects: " + publicKeyData); Log.d(Constants.TAG, "Public Key Data Objects: " + publicKeyData);
return Hex.decode(publicKeyData); return Hex.decode(publicKeyData);
} }
/**
* Transceive data via NFC encoded as Hex
*/
public String nfcCommunicate(String apdu) throws IOException {
return getHex(mIsoCard.transceive(Hex.decode(apdu)));
}
/** /**
* Parses out the status word from a JavaCard response string. * Parses out the status word from a JavaCard response string.
* *
@@ -991,7 +1000,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
} }
public String nfcGetHolderName(String name) { public String getHolderName(String name) {
try { try {
String slength; String slength;
int ilength; int ilength;
@@ -1011,14 +1020,10 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
} }
private String nfcGetDataField(String output) { private String getDataField(String output) {
return output.substring(0, output.length() - 4); return output.substring(0, output.length() - 4);
} }
public String nfcCommunicate(String apdu) throws IOException {
return getHex(mIsoCard.transceive(Hex.decode(apdu)));
}
public static String getHex(byte[] raw) { public static String getHex(byte[] raw) {
return new String(Hex.encode(raw)); return new String(Hex.encode(raw));
} }
@@ -1045,7 +1050,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
private boolean isFidesmoDevice() { private boolean isFidesmoToken() {
if (isNfcConnected()) { // Check if we can still talk to the card if (isNfcConnected()) { // Check if we can still talk to the card
try { try {
// By trying to select any apps that have the Fidesmo AID prefix we can // By trying to select any apps that have the Fidesmo AID prefix we can
@@ -1061,11 +1066,11 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
} }
/** /**
* Ask user if she wants to install PGP onto her Fidesmo device * Ask user if she wants to install PGP onto her Fidesmo token
*/ */
private void promptFidesmoPgpInstall() { private void promptFidesmoPgpInstall() {
FidesmoPgpInstallDialog mFidesmoPgpInstallDialog = new FidesmoPgpInstallDialog(); FidesmoPgpInstallDialog fidesmoPgpInstallDialog = new FidesmoPgpInstallDialog();
mFidesmoPgpInstallDialog.show(getSupportFragmentManager(), "mFidesmoPgpInstallDialog"); fidesmoPgpInstallDialog.show(getSupportFragmentManager(), "fidesmoPgpInstallDialog");
} }
/** /**
@@ -1073,8 +1078,8 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
* to launch the Google Play store. * to launch the Google Play store.
*/ */
private void promptFidesmoAppInstall() { private void promptFidesmoAppInstall() {
FidesmoInstallDialog mFidesmoInstallDialog = new FidesmoInstallDialog(); FidesmoInstallDialog fidesmoInstallDialog = new FidesmoInstallDialog();
mFidesmoInstallDialog.show(getSupportFragmentManager(), "mFidesmoInstallDialog"); fidesmoInstallDialog.show(getSupportFragmentManager(), "fidesmoInstallDialog");
} }
/** /**
@@ -1084,7 +1089,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen
*/ */
private boolean isAndroidAppInstalled(String uri) { private boolean isAndroidAppInstalled(String uri) {
PackageManager mPackageManager = getPackageManager(); PackageManager mPackageManager = getPackageManager();
boolean mAppInstalled = false; boolean mAppInstalled;
try { try {
mPackageManager.getPackageInfo(uri, PackageManager.GET_ACTIVITIES); mPackageManager.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
mAppInstalled = true; mAppInstalled = true;