10 #define NAMEPFX "YubikeyNEO"
12 static const BYTE selcmd[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xA0,
13 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x00};
14 static const BYTE cr_cmd[] = {0x00, 0x01, 0xff, 0x00};
16 static BYTE cr_for_slot[3] = {0xff, 0x30, 0x38};
20 static int ykn_parse_option(char *key, char *val)
22 if (!strcmp(key, "slot")) {
23 if (!strcmp(val, "1")) {
25 } else if (!strcmp(val, "2")) {
36 static DWORD ykn_check_atr_hb(BYTE *str, DWORD size)
38 if (size < strlen(NAMEPFX)) return SCARD_W_UNSUPPORTED_CARD;
39 if (memcmp(str, NAMEPFX, strlen(NAMEPFX)))
40 return SCARD_W_UNSUPPORTED_CARD;
41 return SCARD_S_SUCCESS;
44 static DWORD ykn_prologue(SCARDHANDLE hCard)
47 DWORD rsize = sizeof(buf);
48 DWORD rc = SCardBeginTransaction(hCard);
50 rc = SCardTransmit(hCard, &pioSendPci, selcmd, sizeof(selcmd),
53 if ((buf[rsize-2] == 0x90) && (buf[rsize-1] == 0x00))
54 return SCARD_S_SUCCESS;
55 else return SCARD_W_CARD_NOT_AUTHENTICATED;
58 static DWORD ykn_trancieve(SCARDHANDLE hCard,
59 BYTE *send, DWORD sendsize, BYTE *recv, LPDWORD recvsize_p)
62 DWORD rsize = *recvsize_p + 2;
63 BYTE *rbuf = alloca(rsize);
64 BYTE *sbuf = alloca(sendsize + 6);
65 memcpy(sbuf, cr_cmd, sizeof(cr_cmd));
66 sbuf[2] = cr_for_slot[slot];
67 sbuf[sizeof(cr_cmd)] = sendsize;
68 memcpy(sbuf + sizeof(cr_cmd) + 1, send, sendsize);
69 sbuf[sendsize + 5] = rsize;
70 rc = SCardTransmit(hCard, &pioSendPci, sbuf, sendsize + 6,
73 if ((rbuf[rsize-2] != 0x90) || (rbuf[rsize-1] != 0x00))
74 return SCARD_W_CARD_NOT_AUTHENTICATED;
75 memcpy(recv, rbuf, rsize - 2);
76 *recvsize_p = rsize - 2;
77 return SCARD_S_SUCCESS;
80 static DWORD ykn_epilogue(SCARDHANDLE hCard)
82 return SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
85 struct token_interface ykneo_interface = {
87 .parse_option = ykn_parse_option,
88 .check_atr_hb = ykn_check_atr_hb,
89 .prologue = ykn_prologue,
90 .trancieve = ykn_trancieve,
91 .epilogue = ykn_epilogue,