OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // |
| 5 // VMOptions= |
| 6 // VMOptions=--short_socket_read |
| 7 // VMOptions=--short_socket_write |
| 8 // VMOptions=--short_socket_read --short_socket_write |
| 9 |
| 10 import "package:expect/expect.dart"; |
| 11 import "dart:async"; |
| 12 import "dart:io"; |
| 13 import "dart:isolate"; |
| 14 |
| 15 const SERVER_ADDRESS = "127.0.0.1"; |
| 16 const HOST_NAME = "localhost"; |
| 17 const CERTIFICATE = "localhost_cert"; |
| 18 |
| 19 // This test creates a server and a client connects. After connecting |
| 20 // and an optional initial handshake the connection is secured by |
| 21 // upgrading to a secure connection The client then writes and the |
| 22 // server echos. When the server has finished its echo it |
| 23 // half-closes. When the client gets the close event is closes fully. |
| 24 // |
| 25 // The test can be run in different configurations based on |
| 26 // the boolean arguments: |
| 27 // |
| 28 // handshakeBeforeSecure |
| 29 // When this argument is true some initial clear text handshake is done |
| 30 // between client and server before the connection is secured. This argument |
| 31 // only makes sense when both listenSecure and connectSecure are false. |
| 32 // |
| 33 // postponeSecure |
| 34 // When this argument is false the securing of the server end will |
| 35 // happen as soon as the last byte of the handshake before securing |
| 36 // has been written. When this argument is true the securing of the |
| 37 // server will not happen until the first TLS handshake data has been |
| 38 // received from the client. This argument only takes effect when |
| 39 // handshakeBeforeSecure is true. |
| 40 void test(bool handshakeBeforeSecure, |
| 41 [bool postponeSecure = false]) { |
| 42 ReceivePort port = new ReceivePort(); |
| 43 |
| 44 const messageSize = 1000; |
| 45 const handshakeMessageSize = 100; |
| 46 |
| 47 List<int> createTestData() { |
| 48 List<int> data = new List<int>(messageSize); |
| 49 for (int i = 0; i < messageSize; i++) { |
| 50 data[i] = i & 0xff; |
| 51 } |
| 52 return data; |
| 53 } |
| 54 |
| 55 List<int> createHandshakeTestData() { |
| 56 List<int> data = new List<int>(handshakeMessageSize); |
| 57 for (int i = 0; i < handshakeMessageSize; i++) { |
| 58 data[i] = i & 0xff; |
| 59 } |
| 60 return data; |
| 61 } |
| 62 |
| 63 void verifyTestData(List<int> data) { |
| 64 Expect.equals(messageSize, data.length); |
| 65 List<int> expected = createTestData(); |
| 66 for (int i = 0; i < messageSize; i++) { |
| 67 Expect.equals(expected[i], data[i]); |
| 68 } |
| 69 } |
| 70 |
| 71 void verifyHandshakeTestData(List<int> data) { |
| 72 Expect.equals(handshakeMessageSize, data.length); |
| 73 List<int> expected = createHandshakeTestData(); |
| 74 for (int i = 0; i < handshakeMessageSize; i++) { |
| 75 Expect.equals(expected[i], data[i]); |
| 76 } |
| 77 } |
| 78 |
| 79 Future runServer(Socket client) { |
| 80 var completer = new Completer(); |
| 81 var dataReceived = []; |
| 82 client.listen( |
| 83 (data) { |
| 84 dataReceived.addAll(data); |
| 85 if (dataReceived.length == messageSize) { |
| 86 verifyTestData(dataReceived); |
| 87 client.add(dataReceived); |
| 88 client.close(); |
| 89 } |
| 90 }, |
| 91 onDone: () => completer.complete(null)); |
| 92 return completer.future; |
| 93 } |
| 94 |
| 95 Future<RawSocket> runClient(Socket socket) { |
| 96 var completer = new Completer(); |
| 97 var dataReceived = []; |
| 98 socket.listen( |
| 99 (data) { |
| 100 dataReceived.addAll(data); |
| 101 }, |
| 102 onDone: () { |
| 103 Expect.equals(messageSize, dataReceived.length); |
| 104 verifyTestData(dataReceived); |
| 105 socket.close(); |
| 106 completer.complete(null); |
| 107 }); |
| 108 socket.add(createTestData()); |
| 109 return completer.future; |
| 110 } |
| 111 |
| 112 Future runServerHandshake(Socket client) { |
| 113 var completer = new Completer(); |
| 114 var dataReceived = []; |
| 115 var subscription; |
| 116 subscription = client.listen( |
| 117 (data) { |
| 118 if (dataReceived.length == handshakeMessageSize) { |
| 119 Expect.isTrue(postponeSecure); |
| 120 subscription.pause(); |
| 121 completer.complete(data); |
| 122 } |
| 123 dataReceived.addAll(data); |
| 124 if (dataReceived.length == handshakeMessageSize) { |
| 125 verifyHandshakeTestData(dataReceived); |
| 126 client.add(dataReceived); |
| 127 if (!postponeSecure) { |
| 128 completer.complete(null); |
| 129 } |
| 130 } |
| 131 }, |
| 132 onDone: () => completer.complete(null)); |
| 133 return completer.future; |
| 134 } |
| 135 |
| 136 Future<Socket> runClientHandshake(Socket socket) { |
| 137 var completer = new Completer(); |
| 138 var dataReceived = []; |
| 139 socket.listen( |
| 140 (data) { |
| 141 dataReceived.addAll(data); |
| 142 if (dataReceived.length == handshakeMessageSize) { |
| 143 verifyHandshakeTestData(dataReceived); |
| 144 completer.complete(null); |
| 145 } |
| 146 }, |
| 147 onDone: () => Expect.fail("Should not be called") |
| 148 ); |
| 149 socket.add(createHandshakeTestData()); |
| 150 return completer.future; |
| 151 } |
| 152 |
| 153 Future<SecureSocket> connectClient(int port) { |
| 154 if (!handshakeBeforeSecure) { |
| 155 return Socket.connect(HOST_NAME, port).then((socket) { |
| 156 return SecureSocket.secure(socket).then((secureSocket) { |
| 157 Expect.throws(() => socket.add([0])); |
| 158 return secureSocket; |
| 159 }); |
| 160 }); |
| 161 } else { |
| 162 return Socket.connect(HOST_NAME, port).then((socket) { |
| 163 return runClientHandshake(socket).then((_) { |
| 164 return SecureSocket.secure(socket).then((secureSocket) { |
| 165 Expect.throws(() => socket.add([0])); |
| 166 return secureSocket; |
| 167 }); |
| 168 }); |
| 169 }); |
| 170 } |
| 171 } |
| 172 |
| 173 serverReady(server) { |
| 174 server.listen((client) { |
| 175 if (!handshakeBeforeSecure) { |
| 176 SecureSocket.secureServer(client, CERTIFICATE).then((secureClient) { |
| 177 Expect.throws(() => client.add([0])); |
| 178 runServer(secureClient).then((_) => server.close()); |
| 179 }); |
| 180 } else { |
| 181 runServerHandshake(client).then((carryOverData) { |
| 182 SecureSocket.secureServer( |
| 183 client, |
| 184 CERTIFICATE, |
| 185 carryOverData: carryOverData).then((secureClient) { |
| 186 Expect.throws(() => client.add([0])); |
| 187 runServer(secureClient).then((_) => server.close()); |
| 188 }); |
| 189 }); |
| 190 } |
| 191 }); |
| 192 |
| 193 connectClient(server.port).then(runClient).then((socket) { |
| 194 port.close(); |
| 195 }); |
| 196 } |
| 197 |
| 198 ServerSocket.bind(SERVER_ADDRESS, 0, 5).then(serverReady); |
| 199 } |
| 200 |
| 201 main() { |
| 202 Path scriptDir = new Path(new Options().script).directoryPath; |
| 203 Path certificateDatabase = scriptDir.append('pkcert'); |
| 204 SecureSocket.initialize(database: certificateDatabase.toNativePath(), |
| 205 password: 'dartdart', |
| 206 useBuiltinRoots: false); |
| 207 test(false); |
| 208 test(true); |
| 209 test(true, true); |
| 210 } |
OLD | NEW |