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

Side by Side Diff: tests/standalone/io/raw_secure_server_socket_test.dart

Issue 13502004: Add the ability to secure an already established raw socket connection (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « sdk/lib/io/socket.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 // 4 //
5 // VMOptions= 5 // VMOptions=
6 // VMOptions=--short_socket_read 6 // VMOptions=--short_socket_read
7 // VMOptions=--short_socket_write 7 // VMOptions=--short_socket_write
8 // VMOptions=--short_socket_read --short_socket_write 8 // VMOptions=--short_socket_read --short_socket_write
9 9
10 import "dart:async"; 10 import "dart:async";
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 clientEnd.shutdown(SocketDirection.SEND); 126 clientEnd.shutdown(SocketDirection.SEND);
127 serverEnd.shutdown(SocketDirection.SEND); 127 serverEnd.shutdown(SocketDirection.SEND);
128 server.close(); 128 server.close();
129 port.close(); 129 port.close();
130 }); 130 });
131 }); 131 });
132 }); 132 });
133 }); 133 });
134 } 134 }
135 135
136 void testSimpleReadWrite() { 136 // This test creates a server and a client connects. The client then
137 // This test creates a server and a client connects. The client then 137 // writes and the server echos. When the server has finished its echo
138 // writes and the server echos. When the server has finished its 138 // it half-closes. When the client gets the close event is closes
139 // echo it half-closes. When the client gets the close event is 139 // fully.
140 // closes fully. 140 //
141 // The test can be run in different configurations based on
142 // the boolean arguments:
143 //
144 // listenSecure
145 // When this argument is true a secure server is used. When this is false
146 // a non-secure server is used and the connections are secured after beeing
147 // connected.
148 //
149 // connectSecure
150 // When this argument is true a secure client connection is used. When this
151 // is false a non-secure client connection is used and the connection is
152 // secured after being connected.
153 //
154 // handshakeBeforeSecure
155 // When this argument is true some initial clear text handshake is done
156 // between client and server before the connection is secured. This argument
157 // only makes sense when both listenSecure and connectSecure are false.
158 //
159 // postponeSecure
160 // When this argument is false the securing of the server end will
161 // happen as soon as the last byte of the handshake before securing
162 // has been written. When this argument is true the securing of the
163 // server will not happen until the first TLS handshake data has been
164 // received from the client. This argument only takes effect when
165 // handshakeBeforeSecure is true.
166 void testSimpleReadWrite(bool listenSecure,
167 bool connectSecure,
168 bool handshakeBeforeSecure,
169 [bool postponeSecure = false]) {
170 if (handshakeBeforeSecure == true &&
171 (listenSecure == true || connectSecure == true)) {
172 Expect.fails("Invalid arguments to testSimpleReadWrite");
173 }
174
141 ReceivePort port = new ReceivePort(); 175 ReceivePort port = new ReceivePort();
142 176
143 const messageSize = 1000; 177 const messageSize = 1000;
178 const handshakeMessageSize = 100;
144 179
145 List<int> createTestData() { 180 List<int> createTestData() {
146 List<int> data = new List<int>(messageSize); 181 List<int> data = new List<int>(messageSize);
147 for (int i = 0; i < messageSize; i++) { 182 for (int i = 0; i < messageSize; i++) {
148 data[i] = i & 0xff; 183 data[i] = i & 0xff;
149 } 184 }
150 return data; 185 return data;
151 } 186 }
152 187
188 List<int> createHandshakeTestData() {
189 List<int> data = new List<int>(handshakeMessageSize);
190 for (int i = 0; i < handshakeMessageSize; i++) {
191 data[i] = i & 0xff;
192 }
193 return data;
194 }
195
153 void verifyTestData(List<int> data) { 196 void verifyTestData(List<int> data) {
154 Expect.equals(messageSize, data.length); 197 Expect.equals(messageSize, data.length);
155 List<int> expected = createTestData(); 198 List<int> expected = createTestData();
156 for (int i = 0; i < messageSize; i++) { 199 for (int i = 0; i < messageSize; i++) {
157 Expect.equals(expected[i], data[i]); 200 Expect.equals(expected[i], data[i]);
158 } 201 }
159 } 202 }
160 203
161 RawSecureServerSocket.bind(SERVER_ADDRESS, 0, 5, CERTIFICATE).then((server) { 204 void verifyHandshakeTestData(List<int> data) {
205 Expect.equals(handshakeMessageSize, data.length);
206 List<int> expected = createHandshakeTestData();
207 for (int i = 0; i < handshakeMessageSize; i++) {
208 Expect.equals(expected[i], data[i]);
209 }
210 }
211
212 Future runServer(RawSocket client) {
213 var completer = new Completer();
214 int bytesRead = 0;
215 int bytesWritten = 0;
216 List<int> data = new List<int>(messageSize);
217 client.writeEventsEnabled = false;
218 var subscription;
219 subscription = client.listen((event) {
220 switch (event) {
221 case RawSocketEvent.READ:
222 Expect.isTrue(bytesWritten == 0);
223 Expect.isTrue(client.available() > 0);
224 var buffer = client.read();
225 if (buffer != null) {
226 data.setRange(bytesRead, buffer.length, buffer);
227 bytesRead += buffer.length;
228 for (var value in buffer) {
229 Expect.isTrue(value is int);
230 Expect.isTrue(value < 256 && value >= 0);
231 }
232 }
233 if (bytesRead == data.length) {
234 verifyTestData(data);
235 client.writeEventsEnabled = true;
236 }
237 break;
238 case RawSocketEvent.WRITE:
239 Expect.isFalse(client.writeEventsEnabled);
240 Expect.equals(bytesRead, data.length);
241 for (int i = bytesWritten; i < data.length; ++i) {
242 Expect.isTrue(data[i] is int);
243 Expect.isTrue(data[i] < 256 && data[i] >= 0);
244 }
245 bytesWritten += client.write(
246 data, bytesWritten, data.length - bytesWritten);
247 if (bytesWritten < data.length) {
248 client.writeEventsEnabled = true;
249 }
250 if (bytesWritten == data.length) {
251 client.shutdown(SocketDirection.SEND);
252 }
253 break;
254 case RawSocketEvent.READ_CLOSED:
255 completer.complete(null);
256 break;
257 default: throw "Unexpected event $event";
258 }
259 });
260 return completer.future;
261 }
262
263 Future<RawSocket> runClient(RawSocket socket) {
264 var completer = new Completer();
265 int bytesRead = 0;
266 int bytesWritten = 0;
267 List<int> dataSent = createTestData();
268 List<int> dataReceived = new List<int>(dataSent.length);
269 socket.listen((event) {
270 switch (event) {
271 case RawSocketEvent.READ:
272 Expect.isTrue(socket.available() > 0);
273 var buffer = socket.read();
274 if (buffer != null) {
275 dataReceived.setRange(bytesRead, buffer.length, buffer);
276 bytesRead += buffer.length;
277 }
278 break;
279 case RawSocketEvent.WRITE:
280 Expect.isTrue(bytesRead == 0);
281 Expect.isFalse(socket.writeEventsEnabled);
282 bytesWritten += socket.write(
283 dataSent, bytesWritten, dataSent.length - bytesWritten);
284 if (bytesWritten < dataSent.length) {
285 socket.writeEventsEnabled = true;
286 }
287 break;
288 case RawSocketEvent.READ_CLOSED:
289 verifyTestData(dataReceived);
290 completer.complete(socket);
291 break;
292 default: throw "Unexpected event $event";
293 }
294 });
295 return completer.future;
296 }
297
298 Future runServerHandshake(RawSocket client) {
299 var completer = new Completer();
300 int bytesRead = 0;
301 int bytesWritten = 0;
302 List<int> data = new List<int>(handshakeMessageSize);
303 client.writeEventsEnabled = false;
304 var subscription;
305 subscription = client.listen((event) {
306 switch (event) {
307 case RawSocketEvent.READ:
308 if (bytesRead < data.length) {
309 Expect.isTrue(bytesWritten == 0);
310 }
311 Expect.isTrue(client.available() > 0);
312 var buffer = client.read();
313 if (buffer != null) {
314 if (bytesRead == data.length) {
315 // Read first part of TLS handshake from client.
316 Expect.isTrue(postponeSecure);
317 completer.complete([subscription, buffer]);
318 return;
319 }
320 data.setRange(bytesRead, buffer.length, buffer);
321 bytesRead += buffer.length;
322 for (var value in buffer) {
323 Expect.isTrue(value is int);
324 Expect.isTrue(value < 256 && value >= 0);
325 }
326 }
327 if (bytesRead == data.length) {
328 verifyHandshakeTestData(data);
329 client.writeEventsEnabled = true;
330 }
331 if (bytesRead > data.length) print("XXX");
332 break;
333 case RawSocketEvent.WRITE:
334 Expect.isFalse(client.writeEventsEnabled);
335 Expect.equals(bytesRead, data.length);
336 for (int i = bytesWritten; i < data.length; ++i) {
337 Expect.isTrue(data[i] is int);
338 Expect.isTrue(data[i] < 256 && data[i] >= 0);
339 }
340 bytesWritten += client.write(
341 data, bytesWritten, data.length - bytesWritten);
342 if (bytesWritten < data.length) {
343 client.writeEventsEnabled = true;
344 }
345 if (bytesWritten == data.length) {
346 if (!postponeSecure) {
347 completer.complete([subscription, null]);
348 }
349 }
350 break;
351 case RawSocketEvent.READ_CLOSED:
352 Expect.fail("Unexpected close");
353 break;
354 default: throw "Unexpected event $event";
355 }
356 });
357 return completer.future;
358 }
359
360 Future<RawSocket> runClientHandshake(RawSocket socket) {
361 var completer = new Completer();
362 int bytesRead = 0;
363 int bytesWritten = 0;
364 List<int> dataSent = createHandshakeTestData();
365 List<int> dataReceived = new List<int>(dataSent.length);
366 var subscription;
367 subscription = socket.listen((event) {
368 switch (event) {
369 case RawSocketEvent.READ:
370 Expect.isTrue(socket.available() > 0);
371 var buffer = socket.read();
372 if (buffer != null) {
373 dataReceived.setRange(bytesRead, buffer.length, buffer);
374 bytesRead += buffer.length;
375 if (bytesRead == dataSent.length) {
376 verifyHandshakeTestData(dataReceived);
377 completer.complete(subscription);
378 }
379 }
380 break;
381 case RawSocketEvent.WRITE:
382 Expect.isTrue(bytesRead == 0);
383 Expect.isFalse(socket.writeEventsEnabled);
384 bytesWritten += socket.write(
385 dataSent, bytesWritten, dataSent.length - bytesWritten);
386 if (bytesWritten < dataSent.length) {
387 socket.writeEventsEnabled = true;
388 }
389 break;
390 case RawSocketEvent.READ_CLOSED:
391 Expect.fail("Unexpected close");
392 break;
393 default: throw "Unexpected event $event";
394 }
395 });
396 return completer.future;
397 }
398
399 Future<RawSecureSocket> connectClient(int port) {
400 if (connectSecure) {
401 return RawSecureSocket.connect(HOST_NAME, port);
402 } else if (!handshakeBeforeSecure) {
403 return RawSocket.connect(HOST_NAME, port).then((socket) {
404 return RawSecureSocket.secure(socket);
405 });
406 } else {
407 return RawSocket.connect(HOST_NAME, port).then((socket) {
408 return runClientHandshake(socket).then((subscription) {
409 return RawSecureSocket.secure(socket, subscription: subscription);
410 });
411 });
412 }
413 }
414
415 serverReady(server) {
162 server.listen((client) { 416 server.listen((client) {
163 int bytesRead = 0; 417 if (listenSecure) {
164 int bytesWritten = 0; 418 runServer(client).then((_) => server.close());
165 List<int> data = new List<int>(messageSize); 419 } else if (!handshakeBeforeSecure) {
166 420 RawSecureSocket.secureServer(client, CERTIFICATE).then((client) {
167 client.writeEventsEnabled = false; 421 runServer(client).then((_) => server.close());
168 client.listen((event) { 422 });
169 switch (event) { 423 } else {
170 case RawSocketEvent.READ: 424 runServerHandshake(client).then((secure) {
171 Expect.isTrue(bytesWritten == 0); 425 RawSecureSocket.secureServer(
172 Expect.isTrue(client.available() > 0); 426 client,
173 var buffer = client.read(); 427 CERTIFICATE,
174 if (buffer != null) { 428 subscription: secure[0],
175 data.setRange(bytesRead, buffer.length, buffer); 429 carryOverData: secure[1]).then((client) {
176 bytesRead += buffer.length; 430 runServer(client).then((_) => server.close());
177 for (var value in buffer) { 431 });
178 Expect.isTrue(value is int); 432 });
179 Expect.isTrue(value < 256 && value >= 0); 433 }
180 } 434 });
181 } 435
182 if (bytesRead == data.length) { 436 connectClient(server.port).then(runClient).then((socket) {
183 verifyTestData(data); 437 socket.close();
184 client.writeEventsEnabled = true; 438 port.close();
185 } 439 });
186 break; 440 }
187 case RawSocketEvent.WRITE: 441
188 Expect.isFalse(client.writeEventsEnabled); 442 if (listenSecure) {
189 Expect.equals(bytesRead, data.length); 443 RawSecureServerSocket.bind(
190 for (int i = bytesWritten; i < data.length; ++i) { 444 SERVER_ADDRESS, 0, 5, CERTIFICATE).then(serverReady);
191 Expect.isTrue(data[i] is int); 445 } else {
192 Expect.isTrue(data[i] < 256 && data[i] >= 0); 446 RawServerSocket.bind(SERVER_ADDRESS, 0, 5).then(serverReady);
193 } 447 }
194 bytesWritten += client.write(
195 data, bytesWritten, data.length - bytesWritten);
196 if (bytesWritten < data.length) {
197 client.writeEventsEnabled = true;
198 }
199 if (bytesWritten == data.length) {
200 client.shutdown(SocketDirection.SEND);
201 }
202 break;
203 case RawSocketEvent.READ_CLOSED:
204 server.close();
205 break;
206 default: throw "Unexpected event $event";
207 }
208 });
209 });
210
211 RawSecureSocket.connect(HOST_NAME, server.port).then((socket) {
212 int bytesRead = 0;
213 int bytesWritten = 0;
214 List<int> dataSent = createTestData();
215 List<int> dataReceived = new List<int>(dataSent.length);
216 socket.listen((event) {
217 switch (event) {
218 case RawSocketEvent.READ:
219 Expect.isTrue(socket.available() > 0);
220 var buffer = socket.read();
221 if (buffer != null) {
222 dataReceived.setRange(bytesRead, buffer.length, buffer);
223 bytesRead += buffer.length;
224 }
225 break;
226 case RawSocketEvent.WRITE:
227 Expect.isTrue(bytesRead == 0);
228 Expect.isFalse(socket.writeEventsEnabled);
229 bytesWritten += socket.write(
230 dataSent, bytesWritten, dataSent.length - bytesWritten);
231 if (bytesWritten < dataSent.length) {
232 socket.writeEventsEnabled = true;
233 }
234 break;
235 case RawSocketEvent.READ_CLOSED:
236 verifyTestData(dataReceived);
237 socket.close();
238 port.close();
239 break;
240 default: throw "Unexpected event $event";
241 }
242 });
243 });
244 });
245 } 448 }
246 449
247 main() { 450 main() {
248 Path scriptDir = new Path(new Options().script).directoryPath; 451 Path scriptDir = new Path(new Options().script).directoryPath;
249 Path certificateDatabase = scriptDir.append('pkcert'); 452 Path certificateDatabase = scriptDir.append('pkcert');
250 SecureSocket.initialize(database: certificateDatabase.toNativePath(), 453 SecureSocket.initialize(database: certificateDatabase.toNativePath(),
251 password: 'dartdart', 454 password: 'dartdart',
252 useBuiltinRoots: false); 455 useBuiltinRoots: false);
253 testArguments(); 456 testArguments();
254 testSimpleBind(); 457 testSimpleBind();
255 testInvalidBind(); 458 testInvalidBind();
256 testSimpleConnect(CERTIFICATE); 459 testSimpleConnect(CERTIFICATE);
257 testSimpleConnect("CN=localhost"); 460 testSimpleConnect("CN=localhost");
258 testSimpleConnectFail("not_a_nickname"); 461 testSimpleConnectFail("not_a_nickname");
259 testSimpleConnectFail("CN=notARealDistinguishedName"); 462 testSimpleConnectFail("CN=notARealDistinguishedName");
260 testServerListenAfterConnect(); 463 testServerListenAfterConnect();
261 testSimpleReadWrite(); 464 testSimpleReadWrite(true, true, false);
465 testSimpleReadWrite(true, false, false);
466 testSimpleReadWrite(false, true, false);
467 testSimpleReadWrite(false, false, false);
468 testSimpleReadWrite(false, false, true, true);
469 testSimpleReadWrite(false, false, true, false);
262 } 470 }
OLDNEW
« no previous file with comments | « sdk/lib/io/socket.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698