7 #define NAMEPFX "YubikeyNEO"
9 static const BYTE selcmd[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xA0,
10 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x00};
11 static const BYTE cr_cmd[] = {0x00, 0x01, 0xff, 0x00};
13 static BYTE cr_for_slot[3] = {0xff, 0x30, 0x38};
17 static int ykn_parse_option(char *key, char *val)
19 if (!strcmp(key, "slot")) {
20 if (!strcmp(val, "1")) {
22 } else if (!strcmp(val, "2")) {
33 static DWORD ykn_check_atr_hb(LPTSTR str, DWORD size)
35 if (size < strlen(NAMEPFX)) return SCARD_W_UNSUPPORTED_CARD;
36 if (memcmp(str, NAMEPFX, strlen(NAMEPFX)))
37 return SCARD_W_UNSUPPORTED_CARD;
38 return SCARD_S_SUCCESS;
41 static DWORD ykn_prologue(SCARDHANDLE hCard,LPTSTR envp[])
44 DWORD rsize = sizeof(buf);
45 DWORD rc = SCardBeginTransaction(hCard);
47 rc = SCardTransmit(hCard, &pioSendPci, selcmd, sizeof(selcmd),
50 if ((buf[rsize-2] == 0x90) && (buf[rsize-1] == 0x00))
51 return SCARD_S_SUCCESS;
52 else return SCARD_W_CARD_NOT_AUTHENTICATED;
55 static DWORD ykn_trancieve(SCARDHANDLE hCard,LPTSTR envp[],
56 LPTSTR send, DWORD sendsize, LPTSTR recv, LPDWORD recvsize_p)
59 DWORD rsize = *recvsize_p + 2;
60 BYTE *rbuf = alloca(rsize);
61 BYTE *sbuf = alloca(sendsize + 6);
62 memcpy(sbuf, cr_cmd, sizeof(cr_cmd));
63 sbuf[2] = cr_for_slot[slot];
64 sbuf[sizeof(cr_cmd)] = sendsize;
65 memcpy(sbuf + sizeof(cr_cmd) + 1, send, sendsize);
66 sbuf[sendsize + 5] = rsize;
67 rc = SCardTransmit(hCard, &pioSendPci, sbuf, sendsize + 6,
70 if ((rbuf[rsize-2] != 0x90) || (rbuf[rsize-1] != 0x00))
71 return SCARD_W_CARD_NOT_AUTHENTICATED;
72 memcpy(recv, rbuf, rsize - 2);
73 *recvsize_p = rsize - 2;
74 return SCARD_S_SUCCESS;
77 static DWORD ykn_epilogue(SCARDHANDLE hCard,LPTSTR envp[])
79 return SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
82 struct token_interface ykneo_interface = {
84 .parse_option = ykn_parse_option,
85 .check_atr_hb = ykn_check_atr_hb,
86 .prologue = ykn_prologue,
87 .trancieve = ykn_trancieve,
88 .epilogue = ykn_epilogue,