Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2022 Yubico AB. All rights reserved. |
3 | | * Use of this source code is governed by a BSD-style |
4 | | * license that can be found in the LICENSE file. |
5 | | * SPDX-License-Identifier: BSD-2-Clause |
6 | | */ |
7 | | |
8 | | #undef NDEBUG |
9 | | |
10 | | #include <assert.h> |
11 | | #include <stdint.h> |
12 | | #include <stdlib.h> |
13 | | #include <string.h> |
14 | | #include <stdio.h> |
15 | | #include <winscard.h> |
16 | | |
17 | | #include "mutator_aux.h" |
18 | | |
19 | | static const struct blob *reader_list; |
20 | | static int (*xread)(void *, u_char *, size_t, int); |
21 | | static int (*xwrite)(void *, const u_char *, size_t); |
22 | | static void (*xconsume)(const void *, size_t); |
23 | | |
24 | | LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT); |
25 | | LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD); |
26 | | LONG __wrap_SCardReleaseContext(SCARDCONTEXT); |
27 | | LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE, |
28 | | LPDWORD); |
29 | | LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD); |
30 | | LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE, |
31 | | DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD); |
32 | | |
33 | | LONG |
34 | | __wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, |
35 | | LPCVOID pvReserved2, LPSCARDCONTEXT phContext) |
36 | 236k | { |
37 | 236k | assert(dwScope == SCARD_SCOPE_SYSTEM); |
38 | 236k | assert(pvReserved1 == NULL); |
39 | 236k | assert(pvReserved2 == NULL); |
40 | | |
41 | 236k | *phContext = 1; |
42 | | |
43 | 236k | if (uniform_random(400) < 1) |
44 | 671 | return SCARD_E_NO_SERVICE; |
45 | 235k | if (uniform_random(400) < 1) |
46 | 628 | return SCARD_E_NO_SMARTCARD; |
47 | 235k | if (uniform_random(400) < 1) |
48 | 603 | return SCARD_E_NO_MEMORY; |
49 | 234k | if (uniform_random(400) < 1) |
50 | 635 | *phContext = 0; |
51 | | |
52 | 234k | return SCARD_S_SUCCESS; |
53 | 235k | } |
54 | | |
55 | | LONG |
56 | | __wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, |
57 | | LPSTR mszReaders, LPDWORD pcchReaders) |
58 | 122k | { |
59 | 122k | assert(hContext == 1); |
60 | 122k | assert(mszGroups == NULL); |
61 | 122k | assert(mszReaders != NULL); |
62 | 122k | assert(pcchReaders != 0); |
63 | | |
64 | 122k | if (reader_list == NULL || uniform_random(400) < 1) |
65 | 5.74k | return SCARD_E_NO_READERS_AVAILABLE; |
66 | 116k | if (uniform_random(400) < 1) |
67 | 330 | return SCARD_E_NO_MEMORY; |
68 | | |
69 | 116k | memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ? |
70 | 116k | *pcchReaders : reader_list->len); |
71 | 116k | *pcchReaders = (DWORD)reader_list->len; /* on purpose */ |
72 | | |
73 | 116k | return SCARD_S_SUCCESS; |
74 | 116k | } |
75 | | |
76 | | LONG |
77 | | __wrap_SCardReleaseContext(SCARDCONTEXT hContext) |
78 | 235k | { |
79 | 235k | assert(hContext == 1); |
80 | | |
81 | 235k | return SCARD_S_SUCCESS; |
82 | 235k | } |
83 | | |
84 | | LONG |
85 | | __wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, |
86 | | DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) |
87 | 162k | { |
88 | 162k | uint32_t r; |
89 | | |
90 | 162k | assert(hContext == 1); |
91 | 162k | xconsume(szReader, strlen(szReader) + 1); |
92 | 162k | assert(dwShareMode == SCARD_SHARE_SHARED); |
93 | 162k | assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY); |
94 | 162k | assert(phCard != NULL); |
95 | 162k | assert(pdwActiveProtocol != NULL); |
96 | | |
97 | 162k | if ((r = uniform_random(400)) < 1) |
98 | 635 | return SCARD_E_UNEXPECTED; |
99 | | |
100 | 162k | *phCard = 1; |
101 | 162k | *pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1; |
102 | | |
103 | 162k | if (uniform_random(400) < 1) |
104 | 879 | *pdwActiveProtocol = SCARD_PROTOCOL_RAW; |
105 | | |
106 | 162k | return SCARD_S_SUCCESS; |
107 | 162k | } |
108 | | |
109 | | LONG |
110 | | __wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) |
111 | 162k | { |
112 | 162k | assert(hCard == 1); |
113 | 162k | assert(dwDisposition == SCARD_LEAVE_CARD); |
114 | | |
115 | 162k | return SCARD_S_SUCCESS; |
116 | 162k | } |
117 | | |
118 | | extern void consume(const void *body, size_t len); |
119 | | |
120 | | LONG |
121 | | __wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, |
122 | | LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci, |
123 | | LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) |
124 | 89.6k | { |
125 | 89.6k | void *ioh = (void *)NFC_DEV_HANDLE; |
126 | 89.6k | int n; |
127 | | |
128 | 89.6k | assert(hCard == 1); |
129 | 89.6k | xconsume(pioSendPci, sizeof(*pioSendPci)); |
130 | 89.6k | xwrite(ioh, pbSendBuffer, cbSendLength); |
131 | 89.6k | assert(pioRecvPci == NULL); |
132 | | |
133 | 89.6k | if (uniform_random(400) < 1 || |
134 | 89.6k | (n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1) |
135 | 1.59k | return SCARD_E_UNEXPECTED; |
136 | 88.0k | *pcbRecvLength = (DWORD)n; |
137 | | |
138 | 88.0k | return SCARD_S_SUCCESS; |
139 | 89.6k | } |
140 | | |
141 | | void |
142 | | set_pcsc_parameters(const struct blob *reader_list_ptr) |
143 | 26.4k | { |
144 | 26.4k | reader_list = reader_list_ptr; |
145 | 26.4k | } |
146 | | |
147 | | void |
148 | | set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int), |
149 | | int (*write_f)(void *, const u_char *, size_t), |
150 | | void (*consume_f)(const void *, size_t)) |
151 | 26.4k | { |
152 | 26.4k | xread = read_f; |
153 | 26.4k | xwrite = write_f; |
154 | 26.4k | xconsume = consume_f; |
155 | 26.4k | } |