Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(734)

Side by Side Diff: device/u2f/u2f_hid_device.cc

Issue 2743623006: Modify U2F apdu classes to use unique pointers (Closed)
Patch Set: Use more concise form of base::Passed Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/u2f/u2f_hid_device.h ('k') | device/u2f/u2f_hid_device_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "u2f_hid_device.h" 5 #include "u2f_hid_device.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "crypto/random.h" 10 #include "crypto/random.h"
(...skipping 15 matching lines...) Expand all
26 weak_factory_(this) { 26 weak_factory_(this) {
27 channel_id_ = kBroadcastChannel; 27 channel_id_ = kBroadcastChannel;
28 } 28 }
29 29
30 U2fHidDevice::~U2fHidDevice() { 30 U2fHidDevice::~U2fHidDevice() {
31 // Cleanup connection 31 // Cleanup connection
32 if (connection_) 32 if (connection_)
33 connection_->Close(); 33 connection_->Close();
34 } 34 }
35 35
36 void U2fHidDevice::DeviceTransact(scoped_refptr<U2fApduCommand> command, 36 void U2fHidDevice::DeviceTransact(std::unique_ptr<U2fApduCommand> command,
37 const DeviceCallback& callback) { 37 const DeviceCallback& callback) {
38 Transition(command, callback); 38 Transition(std::move(command), callback);
39 } 39 }
40 40
41 void U2fHidDevice::Transition(scoped_refptr<U2fApduCommand> command, 41 void U2fHidDevice::Transition(std::unique_ptr<U2fApduCommand> command,
42 const DeviceCallback& callback) { 42 const DeviceCallback& callback) {
43 switch (state_) { 43 switch (state_) {
44 case State::INIT: 44 case State::INIT:
45 state_ = State::BUSY; 45 state_ = State::BUSY;
46 Connect(base::Bind(&U2fHidDevice::OnConnect, weak_factory_.GetWeakPtr(), 46 Connect(base::Bind(&U2fHidDevice::OnConnect, weak_factory_.GetWeakPtr(),
47 command, callback)); 47 base::Passed(&command), callback));
48 break; 48 break;
49 case State::CONNECTED: 49 case State::CONNECTED:
50 state_ = State::BUSY; 50 state_ = State::BUSY;
51 AllocateChannel(command, callback); 51 AllocateChannel(std::move(command), callback);
52 break; 52 break;
53 case State::IDLE: { 53 case State::IDLE: {
54 state_ = State::BUSY; 54 state_ = State::BUSY;
55 scoped_refptr<U2fMessage> msg = U2fMessage::Create( 55 scoped_refptr<U2fMessage> msg = U2fMessage::Create(
56 channel_id_, U2fMessage::Type::CMD_MSG, command->GetEncodedCommand()); 56 channel_id_, U2fMessage::Type::CMD_MSG, command->GetEncodedCommand());
57 WriteMessage(msg, true, 57 WriteMessage(msg, true,
58 base::Bind(&U2fHidDevice::MessageReceived, 58 base::Bind(&U2fHidDevice::MessageReceived,
59 weak_factory_.GetWeakPtr(), callback)); 59 weak_factory_.GetWeakPtr(), callback));
60 break; 60 break;
61 } 61 }
(...skipping 14 matching lines...) Expand all
76 break; 76 break;
77 } 77 }
78 } 78 }
79 79
80 void U2fHidDevice::Connect(const HidService::ConnectCallback& callback) { 80 void U2fHidDevice::Connect(const HidService::ConnectCallback& callback) {
81 HidService* hid_service = DeviceClient::Get()->GetHidService(); 81 HidService* hid_service = DeviceClient::Get()->GetHidService();
82 82
83 hid_service->Connect(device_info_->device_id(), callback); 83 hid_service->Connect(device_info_->device_id(), callback);
84 } 84 }
85 85
86 void U2fHidDevice::OnConnect(scoped_refptr<U2fApduCommand> command, 86 void U2fHidDevice::OnConnect(std::unique_ptr<U2fApduCommand> command,
87 const DeviceCallback& callback, 87 const DeviceCallback& callback,
88 scoped_refptr<HidConnection> connection) { 88 scoped_refptr<HidConnection> connection) {
89 if (connection) { 89 if (connection) {
90 connection_ = connection; 90 connection_ = connection;
91 state_ = State::CONNECTED; 91 state_ = State::CONNECTED;
92 } else { 92 } else {
93 state_ = State::DEVICE_ERROR; 93 state_ = State::DEVICE_ERROR;
94 } 94 }
95 Transition(command, callback); 95 Transition(std::move(command), callback);
96 } 96 }
97 97
98 void U2fHidDevice::AllocateChannel(scoped_refptr<U2fApduCommand> command, 98 void U2fHidDevice::AllocateChannel(std::unique_ptr<U2fApduCommand> command,
99 const DeviceCallback& callback) { 99 const DeviceCallback& callback) {
100 // Send random nonce to device to verify received message 100 // Send random nonce to device to verify received message
101 std::vector<uint8_t> nonce(8); 101 std::vector<uint8_t> nonce(8);
102 crypto::RandBytes(nonce.data(), nonce.size()); 102 crypto::RandBytes(nonce.data(), nonce.size());
103 scoped_refptr<U2fMessage> message = 103 scoped_refptr<U2fMessage> message =
104 U2fMessage::Create(channel_id_, U2fMessage::Type::CMD_INIT, nonce); 104 U2fMessage::Create(channel_id_, U2fMessage::Type::CMD_INIT, nonce);
105 105
106 WriteMessage( 106 WriteMessage(
107 message, true, 107 message, true,
108 base::Bind(&U2fHidDevice::OnAllocateChannel, weak_factory_.GetWeakPtr(), 108 base::Bind(&U2fHidDevice::OnAllocateChannel, weak_factory_.GetWeakPtr(),
109 nonce, command, callback)); 109 nonce, base::Passed(&command), callback));
110 } 110 }
111 111
112 void U2fHidDevice::OnAllocateChannel(std::vector<uint8_t> nonce, 112 void U2fHidDevice::OnAllocateChannel(std::vector<uint8_t> nonce,
113 scoped_refptr<U2fApduCommand> command, 113 std::unique_ptr<U2fApduCommand> command,
114 const DeviceCallback& callback, 114 const DeviceCallback& callback,
115 bool success, 115 bool success,
116 scoped_refptr<U2fMessage> message) { 116 scoped_refptr<U2fMessage> message) {
117 if (!success || !message) { 117 if (!success || !message) {
118 state_ = State::DEVICE_ERROR; 118 state_ = State::DEVICE_ERROR;
119 Transition(nullptr, callback); 119 Transition(nullptr, callback);
120 return; 120 return;
121 } 121 }
122 // Channel allocation response is defined as: 122 // Channel allocation response is defined as:
123 // 0: 8 byte nonce 123 // 0: 8 byte nonce
(...skipping 19 matching lines...) Expand all
143 } 143 }
144 144
145 size_t index = 8; 145 size_t index = 8;
146 channel_id_ = payload[index++] << 24; 146 channel_id_ = payload[index++] << 24;
147 channel_id_ |= payload[index++] << 16; 147 channel_id_ |= payload[index++] << 16;
148 channel_id_ |= payload[index++] << 8; 148 channel_id_ |= payload[index++] << 8;
149 channel_id_ |= payload[index++]; 149 channel_id_ |= payload[index++];
150 capabilities_ = payload[16]; 150 capabilities_ = payload[16];
151 151
152 state_ = State::IDLE; 152 state_ = State::IDLE;
153 Transition(command, callback); 153 Transition(std::move(command), callback);
154 } 154 }
155 155
156 void U2fHidDevice::WriteMessage(scoped_refptr<U2fMessage> message, 156 void U2fHidDevice::WriteMessage(scoped_refptr<U2fMessage> message,
157 bool response_expected, 157 bool response_expected,
158 U2fHidMessageCallback callback) { 158 U2fHidMessageCallback callback) {
159 if (!connection_ || !message || message->NumPackets() == 0) { 159 if (!connection_ || !message || message->NumPackets() == 0) {
160 std::move(callback).Run(false, nullptr); 160 std::move(callback).Run(false, nullptr);
161 return; 161 return;
162 } 162 }
163 163
164 scoped_refptr<net::IOBufferWithSize> buffer = message->PopNextPacket(); 164 scoped_refptr<net::IOBufferWithSize> buffer = message->PopNextPacket();
165 165
166 connection_->Write( 166 connection_->Write(
167 buffer, buffer->size(), 167 buffer, buffer->size(),
168 base::Bind(&U2fHidDevice::PacketWritten, weak_factory_.GetWeakPtr(), 168 base::Bind(&U2fHidDevice::PacketWritten, weak_factory_.GetWeakPtr(),
169 message, true, base::Passed(std::move(callback)))); 169 message, true, base::Passed(&callback)));
170 } 170 }
171 171
172 void U2fHidDevice::PacketWritten(scoped_refptr<U2fMessage> message, 172 void U2fHidDevice::PacketWritten(scoped_refptr<U2fMessage> message,
173 bool response_expected, 173 bool response_expected,
174 U2fHidMessageCallback callback, 174 U2fHidMessageCallback callback,
175 bool success) { 175 bool success) {
176 if (success && message->NumPackets() > 0) { 176 if (success && message->NumPackets() > 0) {
177 WriteMessage(message, response_expected, std::move(callback)); 177 WriteMessage(message, response_expected, std::move(callback));
178 } else if (success && response_expected) { 178 } else if (success && response_expected) {
179 ReadMessage(std::move(callback)); 179 ReadMessage(std::move(callback));
180 } else { 180 } else {
181 std::move(callback).Run(success, nullptr); 181 std::move(callback).Run(success, nullptr);
182 } 182 }
183 } 183 }
184 184
185 void U2fHidDevice::ReadMessage(U2fHidMessageCallback callback) { 185 void U2fHidDevice::ReadMessage(U2fHidMessageCallback callback) {
186 if (!connection_) { 186 if (!connection_) {
187 std::move(callback).Run(false, nullptr); 187 std::move(callback).Run(false, nullptr);
188 return; 188 return;
189 } 189 }
190 190
191 connection_->Read(base::Bind(&U2fHidDevice::OnRead, 191 connection_->Read(base::Bind(&U2fHidDevice::OnRead,
192 weak_factory_.GetWeakPtr(), 192 weak_factory_.GetWeakPtr(),
193 base::Passed(std::move(callback)))); 193 base::Passed(&callback)));
194 } 194 }
195 195
196 void U2fHidDevice::OnRead(U2fHidMessageCallback callback, 196 void U2fHidDevice::OnRead(U2fHidMessageCallback callback,
197 bool success, 197 bool success,
198 scoped_refptr<net::IOBuffer> buf, 198 scoped_refptr<net::IOBuffer> buf,
199 size_t size) { 199 size_t size) {
200 if (!success) { 200 if (!success) {
201 std::move(callback).Run(success, nullptr); 201 std::move(callback).Run(success, nullptr);
202 return; 202 return;
203 } 203 }
204 204
205 scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(size)); 205 scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(size));
206 memcpy(buffer->data(), buf->data(), size); 206 memcpy(buffer->data(), buf->data(), size);
207 scoped_refptr<U2fMessage> read_message = 207 scoped_refptr<U2fMessage> read_message =
208 U2fMessage::CreateFromSerializedData(buffer); 208 U2fMessage::CreateFromSerializedData(buffer);
209 209
210 if (!read_message) { 210 if (!read_message) {
211 std::move(callback).Run(false, nullptr); 211 std::move(callback).Run(false, nullptr);
212 return; 212 return;
213 } 213 }
214 214
215 // Received a message from a different channel, so try again 215 // Received a message from a different channel, so try again
216 if (channel_id_ != read_message->channel_id()) { 216 if (channel_id_ != read_message->channel_id()) {
217 connection_->Read(base::Bind(&U2fHidDevice::OnRead, 217 connection_->Read(base::Bind(&U2fHidDevice::OnRead,
218 weak_factory_.GetWeakPtr(), 218 weak_factory_.GetWeakPtr(),
219 base::Passed(std::move(callback)))); 219 base::Passed(&callback)));
220 return; 220 return;
221 } 221 }
222 222
223 if (read_message->MessageComplete()) { 223 if (read_message->MessageComplete()) {
224 std::move(callback).Run(success, read_message); 224 std::move(callback).Run(success, read_message);
225 return; 225 return;
226 } 226 }
227 227
228 // Continue reading additional packets 228 // Continue reading additional packets
229 connection_->Read(base::Bind(&U2fHidDevice::OnReadContinuation, 229 connection_->Read(base::Bind(&U2fHidDevice::OnReadContinuation,
230 weak_factory_.GetWeakPtr(), read_message, 230 weak_factory_.GetWeakPtr(), read_message,
231 base::Passed(std::move(callback)))); 231 base::Passed(&callback)));
232 } 232 }
233 233
234 void U2fHidDevice::OnReadContinuation(scoped_refptr<U2fMessage> message, 234 void U2fHidDevice::OnReadContinuation(scoped_refptr<U2fMessage> message,
235 U2fHidMessageCallback callback, 235 U2fHidMessageCallback callback,
236 bool success, 236 bool success,
237 scoped_refptr<net::IOBuffer> buf, 237 scoped_refptr<net::IOBuffer> buf,
238 size_t size) { 238 size_t size) {
239 if (!success) { 239 if (!success) {
240 std::move(callback).Run(success, nullptr); 240 std::move(callback).Run(success, nullptr);
241 return; 241 return;
242 } 242 }
243 243
244 scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(size)); 244 scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(size));
245 memcpy(buffer->data(), buf->data(), size); 245 memcpy(buffer->data(), buf->data(), size);
246 message->AddContinuationPacket(buffer); 246 message->AddContinuationPacket(buffer);
247 if (message->MessageComplete()) { 247 if (message->MessageComplete()) {
248 std::move(callback).Run(success, message); 248 std::move(callback).Run(success, message);
249 return; 249 return;
250 } 250 }
251 connection_->Read(base::Bind(&U2fHidDevice::OnReadContinuation, 251 connection_->Read(base::Bind(&U2fHidDevice::OnReadContinuation,
252 weak_factory_.GetWeakPtr(), message, 252 weak_factory_.GetWeakPtr(), message,
253 base::Passed(std::move(callback)))); 253 base::Passed(&callback)));
254 } 254 }
255 255
256 void U2fHidDevice::MessageReceived(const DeviceCallback& callback, 256 void U2fHidDevice::MessageReceived(const DeviceCallback& callback,
257 bool success, 257 bool success,
258 scoped_refptr<U2fMessage> message) { 258 scoped_refptr<U2fMessage> message) {
259 if (!success) { 259 if (!success) {
260 state_ = State::DEVICE_ERROR; 260 state_ = State::DEVICE_ERROR;
261 Transition(nullptr, callback); 261 Transition(nullptr, callback);
262 return; 262 return;
263 } 263 }
264 scoped_refptr<U2fApduResponse> response = nullptr; 264 std::unique_ptr<U2fApduResponse> response = nullptr;
265 if (message) 265 if (message)
266 response = U2fApduResponse::CreateFromMessage(message->GetMessagePayload()); 266 response = U2fApduResponse::CreateFromMessage(message->GetMessagePayload());
267 state_ = State::IDLE; 267 state_ = State::IDLE;
268 base::WeakPtr<U2fHidDevice> self = weak_factory_.GetWeakPtr(); 268 base::WeakPtr<U2fHidDevice> self = weak_factory_.GetWeakPtr();
269 callback.Run(success, response); 269 callback.Run(success, std::move(response));
270 270
271 // Executing |callback| may have freed |this|. Check |self| first. 271 // Executing |callback| may have freed |this|. Check |self| first.
272 if (self && !pending_transactions_.empty()) { 272 if (self && !pending_transactions_.empty()) {
273 // If any transactions were queued, process the first one 273 // If any transactions were queued, process the first one
274 scoped_refptr<U2fApduCommand> pending_cmd = 274 std::unique_ptr<U2fApduCommand> pending_cmd =
275 std::move(pending_transactions_.front().first); 275 std::move(pending_transactions_.front().first);
276 DeviceCallback pending_cb = pending_transactions_.front().second; 276 DeviceCallback pending_cb = pending_transactions_.front().second;
277 pending_transactions_.pop_front(); 277 pending_transactions_.pop_front();
278 Transition(pending_cmd, pending_cb); 278 Transition(std::move(pending_cmd), pending_cb);
279 } 279 }
280 } 280 }
281 281
282 void U2fHidDevice::TryWink(const WinkCallback& callback) { 282 void U2fHidDevice::TryWink(const WinkCallback& callback) {
283 // Only try to wink if device claims support 283 // Only try to wink if device claims support
284 if (!(capabilities_ & kWinkCapability) || state_ != State::IDLE) { 284 if (!(capabilities_ & kWinkCapability) || state_ != State::IDLE) {
285 callback.Run(); 285 callback.Run();
286 return; 286 return;
287 } 287 }
288 288
(...skipping 16 matching lines...) Expand all
305 return id.str(); 305 return id.str();
306 } 306 }
307 307
308 // static 308 // static
309 bool U2fHidDevice::IsTestEnabled() { 309 bool U2fHidDevice::IsTestEnabled() {
310 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 310 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
311 return command_line->HasSwitch(switches::kEnableU2fHidTest); 311 return command_line->HasSwitch(switches::kEnableU2fHidTest);
312 } 312 }
313 313
314 } // namespace device 314 } // namespace device
OLDNEW
« no previous file with comments | « device/u2f/u2f_hid_device.h ('k') | device/u2f/u2f_hid_device_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698