package org.average.nfcauthcr;
-import java.io.IOException;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
private final String TAG = getClass().getName();
- private static final byte[] selectCommand =
- {0x00, (byte) 0xA4, 0x04, 0x00, 0x07, (byte) 0xA0,
- 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x00};
-
private AlertDialog swipeDialog;
private PendingIntent tagIntent;
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag == null) return;
IsoDep isoTag = IsoDep.get(tag);
- byte[] response = doChallengeYubiKey(isoTag, slot, challenge);
+ byte[] response = NFCAuthCRYubiNeo.doChallengeYubiKey(
+ isoTag, slot, challenge);
if (response != null) {
Intent data = getIntent();
data.putExtra("response", response);
adapter.disableForegroundDispatch(this);
}
}
-
- private byte[] doChallengeYubiKey(IsoDep isoTag, int slot,
- byte[] challenge) {
- try {
- isoTag.connect();
- byte[] resp = isoTag.transceive(selectCommand);
- int length = resp.length;
- if (resp[length - 2] == (byte)0x90 &&
- resp[length - 1] == 0x00) {
- return challenge;
- } else {
- Toast.makeText(this, R.string.tag_error,
- Toast.LENGTH_LONG).show();
- }
- } catch (TagLostException e) {
- Toast.makeText(this,
- R.string.tag_lost, Toast.LENGTH_LONG).show();
- } catch (IOException e) {
- Toast.makeText(this,
- getText(R.string.tag_error) +
- e.getMessage(),
- Toast.LENGTH_LONG).show();
- }
- return null;
- }
}
--- /dev/null
+package org.average.nfcauthcr;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.nfc.TagLostException;
+import android.nfc.tech.IsoDep;
+import android.util.Log;
+
+import org.average.nfcauthcr.NFCAuthCRYubiNeo;
+
+public class NFCAuthCRYubiNeo {
+
+ private static final String TAG = "NFCAuthCRYubiNeo";
+
+ // Is it CCID APDU? ISO 7816-4?
+
+ // 00 A4 04 00 xx AID - GlobalPlatform - SELECT
+ // Le send data = 07: A0 00 00 05 27 20 01
+ // Le recv data = 00
+ private static final byte[] selectCommand =
+ {0x00, (byte) 0xA4, 0x04, 0x00, 0x07, (byte) 0xA0,
+ 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x00};
+
+ private static final byte[] crCommand =
+ {0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
+
+ private static final byte SLOT_CHAL_HMAC1 = 0x30;
+ private static final byte SLOT_CHAL_HMAC2 = 0x38;
+
+ public static final byte[] doChallengeYubiKey(IsoDep isoTag, int slot,
+ byte[] challenge) {
+ try {
+ isoTag.connect();
+ byte[] resp = isoTag.transceive(selectCommand);
+ int length = resp.length;
+ Log.v(TAG, "response to select length is " + length);
+ if (resp[length - 2] != (byte)0x90 ||
+ resp[length - 1] != 0x00) {
+ Log.v(TAG, "Wrong response to select");
+ //Toast.makeText(this, R.string.tag_error,
+ // Toast.LENGTH_LONG).show();
+ return null;
+ }
+ byte[] apdu = new byte[69];
+ apdu[0] = 0x00; // CLA
+ apdu[1] = 0x01; // INS
+ switch (slot) {
+ case 1: apdu[2] = SLOT_CHAL_HMAC1; break; // P1
+ case 2: apdu[2] = SLOT_CHAL_HMAC2; break; // P1
+ }
+ apdu[3] = 0x00; // P2
+ apdu[4] = 63; // Lc
+ System.arraycopy(challenge, 0, apdu, 5,
+ challenge.length);
+ apdu[apdu.length-1] = 22;
+ resp = isoTag.transceive(apdu);
+ length = resp.length;
+ if (resp[length - 2] != (byte)0x90 ||
+ resp[length - 1] != 0x00) {
+ Log.v(TAG, "Wrong response to challenge");
+ //Toast.makeText(this, R.string.tag_error,
+ // Toast.LENGTH_LONG).show();
+ return null;
+ }
+ Log.v(TAG, "response to challenge length is " + length);
+ return Arrays.copyOf(resp, length-2);
+ } catch (TagLostException e) {
+ Log.v(TAG, e.getMessage());
+ //Toast.makeText(this,
+ // R.string.tag_lost, Toast.LENGTH_LONG).show();
+ } catch (IOException e) {
+ Log.v(TAG, e.getMessage());
+ //Toast.makeText(this,
+ // getText(R.string.tag_error) +
+ // e.getMessage(),
+ // Toast.LENGTH_LONG).show();
+ }
+ return null;
+ }
+}