Skip to content

Commit

Permalink
updated
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfehr committed Mar 27, 2023
1 parent 02c40f8 commit f1c87dc
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
Expand Down Expand Up @@ -54,7 +55,7 @@
public class MainActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback {

private final String TAG = "MainAct";
private com.google.android.material.textfield.TextInputEditText etLog;
private com.google.android.material.textfield.TextInputEditText etData, etLog;
private View loadingLayout;
private NfcAdapter mNfcAdapter;

Expand All @@ -71,6 +72,7 @@ protected void onCreate(Bundle savedInstanceState) {
Toolbar myToolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(myToolbar);

etData = findViewById(R.id.etData);
etLog = findViewById(R.id.etLog);
loadingLayout = findViewById(R.id.loading_layout);

Expand All @@ -91,7 +93,7 @@ protected void onCreate(Bundle savedInstanceState) {

@Override
public void onTagDiscovered(Tag tag) {
clearData(etLog);
clearData();
Log.d(TAG, "NFC tag discovered");
writeToUiAppend("NFC tag discovered");
playPing();
Expand All @@ -117,6 +119,7 @@ public void onTagDiscovered(Tag tag) {
// here we are going to start our journey through the card

printStepHeader(0, "our journey begins");
writeToUiAppend(etData, "00 reading of the card started");

writeToUiAppend("increase IsoDep timeout for long reading");
writeToUiAppend("timeout old: " + nfc.getTimeout() + " ms");
Expand All @@ -134,6 +137,7 @@ public void onTagDiscovered(Tag tag) {
byte[] selectPpseResponse = nfc.transceive(selectPpseCommand);
writeToUiAppend("01 select PPSE command length " + selectPpseCommand.length + " data: " + bytesToHexNpe(selectPpseCommand));
writeToUiAppend("01 select PPSE response length " + selectPpseResponse.length + " data: " + bytesToHexNpe(selectPpseResponse));
writeToUiAppend(etData, "01 select PPSE completed");
writeToUiAppend(prettyPrintDataToString(selectPpseResponse));

byte[] selectPpseResponseOk = checkResponse(selectPpseResponse);
Expand All @@ -144,6 +148,7 @@ public void onTagDiscovered(Tag tag) {
* step 1 code end
*/

/*
// get the tags from respond
BerTlvParser parserA = new BerTlvParser();
BerTlvs tlvs = parserA.parse(selectPpseResponseOk, 0, selectPpseResponseOk.length);
Expand All @@ -159,6 +164,8 @@ public void onTagDiscovered(Tag tag) {
}
*/

/*
// devnied
writeToUiAppend("");
Expand Down Expand Up @@ -186,7 +193,7 @@ public void onTagDiscovered(Tag tag) {
* step 2 code start
*/

writeToUiAppend("");
//writeToUiAppend("");
printStepHeader(2, "search applications on card");
writeToUiAppend("02 analyze select PPSE response and search for tag 0x4F (applications on card)");

Expand All @@ -206,6 +213,7 @@ public void onTagDiscovered(Tag tag) {
aidList.add(tlv4fBytes);
writeToUiAppend("application Id (AID): " + bytesToHexNpe(tlv4fBytes));
}
writeToUiAppend(etData, "02 analyze select PPSE response completed");

/**
* step 2 code end
Expand All @@ -227,35 +235,37 @@ public void onTagDiscovered(Tag tag) {
writeToUiAppend("03 select AID command length " + selectAidCommand.length + " data: " + bytesToHexNpe(selectAidCommand));
writeToUiAppend("03 select AID response length " + selectAidResponse.length + " data: " + bytesToHexNpe(selectAidResponse));
writeToUiAppend(prettyPrintDataToString(selectAidResponse));

writeToUiAppend(etData, "03 select AID completed");
//}
/**
* step 3 code end
*/

// intermediate step - get single data from card, will be printed later
writeToUiAppend("");
//writeToUiAppend("");
writeToUiAppend("get single data elements");
byte[] applicationTransactionCounter = getApplicationTransactionCounter(nfc);
byte[] pinTryCounter = getPinTryCounter(nfc);
byte[] lastOnlineATCRegister = getLastOnlineATCRegister(nfc);
byte[] logFormat = getLogFormat(nfc);
// print single data
writeToUiAppend(dumpSingleData(applicationTransactionCounter, pinTryCounter, lastOnlineATCRegister, logFormat));
writeToUiAppend("");

// todo remove code
/*
// does not work on my cards
byte[] challenge8Byte = getChallenge(nfc);
writeToUiAppend("challenge length: " + challenge8Byte.length + " data: " + bytesToHexNpe(challenge8Byte));
*/


/**
* step 4 code start
*/

byte[] selectAidResponseOk = checkResponse(selectAidResponse);
if (selectAidResponseOk != null) {
writeToUiAppend("");
//writeToUiAppend("");
printStepHeader(4, "search for tag 0x9F38");
writeToUiAppend("04 search for tag 0x9F38 in the selectAid response");
/**
Expand All @@ -265,13 +275,14 @@ public void onTagDiscovered(Tag tag) {
*/
BerTlvs tlvsAid = parser.parse(selectAidResponseOk);
BerTlv tag9f38 = tlvsAid.find(new BerTag(0x9F, 0x38));
writeToUiAppend(etData, "04 search for tag 0x9F38 in the selectAid response completed");
byte[] gpoRequestCommand;
if (tag9f38 != null) {
/**
* the following code is for VisaCards and (German) GiroCards as we found a PDOL
*/
writeToUiAppend("");
writeToUiAppend("### processing the VisaCard and GiroCard path ###");
writeToUiAppend("### processing the America Express, VisaCard and GiroCard path ###");
writeToUiAppend("");
byte[] pdolValue = tag9f38.getBytesValue();
/*
Expand All @@ -293,8 +304,6 @@ public void onTagDiscovered(Tag tag) {
"] length " + String.valueOf(pdolEntry.getLength()));
}
// todo show contents from pdol request returned with tags (just a dump)
// take pdol + command, extract data
gpoRequestCommand = getGpoFromPdol(pdolValue);
//gpoRequestCommand = getGetProcessingOptionsFromPdol(pdolValue); // not working for DKB Visa
Expand Down Expand Up @@ -322,7 +331,7 @@ public void onTagDiscovered(Tag tag) {
writeToUiAppend(pdolRequestString);
}

writeToUiAppend("");
//writeToUiAppend("");
printStepHeader(5, "get the processing options");
writeToUiAppend("05 get the processing options command length: " + gpoRequestCommand.length + " data: " + bytesToHexNpe(gpoRequestCommand));

Expand All @@ -340,6 +349,7 @@ public void onTagDiscovered(Tag tag) {

byte[] gpoRequestResponse = nfc.transceive(gpoRequestCommand);
byte[] gpoRequestResponseOk;
writeToUiAppend(etData, "05 get the processing options completed");
if (gpoRequestResponse != null) {
writeToUiAppend("05 get the processing options response length: " + gpoRequestResponse.length + " data: " + bytesToHexNpe(gpoRequestResponse));
gpoRequestResponseOk = checkResponse(gpoRequestResponse);
Expand Down Expand Up @@ -382,8 +392,13 @@ public void onTagDiscovered(Tag tag) {

BerTlv tag57 = tlvsGpo.find(new BerTag(0x57));
if (tag57 != null) {
writeToUiAppend("");
//writeToUiAppend("");
writeToUiAppend("workflow a)");
writeToUiAppend("");
printStepHeader(6, "read files & search PAN");
writeToUiAppend("06 read the files from card skipped");
writeToUiAppend(etData, "06 read the files from card skipped");

writeToUiAppend("the response contains a Track 2 Equivalent Data tag [tag 0x57]");
byte[] gpoResponseTag57 = tag57.getBytesValue();
writeToUiAppend("found tag 0x57 in the gpoResponse length: " + gpoResponseTag57.length + " data: " + bytesToHexNpe(gpoResponseTag57));
Expand All @@ -393,9 +408,14 @@ public void onTagDiscovered(Tag tag) {
writeToUiAppend("");
printStepHeader(7, "print PAN & expire date");
writeToUiAppend("07 get PAN and Expiration date from tag 0x57 (Track 2 Equivalent Data)");
writeToUiAppend("data for AID " + aidSelected);
writeToUiAppend(etData, "07 get PAN and Expiration date from tag 0x57 (Track 2 Equivalent Data) completed");
writeToUiAppend("data for AID " + bytesToHexNpe(aidSelected));
writeToUiAppend("PAN: " + pan);
writeToUiAppend("Expiration date (YYMM): " + expDate);
String expirationDateString = "Expiration date (" + (expDate.length() == 4 ? "YYMM): " : "YYMMDD): ") + expDate;
writeToUiAppend(expirationDateString);
writeToUiAppend(etData, "data for AID " + bytesToHexNpe(aidSelected));
writeToUiAppend(etData,"PAN: " + pan);
writeToUiAppend(etData, expirationDateString);
writeToUiAppend("");
}

Expand All @@ -409,7 +429,7 @@ public void onTagDiscovered(Tag tag) {

BerTlv tag80 = tlvsGpo.find(new BerTag(0x80));
if (tag80 != null) {
writeToUiAppend("");
//writeToUiAppend("");
writeToUiAppend("workflow b)");
writeToUiAppend("the response is of type 'Response Message Template Format 1' [tag 0x80]");
byte[] gpoResponseTag80 = tag80.getBytesValue();
Expand All @@ -427,7 +447,7 @@ public void onTagDiscovered(Tag tag) {

BerTlv tag77 = tlvsGpo.find(new BerTag(0x77));
if (tag77 != null) {
writeToUiAppend("");
//writeToUiAppend("");
writeToUiAppend("workflow c)");
writeToUiAppend("the response is of type 'Response Message Template Format 2' [tag 0x77]");
writeToUiAppend("found tag 0x77 in the gpoResponse");
Expand All @@ -442,6 +462,10 @@ public void onTagDiscovered(Tag tag) {

writeToUiAppend("");
writeToUiAppend("found this AFL data in the gpoResponse to read from: " + bytesToHexNpe(aflBytes));
writeToUiAppend("");
printStepHeader(6, "read files & search PAN");
writeToUiAppend("06 read the files from card and search for PAN & Expiration date");
writeToUiAppend(etData, "06 read the files from card and search for PAN & Expiration date");

List<byte[]> tag94BytesList = divideArray(aflBytes, 4);
int tag94BytesListLength = tag94BytesList.size();
Expand Down Expand Up @@ -513,10 +537,14 @@ public void onTagDiscovered(Tag tag) {
writeToUiAppend("");
printStepHeader(7, "print PAN & expire date");
writeToUiAppend("07 get PAN and Expiration date from tags 0x5a and 0x5f24");
writeToUiAppend(etData, "07 get PAN and Expiration date from tags 0x5a and 0x5f24 completed");
writeToUiAppend("data for AID " + bytesToHexNpe(aidSelected));
writeToUiAppend("PAN: " + readRecordPanString);
// todo yymmdd or yymm depending on length
writeToUiAppend("Expiration date (YYMM): " + readRecordExpirationDateString);
String expirationDateString = "Expiration date (" + (readRecordExpirationDateString.length() == 4 ? "YYMM): " : "YYMMDD): ") + readRecordExpirationDateString;
writeToUiAppend(expirationDateString);
writeToUiAppend(etData, "data for AID " + bytesToHexNpe(aidSelected));
writeToUiAppend(etData,"PAN: " + readRecordPanString);
writeToUiAppend(etData, expirationDateString);
writeToUiAppend("");
}
} catch (RuntimeException e) {
Expand Down Expand Up @@ -563,7 +591,7 @@ public void onTagDiscovered(Tag tag) {
* step 4 code end
*/


writeToUiAppend(etData, lineSeparatorString);
} // for (int aidNumber = 0; aidNumber < tag4fList.size(); aidNumber++) {

/**
Expand All @@ -578,6 +606,7 @@ public void onTagDiscovered(Tag tag) {
}

printStepHeader(99, "our journey ends");
writeToUiAppend(etData, "99 reading of the card completed");
vibrate();


Expand Down Expand Up @@ -1342,19 +1371,37 @@ public static String trimLeadingLineFeeds(String input) {
return output.length > 1 ? output[1] : output[0];
}

private void clearData(final TextView textView) {
private void clearData() {
runOnUiThread(() -> {
outputString = "";
exportString = "";
textView.setText("");
etData.setText("");
etLog.setText("");
});
}

private void writeToUiAppend(String message) {
System.out.println(message);
//System.out.println(message);
outputString = outputString + message + "\n";
}

private void writeToUiAppend(final TextView textView, String message) {
runOnUiThread(() -> {
if (TextUtils.isEmpty(textView.getText().toString())) {
if (textView == (TextView) etLog) {
} else {
textView.setText(message);
}
} else {
String newString = textView.getText().toString() + "\n" + message;
if (textView == (TextView) etLog) {
} else {
textView.setText(newString);
}
}
});
}

private void writeToUiFinal(final TextView textView) {
if (textView == (TextView) etLog) {
runOnUiThread(new Runnable() {
Expand Down
27 changes: 27 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,33 @@

</LinearLayout>

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/etDataLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="Data:"
android:visibility="visible"
app:boxCornerRadiusBottomEnd="5dp"
app:boxCornerRadiusBottomStart="5dp"
app:boxCornerRadiusTopEnd="5dp"
app:boxCornerRadiusTopStart="5dp"
app:endIconMode="clear_text">

<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:focusable="false"
android:fontFamily="monospace"
android:text=""
android:textSize="14sp"
android:visibility="visible"
tools:ignore="KeyboardInaccessibleWidget" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/etLogLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
Expand Down

0 comments on commit f1c87dc

Please sign in to comment.