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 yk_cmd[] = {0x00, 0x01, 0xff, 0x00};
16 static BYTE cr_for_slot[3] = {0xff, 0x30, 0x38};
18 static int slot = 2; /* second by default, people tend to leave */
19 /* the first with factory settings. */
21 static int ykn_parse_option(char *key, char *val)
23 if (!strcmp(key, "slot")) {
24 if (!strcmp(val, "1")) {
26 } else if (!strcmp(val, "2")) {
37 static DWORD ykn_check_atr_hb(BYTE *str, DWORD size)
39 if (size < strlen(NAMEPFX)) return SCARD_W_UNSUPPORTED_CARD;
40 if (memcmp(str, NAMEPFX, strlen(NAMEPFX)))
41 return SCARD_W_UNSUPPORTED_CARD;
42 return SCARD_S_SUCCESS;
45 static DWORD ykn_prologue(SCARDHANDLE hCard)
48 DWORD rsize = sizeof(buf);
49 DWORD rc = SCardBeginTransaction(hCard);
51 rc = SCardTransmit(hCard, &pioSendPci, selcmd, sizeof(selcmd),
54 if ((buf[rsize-2] == 0x90) && (buf[rsize-1] == 0x00))
55 return SCARD_S_SUCCESS;
56 else return SCARD_W_CARD_NOT_AUTHENTICATED;
59 static DWORD ykn_getserial(SCARDHANDLE hCard, BYTE *recv, LPDWORD recvsize_p)
63 DWORD rsize = sizeof(rbuf);
64 BYTE sbuf[sizeof(yk_cmd) + 1];
67 memcpy(sbuf, yk_cmd, sizeof(yk_cmd));
68 sbuf[2] = 0x10; /* read serial */
70 rc = SCardTransmit(hCard, &pioSendPci, sbuf, sizeof(sbuf),
73 if ((rbuf[rsize-2] != 0x90) || (rbuf[rsize-1] != 0x00))
74 return SCARD_W_CARD_NOT_AUTHENTICATED;
75 serial = (rbuf[0]<<24) + (rbuf[1]<<16) + (rbuf[2]<<8) + (rbuf[3]);
76 rc = snprintf(recv, *recvsize_p, "%u", serial);
78 return SCARD_S_SUCCESS;
81 static DWORD ykn_trancieve(SCARDHANDLE hCard,
82 BYTE *send, DWORD sendsize, BYTE *recv, LPDWORD recvsize_p)
85 DWORD rsize = *recvsize_p + 2;
86 BYTE *rbuf = alloca(rsize);
87 BYTE *sbuf = alloca(sendsize + 6);
88 memcpy(sbuf, yk_cmd, sizeof(yk_cmd));
89 sbuf[2] = cr_for_slot[slot];
90 sbuf[sizeof(yk_cmd)] = sendsize;
91 memcpy(sbuf + sizeof(yk_cmd) + 1, send, sendsize);
92 sbuf[sendsize + 5] = rsize;
93 rc = SCardTransmit(hCard, &pioSendPci, sbuf, sendsize + 6,
96 if ((rbuf[rsize-2] != 0x90) || (rbuf[rsize-1] != 0x00))
97 return SCARD_W_CARD_NOT_AUTHENTICATED;
98 memcpy(recv, rbuf, rsize - 2);
99 *recvsize_p = rsize - 2;
100 return SCARD_S_SUCCESS;
103 static DWORD ykn_epilogue(SCARDHANDLE hCard)
105 return SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
108 struct token_interface ykneo_interface = {
110 .parse_option = ykn_parse_option,
111 .check_atr_hb = ykn_check_atr_hb,
112 .prologue = ykn_prologue,
113 .getserial = ykn_getserial,
114 .trancieve = ykn_trancieve,
115 .epilogue = ykn_epilogue,