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