]> www.average.org Git - YkNeoCR.git/blobdiff - src/org/average/nfcauthcr/YkNeo.java
Renamed classes
[YkNeoCR.git] / src / org / average / nfcauthcr / YkNeo.java
diff --git a/src/org/average/nfcauthcr/YkNeo.java b/src/org/average/nfcauthcr/YkNeo.java
new file mode 100644 (file)
index 0000000..a291eab
--- /dev/null
@@ -0,0 +1,75 @@
+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;
+
+public class YkNeo {
+
+       // This is a CCID APDU, ISO 7816-4.
+       // 00 A4 04 00 xx AID - GlobalPlatform - SELECT
+       // Lc, send data = 07: A0 00 00 05 27 20 01
+       // Le, recv data = 00
+       private static final byte[] selectApdu =
+               {0x00, (byte) 0xA4, 0x04, 0x00, 0x07, (byte) 0xA0,
+                0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 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(selectApdu);
+                       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[] crApdu = new byte[69];
+                       crApdu[0] = 0x00; // CLA
+                       crApdu[1] = 0x01; // INS
+                       switch (slot) {
+                       case 1: crApdu[2] = SLOT_CHAL_HMAC1; break; // P1
+                       case 2: crApdu[2] = SLOT_CHAL_HMAC2; break; // P1
+                       }
+                       crApdu[3] = 0x00; // P2
+                       crApdu[4] = 63;   // Lc
+                       System.arraycopy(challenge, 0, crApdu, 5,
+                                               challenge.length); // Payload
+                       crApdu[crApdu.length-1] = 22; // Le
+                       resp = isoTag.transceive(crApdu);
+                       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;
+       }
+}