]> www.average.org Git - pam_pcsc_cr.git/blob - pcsc_cr.c
configure.ac: remove sanitizer by default
[pam_pcsc_cr.git] / pcsc_cr.c
1 /*
2 Copyright (c) 2013 Eugene Crosser
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12     1. The origin of this software must not be misrepresented; you must
13     not claim that you wrote the original software. If you use this
14     software in a product, an acknowledgment in the product documentation
15     would be appreciated but is not required.
16
17     2. Altered source versions must be plainly marked as such, and must
18     not be misrepresented as being the original software.
19
20     3. This notice may not be removed or altered from any source
21     distribution.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27 #include <stdio.h>
28 #include <string.h>
29 #include <alloca.h>
30 #include "token.h"
31 #include <reader.h>
32
33 extern struct token_interface ykneo_interface;
34
35 static struct token_interface *types[] = {
36         &ykneo_interface,
37         NULL,
38 };
39
40 SCARD_IO_REQUEST pioSendPci;
41
42 static LONG find_hb(BYTE *atr, DWORD atrsize, BYTE **hb, LPDWORD hbsize)
43 {
44         DWORD i;
45         int j, cont;
46         if (atrsize < 2) return SCARD_W_UNSUPPORTED_CARD;
47         switch (atr[0]) {
48         case 0x3B: break;
49         case 0x3F: break;
50         default: return SCARD_W_UNSUPPORTED_CARD;
51         }
52         *hbsize = atr[1]&0x0f;
53         i=1;
54         do {
55                 cont = atr[i]>>4;
56                 for (j = 0; j < 4; j++) if (cont & (0x01 << j)) i++;
57         } while ((cont & 0x08) && (i < atrsize));
58         if ((i + (*hbsize) + 2) != atrsize)
59                 return SCARD_W_UNSUPPORTED_CARD;
60         *hb = atr + i + 1;
61         return SCARD_S_SUCCESS;
62 }
63
64 long pcsc_cr(const unsigned char *chal, const int csize,
65                 unsigned char *resp, int *rsize)
66 {
67         struct token_interface *type;
68         LONG rc;
69         SCARDCONTEXT hContext;
70         LPTSTR readers, rdr;
71         SCARDHANDLE hCard;
72         DWORD nrdrs = SCARD_AUTOALLOCATE, activeproto;
73         BYTE atr[33];
74         DWORD atrsize;
75         BYTE *hb;
76         DWORD hbsize;
77         DWORD lrsize;
78         int i;
79
80         rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
81         if (rc) return rc;
82         rc = SCardListReaders(hContext, NULL, (LPTSTR)&readers, &nrdrs);
83         if (rc) return rc;
84         for (rdr=readers; rdr < readers + nrdrs - 1; rdr += strlen(rdr) + 1) {
85                 rc = SCardConnect(hContext, rdr, SCARD_SHARE_SHARED,
86                         SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
87                         &hCard, &activeproto);
88                 if (rc) continue;
89                 switch (activeproto) {
90                 case SCARD_PROTOCOL_T0:
91                         pioSendPci = *SCARD_PCI_T0;
92                         break;
93                 case SCARD_PROTOCOL_T1:
94                         pioSendPci = *SCARD_PCI_T1;
95                         break;
96                 }
97                 atrsize = sizeof(atr);
98                 rc = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING,
99                         atr, &atrsize);
100                 if (rc) goto disconnect;
101                 rc = find_hb(atr, atrsize, &hb, &hbsize);
102                 if (rc) goto disconnect;
103                 for (i = 0; types[i]; i++) {
104                         type = types[i];
105                         rc = type->check_atr_hb(hb, hbsize);
106                         if (rc == 0) break;
107                 }
108                 if (rc) goto disconnect;
109                 rc = type->prologue(hCard);
110                 if (rc == 0) break;
111         disconnect:
112                 (void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
113         }
114         if (rc) goto free_out;
115 #if 0
116         char serial[16];
117         memset(serial, 'z', sizeof(serial));
118         serial[sizeof(serial) - 1] - '\0';
119         lrsize = sizeof(serial);
120         rc = type->getserial(hCard, &serial, &lrsize);
121         if (rc) goto disc_free_out;
122         printf("Serial is %s\n", serial);
123 #endif
124         lrsize = *rsize;
125         rc = type->trancieve(hCard, (BYTE*)chal, csize, resp, &lrsize);
126         if (rc) goto disc_free_out;
127         *rsize = lrsize;
128         rc = type->epilogue(hCard);
129 disc_free_out:
130         (void)SCardDisconnect(hCard, SCARD_EJECT_CARD);
131 free_out:
132         (void)SCardFreeMemory(hContext, readers);
133         return rc;
134 }
135
136 const char *pcsc_errstr(long err) {
137         return pcsc_stringify_error(err);
138 }
139
140 int pcsc_option(const char *option)
141 {
142         char *name, *key, *val;
143         int i, rc = -1;
144         struct token_interface *type;
145
146         name=(char *)alloca(strlen(option)+1);
147         strcpy(name, option);
148         if ((key = strchr(name, ':'))) *(key++) = '\0';
149         else return -1;
150         if ((val = strchr(key, '='))) *(val++) = '\0';
151         else return -1;
152         if (*val == '\0') return -1;
153         for (i = 0; types[i]; i++) {
154                 type = types[i];
155                 if (!strcmp(type->name,name)) {
156                         rc = type->parse_option(key, val);
157                         break;
158                 }
159         }
160         return rc;
161 }