handle multivalue challenges
[YkNeoCR.git] / src / org / average / nfcauthcr / YkNeo.java
index 9c19135b23194dfb5afbf2948445c4892a8f1be2..96f3e0fbb53b776a02444b17f07c8608ca80935f 100644 (file)
@@ -1,15 +1,16 @@
-package org.average.nfcauthcr;
+package org.average.ykneocr;
 
 import java.io.IOException;
 import java.lang.String;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Iterator;
 
 import android.nfc.NfcAdapter;
 import android.nfc.Tag;
 import android.nfc.tech.IsoDep;
 
-import org.average.nfcauthcr.CRException;
+import org.average.ykneocr.CRException;
 
 public class YkNeo {
 
@@ -43,12 +44,6 @@ public class YkNeo {
        public static ArrayList<String> doChalResp(IsoDep isoTag, int slot,
                                        ArrayList<String> cset)
                        throws IOException, CRException {
-               byte[] challenge = unhex(cset.get(0));
-               if (challenge.length > 127) {
-                       throw new CRException(String.format(
-                       "NFC challenge size too big: %d",
-                       challenge.length));
-               }
                if (slot != 1 && slot != 2) {
                        throw new CRException(String.format(
                        "NFC Yubikey slot is %d, can be 1 or 2",
@@ -62,33 +57,44 @@ public class YkNeo {
                        "NFC select error code: %02x:%02x",
                        resp[length - 2], resp[length - 1]));
                }
-               byte[] crApdu = new byte[6+challenge.length];
-               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] = (byte)challenge.length; // Lc
-               System.arraycopy(challenge, 0, crApdu, 5,
-                                       challenge.length); // Payload
-               crApdu[5+challenge.length] = 22; // Le
-               resp = isoTag.transceive(crApdu);
-               length = resp.length;
-               if (resp[length - 2] != (byte)0x90 ||
-                   resp[length - 1] != 0x00) {
-                       throw new CRException(String.format(
-                       "NFC CR error code: %02x:%02x",
-                       resp[length - 2], resp[length - 1]));
-               }
-               if (length <= 2) {
-                       throw new CRException(String.format(
-                       "NFC wrong response size: only %d bytes",
-                       length-2));
-               }
                ArrayList<String> rset = new ArrayList<String>();
-               rset.add(hex(Arrays.copyOf(resp, length-2)));
+
+               Iterator itr = cset.iterator();
+               while (itr.hasNext()) {
+                       byte[] challenge = unhex((String)itr.next());
+                       if (challenge.length > 127) {
+                               throw new CRException(String.format(
+                               "NFC challenge size too big: %d",
+                               challenge.length));
+                       }
+                       byte[] crApdu = new byte[6+challenge.length];
+                       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] = (byte)challenge.length; // Lc
+                       System.arraycopy(challenge, 0, crApdu, 5,
+                                               challenge.length); // Payload
+                       crApdu[5+challenge.length] = 22; // Le
+                       resp = isoTag.transceive(crApdu);
+                       length = resp.length;
+                       if (resp[length - 2] != (byte)0x90 ||
+                           resp[length - 1] != 0x00) {
+                               throw new CRException(String.format(
+                               "NFC CR error code: %02x:%02x",
+                               resp[length - 2], resp[length - 1]));
+                       }
+                       if (length <= 2) {
+                               throw new CRException(String.format(
+                               "NFC wrong response size: only %d bytes",
+                               length-2));
+                       }
+                       rset.add(hex(Arrays.copyOf(resp, length-2)));
+               }
+
                return rset;
        }