Line | Count | Source (jump to first uncovered line) |
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 | | */ |
6 | | |
7 | | #include <assert.h> |
8 | | #include <stdint.h> |
9 | | #include <stdlib.h> |
10 | | #include <string.h> |
11 | | #include <stdio.h> |
12 | | #include <winscard.h> |
13 | | |
14 | | #include "mutator_aux.h" |
15 | | |
16 | | static const struct blob *reader_list; |
17 | | static int (*xread)(void *, u_char *, size_t, int); |
18 | | static int (*xwrite)(void *, const u_char *, size_t); |
19 | | static void (*xconsume)(const void *, size_t); |
20 | | |
21 | | LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT); |
22 | | LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD); |
23 | | LONG __wrap_SCardReleaseContext(SCARDCONTEXT); |
24 | | LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE, |
25 | | LPDWORD); |
26 | | LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD); |
27 | | LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE, |
28 | | DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD); |
29 | | |
30 | | LONG |
31 | | __wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, |
32 | | LPCVOID pvReserved2, LPSCARDCONTEXT phContext) |
33 | 6.59k | { |
34 | 6.59k | assert(dwScope == SCARD_SCOPE_SYSTEM); |
35 | 0 | assert(pvReserved1 == NULL); |
36 | 0 | assert(pvReserved2 == NULL); |
37 | | |
38 | 0 | *phContext = 1; |
39 | | |
40 | 6.59k | if (uniform_random(400) < 1) |
41 | 43 | return SCARD_E_NO_SERVICE; |
42 | 6.54k | if (uniform_random(400) < 1) |
43 | 31 | return SCARD_E_NO_SMARTCARD; |
44 | 6.51k | if (uniform_random(400) < 1) |
45 | 45 | return SCARD_E_NO_MEMORY; |
46 | 6.47k | if (uniform_random(400) < 1) |
47 | 44 | *phContext = 0; |
48 | | |
49 | 6.47k | return SCARD_S_SUCCESS; |
50 | 6.51k | } |
51 | | |
52 | | LONG |
53 | | __wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, |
54 | | LPSTR mszReaders, LPDWORD pcchReaders) |
55 | 3.73k | { |
56 | 3.73k | assert(hContext == 1); |
57 | 0 | assert(mszGroups == NULL); |
58 | 0 | assert(mszReaders != NULL); |
59 | 0 | assert(pcchReaders != 0); |
60 | | |
61 | 3.73k | if (reader_list == NULL || uniform_random(400) < 1) |
62 | 1.04k | return SCARD_E_NO_READERS_AVAILABLE; |
63 | 2.69k | if (uniform_random(400) < 1) |
64 | 21 | return SCARD_E_NO_MEMORY; |
65 | | |
66 | 2.67k | memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ? |
67 | 2.63k | *pcchReaders : reader_list->len); |
68 | 2.67k | *pcchReaders = (DWORD)reader_list->len; /* on purpose */ |
69 | | |
70 | 2.67k | return SCARD_S_SUCCESS; |
71 | 2.69k | } |
72 | | |
73 | | LONG |
74 | | __wrap_SCardReleaseContext(SCARDCONTEXT hContext) |
75 | 6.54k | { |
76 | 6.54k | assert(hContext == 1); |
77 | | |
78 | 6.54k | return SCARD_S_SUCCESS; |
79 | 6.54k | } |
80 | | |
81 | | LONG |
82 | | __wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, |
83 | | DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) |
84 | 2.96k | { |
85 | 2.96k | uint32_t r; |
86 | | |
87 | 2.96k | assert(hContext == 1); |
88 | 0 | xconsume(szReader, strlen(szReader) + 1); |
89 | 2.96k | assert(dwShareMode == SCARD_SHARE_SHARED); |
90 | 0 | assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY); |
91 | 0 | assert(phCard != NULL); |
92 | 0 | assert(pdwActiveProtocol != NULL); |
93 | | |
94 | 2.96k | if ((r = uniform_random(400)) < 1) |
95 | 25 | return SCARD_E_UNEXPECTED; |
96 | | |
97 | 2.94k | *phCard = 1; |
98 | 2.94k | *pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1; |
99 | | |
100 | 2.94k | if (uniform_random(400) < 1) |
101 | 29 | *pdwActiveProtocol = SCARD_PROTOCOL_RAW; |
102 | | |
103 | 2.94k | return SCARD_S_SUCCESS; |
104 | 2.96k | } |
105 | | |
106 | | LONG |
107 | | __wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) |
108 | 2.94k | { |
109 | 2.94k | assert(hCard == 1); |
110 | 0 | assert(dwDisposition == SCARD_LEAVE_CARD); |
111 | | |
112 | 2.94k | return SCARD_S_SUCCESS; |
113 | 2.94k | } |
114 | | |
115 | | extern void consume(const void *body, size_t len); |
116 | | |
117 | | LONG |
118 | | __wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, |
119 | | LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci, |
120 | | LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) |
121 | 1.65k | { |
122 | 1.65k | void *ioh = (void *)NFC_DEV_HANDLE; |
123 | 1.65k | int n; |
124 | | |
125 | 1.65k | assert(hCard == 1); |
126 | 0 | xconsume(pioSendPci, sizeof(*pioSendPci)); |
127 | 1.65k | xwrite(ioh, pbSendBuffer, cbSendLength); |
128 | 1.65k | assert(pioRecvPci == NULL); |
129 | | |
130 | 1.65k | if (uniform_random(400) < 1 || |
131 | 1.65k | (n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1) |
132 | 24 | return SCARD_E_UNEXPECTED; |
133 | 1.62k | *pcbRecvLength = (DWORD)n; |
134 | | |
135 | 1.62k | return SCARD_S_SUCCESS; |
136 | 1.65k | } |
137 | | |
138 | | void |
139 | | set_pcsc_parameters(const struct blob *reader_list_ptr) |
140 | 751 | { |
141 | 751 | reader_list = reader_list_ptr; |
142 | 751 | } |
143 | | |
144 | | void |
145 | | set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int), |
146 | | int (*write_f)(void *, const u_char *, size_t), |
147 | | void (*consume_f)(const void *, size_t)) |
148 | 751 | { |
149 | 751 | xread = read_f; |
150 | 751 | xwrite = write_f; |
151 | 751 | xconsume = consume_f; |
152 | 751 | } |