+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <stdlib.h>
#include <string.h>
#include <alloca.h>
static const BYTE selcmd[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xA0,
0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x00};
-static const BYTE cr_cmd[] = {0x00, 0x01, 0x38, 0x00};
+static const BYTE yk_cmd[] = {0x00, 0x01, 0xff, 0x00};
-static DWORD ykn_check_atr_hb(LPTSTR str, DWORD size)
+static BYTE cr_for_slot[3] = {0xff, 0x30, 0x38};
+
+static int slot = 2; /* second by default, people tend to leave */
+ /* the first with factory settings. */
+
+static int ykn_parse_option(char *key, char *val)
+{
+ if (!strcmp(key, "slot")) {
+ if (!strcmp(val, "1")) {
+ slot = 1;
+ } else if (!strcmp(val, "2")) {
+ slot = 2;
+ } else {
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+static DWORD ykn_check_atr_hb(BYTE *str, DWORD size)
{
if (size < strlen(NAMEPFX)) return SCARD_W_UNSUPPORTED_CARD;
if (memcmp(str, NAMEPFX, strlen(NAMEPFX)))
return SCARD_S_SUCCESS;
}
-static DWORD ykn_prologue(SCARDHANDLE hCard,LPTSTR envp[])
+static DWORD ykn_prologue(SCARDHANDLE hCard)
{
BYTE buf[258];
DWORD rsize = sizeof(buf);
else return SCARD_W_CARD_NOT_AUTHENTICATED;
}
-static DWORD ykn_trancieve(SCARDHANDLE hCard,LPTSTR envp[],
- LPTSTR send, DWORD sendsize, LPTSTR recv, LPDWORD recvsize_p)
+static DWORD ykn_getserial(SCARDHANDLE hCard, BYTE *recv, LPDWORD recvsize_p)
+{
+ DWORD rc;
+ BYTE rbuf[4 + 2];
+ DWORD rsize = sizeof(rbuf);
+ BYTE sbuf[sizeof(yk_cmd) + 1];
+ unsigned int serial;
+
+ memcpy(sbuf, yk_cmd, sizeof(yk_cmd));
+ sbuf[2] = 0x10; /* read serial */
+ sbuf[4] = rsize;
+ rc = SCardTransmit(hCard, &pioSendPci, sbuf, sizeof(sbuf),
+ NULL, rbuf, &rsize);
+ if (rc) return rc;
+ if ((rbuf[rsize-2] != 0x90) || (rbuf[rsize-1] != 0x00))
+ return SCARD_W_CARD_NOT_AUTHENTICATED;
+ serial = (rbuf[0]<<24) + (rbuf[1]<<16) + (rbuf[2]<<8) + (rbuf[3]);
+ rc = snprintf(recv, *recvsize_p, "%u", serial);
+ *recvsize_p = rc;
+ return SCARD_S_SUCCESS;
+}
+
+static DWORD ykn_trancieve(SCARDHANDLE hCard,
+ BYTE *send, DWORD sendsize, BYTE *recv, LPDWORD recvsize_p)
{
DWORD rc;
DWORD rsize = *recvsize_p + 2;
BYTE *rbuf = alloca(rsize);
BYTE *sbuf = alloca(sendsize + 6);
- memcpy(sbuf, cr_cmd, sizeof(cr_cmd));
- sbuf[sizeof(cr_cmd)] = sendsize;
- memcpy(sbuf + sizeof(cr_cmd) + 1, send, sendsize);
+ memcpy(sbuf, yk_cmd, sizeof(yk_cmd));
+ sbuf[2] = cr_for_slot[slot];
+ sbuf[sizeof(yk_cmd)] = sendsize;
+ memcpy(sbuf + sizeof(yk_cmd) + 1, send, sendsize);
sbuf[sendsize + 5] = rsize;
rc = SCardTransmit(hCard, &pioSendPci, sbuf, sendsize + 6,
NULL, rbuf, &rsize);
return SCARD_S_SUCCESS;
}
-static DWORD ykn_epilogue(SCARDHANDLE hCard,LPTSTR envp[])
+static DWORD ykn_epilogue(SCARDHANDLE hCard)
{
return SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
}
struct token_interface ykneo_interface = {
+ .name = "ykneo",
+ .parse_option = ykn_parse_option,
.check_atr_hb = ykn_check_atr_hb,
.prologue = ykn_prologue,
+ .getserial = ykn_getserial,
.trancieve = ykn_trancieve,
.epilogue = ykn_epilogue,
};