]> www.average.org Git - pam_pcsc_cr.git/blob - pcsc_cr.c
change serialization interface
[pam_pcsc_cr.git] / pcsc_cr.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 #include <stdio.h>
5 #include <string.h>
6 #include <alloca.h>
7 #include "token.h"
8 #include <reader.h>
9
10 extern struct token_interface ykneo_interface;
11
12 static struct token_interface *types[] = {
13         &ykneo_interface,
14         NULL,
15 };
16
17 SCARD_IO_REQUEST pioSendPci;
18
19 static LONG find_hb(BYTE *atr, DWORD atrsize, BYTE **hb, LPDWORD hbsize)
20 {
21         int i, j, cont;
22         if (atrsize < 2) return SCARD_W_UNSUPPORTED_CARD;
23         switch (atr[0]) {
24         case 0x3B: break;
25         case 0x3F: break;
26         default: return SCARD_W_UNSUPPORTED_CARD;
27         }
28         *hbsize = atr[1]&0x0f;
29         i=1;
30         do {
31                 cont = atr[i]>>4;
32                 for (j = 0; j < 4; j++) if (cont & (0x01 << j)) i++;
33         } while ((cont & 0x08) && (i < atrsize));
34         if ((i + (*hbsize) + 2) != atrsize)
35                 return SCARD_W_UNSUPPORTED_CARD;
36         *hb = atr + i + 1;
37         return SCARD_S_SUCCESS;
38 }
39
40 long pcsc_cr(unsigned char *chal, int csize, unsigned char *resp, int *rsize)
41 {
42         struct token_interface *type;
43         LONG rc;
44         SCARDCONTEXT hContext;
45         LPTSTR readers, rdr;
46         SCARDHANDLE hCard;
47         DWORD nrdrs = SCARD_AUTOALLOCATE, activeproto;
48         BYTE atr[33];
49         DWORD atrsize;
50         BYTE *hb;
51         DWORD hbsize;
52         DWORD lrsize;
53         int i;
54
55         rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
56         if (rc) return rc;
57         rc = SCardListReaders(hContext, NULL, (LPTSTR)&readers, &nrdrs);
58         if (rc) return rc;
59         for (rdr=readers; rdr < readers + nrdrs - 1; rdr += strlen(rdr) + 1) {
60                 rc = SCardConnect(hContext, rdr, SCARD_SHARE_SHARED,
61                         SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
62                         &hCard, &activeproto);
63                 if (rc) continue;
64                 switch (activeproto) {
65                 case SCARD_PROTOCOL_T0:
66                         pioSendPci = *SCARD_PCI_T0;
67                         break;
68                 case SCARD_PROTOCOL_T1:
69                         pioSendPci = *SCARD_PCI_T1;
70                         break;
71                 }
72                 atrsize = sizeof(atr);
73                 rc = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING,
74                         atr, &atrsize);
75                 if (rc) goto disconnect;
76                 rc = find_hb(atr, atrsize, &hb, &hbsize);
77                 if (rc) goto disconnect;
78                 for (i = 0; types[i]; i++) {
79                         type = types[i];
80                         rc = type->check_atr_hb(hb, hbsize);
81                         if (rc == 0) break;
82                 }
83                 if (rc) goto disconnect;
84                 rc = type->prologue(hCard);
85                 if (rc == 0) break;
86         disconnect:
87                 (void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
88         }
89         if (rc) goto free_out;
90 #if 0
91         char serial[16];
92         memset(serial, 'z', sizeof(serial));
93         serial[sizeof(serial) - 1] - '\0';
94         lrsize = sizeof(serial);
95         rc = type->getserial(hCard, &serial, &lrsize);
96         if (rc) goto disc_free_out;
97         printf("Serial is %s\n", serial);
98 #endif
99         lrsize = *rsize;
100         rc = type->trancieve(hCard, chal, csize, resp, &lrsize);
101         if (rc) goto disc_free_out;
102         *rsize = lrsize;
103         rc = type->epilogue(hCard);
104 disc_free_out:
105         (void)SCardDisconnect(hCard, SCARD_EJECT_CARD);
106 free_out:
107         (void)SCardFreeMemory(hContext, readers);
108         return rc;
109 }
110
111 char *pcsc_errstr(long err) {
112         return pcsc_stringify_error(err);
113 }
114
115 int pcsc_option(char *option)
116 {
117         char *name, *key, *val;
118         int i, rc = -1;
119         struct token_interface *type;
120
121         name=(char *)alloca(strlen(option)+1);
122         strcpy(name, option);
123         if ((key = strchr(name, ':'))) *(key++) = '\0';
124         else return -1;
125         if ((val = strchr(key, '='))) *(val++) = '\0';
126         else return -1;
127         if (*val == '\0') return -1;
128         for (i = 0; types[i]; i++) {
129                 type = types[i];
130                 if (!strcmp(type->name,name)) {
131                         rc = type->parse_option(key, val);
132                         break;
133                 }
134         }
135         return rc;
136 }