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

Side by Side Diff: sdk/lib/io/secure_socket.dart

Issue 11419138: Rename TlsSocket to SecureSocket, and all other Tls... items to Secure.... (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rename C++ class from Filter to SSLFilter. Created 8 years, 1 month 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/secure_server_socket.dart ('k') | sdk/lib/io/tls_server_socket.dart » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * TlsSocket provides a secure (SSL or TLS) client connection to a server. 6 * SecureSocket provides a secure (SSL or TLS) client connection to a server.
7 * The certificate provided by the server is checked 7 * The certificate provided by the server is checked
8 * using the certificate database provided in setCertificateDatabase. 8 * using the certificate database provided in setCertificateDatabase.
9 */ 9 */
10 abstract class TlsSocket implements Socket { 10 abstract class SecureSocket implements Socket {
11 /** 11 /**
12 * Constructs a new secure client socket and connect it to the given 12 * Constructs a new secure client socket and connect it to the given
13 * host on the given port. The returned socket is not yet connected 13 * host on the given port. The returned socket is not yet connected
14 * but ready for registration of callbacks. 14 * but ready for registration of callbacks.
15 */ 15 */
16 factory TlsSocket(String host, int port) => new _TlsSocket(host, port); 16 factory SecureSocket(String host, int port) => new _SecureSocket(host, port);
17 17
18 /** 18 /**
19 * Initializes the TLS library with the path to a certificate database 19 * Initializes the NSS library with the path to a certificate database
20 * containing root certificates for verifying certificate paths on 20 * containing root certificates for verifying certificate paths on
21 * client connections, and server certificates to provide on server 21 * client connections, and server certificates to provide on server
22 * connections. The password argument should be used when creating 22 * connections. The password argument should be used when creating
23 * secure server sockets, to allow the private key of the server 23 * secure server sockets, to allow the private key of the server
24 * certificate to be fetched. 24 * certificate to be fetched.
25 * 25 *
26 * The database should be an NSS certificate database directory 26 * The database should be an NSS certificate database directory
27 * containing a cert9.db file, not a cert8.db file. This version of 27 * containing a cert9.db file, not a cert8.db file. This version of
28 * the database can be created using the NSS certutil tool with "sql:" in 28 * the database can be created using the NSS certutil tool with "sql:" in
29 * front of the absolute path of the database directory, or setting the 29 * front of the absolute path of the database directory, or setting the
30 * environment variable NSS_DEFAULT_DB_TYPE to "sql". 30 * environment variable NSS_DEFAULT_DB_TYPE to "sql".
31 */ 31 */
32 external static void setCertificateDatabase(String certificateDatabase, 32 external static void setCertificateDatabase(String certificateDatabase,
33 [String password]); 33 [String password]);
34 } 34 }
35 35
36 36
37 class _TlsSocket implements TlsSocket { 37 class _SecureSocket implements SecureSocket {
38 // Status states 38 // Status states
39 static final int NOT_CONNECTED = 200; 39 static final int NOT_CONNECTED = 200;
40 static final int HANDSHAKE = 201; 40 static final int HANDSHAKE = 201;
41 static final int CONNECTED = 202; 41 static final int CONNECTED = 202;
42 static final int CLOSED = 203; 42 static final int CLOSED = 203;
43 43
44 // Buffer identifiers. 44 // Buffer identifiers.
45 // These must agree with those in the native C++ implementation. 45 // These must agree with those in the native C++ implementation.
46 static final int READ_PLAINTEXT = 0; 46 static final int READ_PLAINTEXT = 0;
47 static final int WRITE_PLAINTEXT = 1; 47 static final int WRITE_PLAINTEXT = 1;
48 static final int READ_ENCRYPTED = 2; 48 static final int READ_ENCRYPTED = 2;
49 static final int WRITE_ENCRYPTED = 3; 49 static final int WRITE_ENCRYPTED = 3;
50 static final int NUM_BUFFERS = 4; 50 static final int NUM_BUFFERS = 4;
51 51
52 int _count = 0; 52 int _count = 0;
53 // Constructs a new secure client socket. 53 // Constructs a new secure client socket.
54 factory _TlsSocket(String host, int port) => 54 factory _SecureSocket(String host, int port) =>
55 new _TlsSocket.internal(host, port, false); 55 new _SecureSocket.internal(host, port, false);
56 56
57 // Constructs a new secure server socket, with the named server certificate. 57 // Constructs a new secure server socket, with the named server certificate.
58 factory _TlsSocket.server(String host, 58 factory _SecureSocket.server(String host,
59 int port, 59 int port,
60 Socket socket, 60 Socket socket,
61 String certificateName) => 61 String certificateName) =>
62 new _TlsSocket.internal(host, port, true, socket, certificateName); 62 new _SecureSocket.internal(host, port, true, socket, certificateName);
63 63
64 _TlsSocket.internal(String host, 64 _SecureSocket.internal(String host,
65 int port, 65 int port,
66 bool is_server, 66 bool is_server,
67 [Socket socket, 67 [Socket socket,
68 String certificateName]) 68 String certificateName])
69 : _host = host, 69 : _host = host,
70 _port = port, 70 _port = port,
71 _socket = socket, 71 _socket = socket,
72 _certificateName = certificateName, 72 _certificateName = certificateName,
73 _is_server = is_server, 73 _is_server = is_server,
74 _tlsFilter = new _TlsFilter() { 74 _secureFilter = new _SecureFilter() {
75 if (_socket == null) { 75 if (_socket == null) {
76 _socket = new Socket(host, port); 76 _socket = new Socket(host, port);
77 } 77 }
78 _socket.onConnect = _tlsConnectHandler; 78 _socket.onConnect = _secureConnectHandler;
79 _socket.onData = _tlsDataHandler; 79 _socket.onData = _secureDataHandler;
80 _socket.onClosed = _tlsCloseHandler; 80 _socket.onClosed = _secureCloseHandler;
81 _tlsFilter.init(); 81 _secureFilter.init();
82 _tlsFilter.registerHandshakeCompleteCallback(_tlsHandshakeCompleteHandler); 82 _secureFilter.registerHandshakeCompleteCallback(_secureHandshakeCompleteHand ler);
83 } 83 }
84 84
85 int get port => _socket.port; 85 int get port => _socket.port;
86 86
87 String get remoteHost => _socket.remoteHost; 87 String get remoteHost => _socket.remoteHost;
88 88
89 int get remotePort => _socket.remotePort; 89 int get remotePort => _socket.remotePort;
90 90
91 void set onClosed(void callback()) { 91 void set onClosed(void callback()) {
92 if (_inputStream != null) { 92 if (_inputStream != null) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 if (_outputStream != null) { 132 if (_outputStream != null) {
133 throw new StreamException( 133 throw new StreamException(
134 "Cannot set write handler when output stream is used"); 134 "Cannot set write handler when output stream is used");
135 } 135 }
136 _onWrite = callback; 136 _onWrite = callback;
137 } 137 }
138 138
139 void set _onWrite(void callback()) { 139 void set _onWrite(void callback()) {
140 _socketWriteHandler = callback; 140 _socketWriteHandler = callback;
141 // Reset the one-shot onWrite handler. 141 // Reset the one-shot onWrite handler.
142 _socket.onWrite = _tlsWriteHandler; 142 _socket.onWrite = _secureWriteHandler;
143 } 143 }
144 144
145 InputStream get inputStream { 145 InputStream get inputStream {
146 if (_inputStream == null) { 146 if (_inputStream == null) {
147 if (_socketDataHandler != null || _socketCloseHandler != null) { 147 if (_socketDataHandler != null || _socketCloseHandler != null) {
148 throw new StreamException( 148 throw new StreamException(
149 "Cannot get input stream when socket handlers are used"); 149 "Cannot get input stream when socket handlers are used");
150 } 150 }
151 _inputStream = new _SocketInputStream(this); 151 _inputStream = new _SocketInputStream(this);
152 } 152 }
153 return _inputStream; 153 return _inputStream;
154 } 154 }
155 155
156 OutputStream get outputStream { 156 OutputStream get outputStream {
157 if (_outputStream == null) { 157 if (_outputStream == null) {
158 if (_socketConnectHandler != null || _socketWriteHandler != null) { 158 if (_socketConnectHandler != null || _socketWriteHandler != null) {
159 throw new StreamException( 159 throw new StreamException(
160 "Cannot get output stream when socket handlers are used"); 160 "Cannot get output stream when socket handlers are used");
161 } 161 }
162 _outputStream = new _SocketOutputStream(this); 162 _outputStream = new _SocketOutputStream(this);
163 } 163 }
164 return _outputStream; 164 return _outputStream;
165 } 165 }
166 166
167 int available() { 167 int available() {
168 throw new UnimplementedError("TlsSocket.available not implemented yet"); 168 throw new UnimplementedError("SecureSocket.available not implemented yet");
169 } 169 }
170 170
171 void close([bool halfClose]) { 171 void close([bool halfClose]) {
172 if (halfClose) { 172 if (halfClose) {
173 _closedWrite = true; 173 _closedWrite = true;
174 _writeEncryptedData(); 174 _writeEncryptedData();
175 if (_filterWriteEmpty) { 175 if (_filterWriteEmpty) {
176 _socket.close(true); 176 _socket.close(true);
177 _socketClosedWrite = true; 177 _socketClosedWrite = true;
178 } 178 }
179 } else { 179 } else {
180 _closedWrite = true; 180 _closedWrite = true;
181 _closedRead = true; 181 _closedRead = true;
182 _socket.close(false); 182 _socket.close(false);
183 _socketClosedWrite = true; 183 _socketClosedWrite = true;
184 _socketClosedRead = true; 184 _socketClosedRead = true;
185 _tlsFilter.destroy(); 185 _secureFilter.destroy();
186 _tlsFilter = null; 186 _secureFilter = null;
187 if (scheduledDataEvent != null) { 187 if (scheduledDataEvent != null) {
188 scheduledDataEvent.cancel(); 188 scheduledDataEvent.cancel();
189 } 189 }
190 _status = CLOSED; 190 _status = CLOSED;
191 } 191 }
192 } 192 }
193 193
194 void _closeWrite() => close(true); 194 void _closeWrite() => close(true);
195 195
196 List<int> read([int len]) { 196 List<int> read([int len]) {
197 if (_closedRead) { 197 if (_closedRead) {
198 throw new SocketException("Reading from a closed socket"); 198 throw new SocketException("Reading from a closed socket");
199 } 199 }
200 if (_status != CONNECTED) { 200 if (_status != CONNECTED) {
201 return new List<int>(0); 201 return new List<int>(0);
202 } 202 }
203 var buffer = _tlsFilter.buffers[READ_PLAINTEXT]; 203 var buffer = _secureFilter.buffers[READ_PLAINTEXT];
204 _readEncryptedData(); 204 _readEncryptedData();
205 int toRead = buffer.length; 205 int toRead = buffer.length;
206 if (len != null) { 206 if (len != null) {
207 if (len is! int || len < 0) { 207 if (len is! int || len < 0) {
208 throw new ArgumentError( 208 throw new ArgumentError(
209 "Invalid len parameter in TlsSocket.read (len: $len)"); 209 "Invalid len parameter in SecureSocket.read (len: $len)");
210 } 210 }
211 if (len < toRead) { 211 if (len < toRead) {
212 toRead = len; 212 toRead = len;
213 } 213 }
214 } 214 }
215 List<int> result = buffer.data.getRange(buffer.start, toRead); 215 List<int> result = buffer.data.getRange(buffer.start, toRead);
216 buffer.advanceStart(toRead); 216 buffer.advanceStart(toRead);
217 _setHandlersAfterRead(); 217 _setHandlersAfterRead();
218 return result; 218 return result;
219 } 219 }
220 220
221 int readList(List<int> data, int offset, int bytes) { 221 int readList(List<int> data, int offset, int bytes) {
222 if (_closedRead) { 222 if (_closedRead) {
223 throw new SocketException("Reading from a closed socket"); 223 throw new SocketException("Reading from a closed socket");
224 } 224 }
225 if (offset < 0 || bytes < 0 || offset + bytes > data.length) { 225 if (offset < 0 || bytes < 0 || offset + bytes > data.length) {
226 throw new ArgumentError( 226 throw new ArgumentError(
227 "Invalid offset or bytes in TlsSocket.readList"); 227 "Invalid offset or bytes in SecureSocket.readList");
228 } 228 }
229 if (_status != CONNECTED && _status != CLOSED) { 229 if (_status != CONNECTED && _status != CLOSED) {
230 return 0; 230 return 0;
231 } 231 }
232 232
233 int bytesRead = 0; 233 int bytesRead = 0;
234 var buffer = _tlsFilter.buffers[READ_PLAINTEXT]; 234 var buffer = _secureFilter.buffers[READ_PLAINTEXT];
235 // TODO(whesse): Currently this fails if the if is turned into a while loop. 235 // TODO(whesse): Currently this fails if the if is turned into a while loop.
236 // Fix it so that it can loop and read more than one buffer's worth of data. 236 // Fix it so that it can loop and read more than one buffer's worth of data.
237 if (bytes > bytesRead) { 237 if (bytes > bytesRead) {
238 _readEncryptedData(); 238 _readEncryptedData();
239 if (buffer.length > 0) { 239 if (buffer.length > 0) {
240 int toRead = min(bytes - bytesRead, buffer.length); 240 int toRead = min(bytes - bytesRead, buffer.length);
241 data.setRange(offset, toRead, buffer.data, buffer.start); 241 data.setRange(offset, toRead, buffer.data, buffer.start);
242 buffer.advanceStart(toRead); 242 buffer.advanceStart(toRead);
243 bytesRead += toRead; 243 bytesRead += toRead;
244 offset += toRead; 244 offset += toRead;
245 } 245 }
246 } 246 }
247 247
248 _setHandlersAfterRead(); 248 _setHandlersAfterRead();
249 return bytesRead; 249 return bytesRead;
250 } 250 }
251 251
252 // Write the data to the socket, and flush it as much as possible 252 // Write the data to the socket, and flush it as much as possible
253 // until it would block. If the write would block, _writeEncryptedData sets 253 // until it would block. If the write would block, _writeEncryptedData sets
254 // up handlers to flush the pipeline when possible. 254 // up handlers to flush the pipeline when possible.
255 int writeList(List<int> data, int offset, int bytes) { 255 int writeList(List<int> data, int offset, int bytes) {
256 if (_closedWrite) { 256 if (_closedWrite) {
257 throw new SocketException("Writing to a closed socket"); 257 throw new SocketException("Writing to a closed socket");
258 } 258 }
259 if (_status != CONNECTED) return 0; 259 if (_status != CONNECTED) return 0;
260 var buffer = _tlsFilter.buffers[WRITE_PLAINTEXT]; 260 var buffer = _secureFilter.buffers[WRITE_PLAINTEXT];
261 if (bytes > buffer.free) { 261 if (bytes > buffer.free) {
262 bytes = buffer.free; 262 bytes = buffer.free;
263 } 263 }
264 if (bytes > 0) { 264 if (bytes > 0) {
265 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset); 265 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset);
266 buffer.length += bytes; 266 buffer.length += bytes;
267 } 267 }
268 _writeEncryptedData(); // Tries to flush all pipeline stages. 268 _writeEncryptedData(); // Tries to flush all pipeline stages.
269 return bytes; 269 return bytes;
270 } 270 }
271 271
272 void _tlsConnectHandler() { 272 void _secureConnectHandler() {
273 _connectPending = true; 273 _connectPending = true;
274 _tlsFilter.connect(_host, _port, _is_server, _certificateName); 274 _secureFilter.connect(_host, _port, _is_server, _certificateName);
275 _status = HANDSHAKE; 275 _status = HANDSHAKE;
276 _tlsHandshake(); 276 _secureHandshake();
277 } 277 }
278 278
279 void _tlsWriteHandler() { 279 void _secureWriteHandler() {
280 _writeEncryptedData(); 280 _writeEncryptedData();
281 if (_filterWriteEmpty && _closedWrite && !_socketClosedWrite) { 281 if (_filterWriteEmpty && _closedWrite && !_socketClosedWrite) {
282 _socket.close(true); 282 _socket.close(true);
283 _sockedClosedWrite = true; 283 _sockedClosedWrite = true;
284 } 284 }
285 if (_status == HANDSHAKE) { 285 if (_status == HANDSHAKE) {
286 _tlsHandshake(); 286 _secureHandshake();
287 } else if (_status == CONNECTED && 287 } else if (_status == CONNECTED &&
288 _socketWriteHandler != null && 288 _socketWriteHandler != null &&
289 _tlsFilter.buffers[WRITE_PLAINTEXT].free > 0) { 289 _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) {
290 // We must be able to set onWrite from the onWrite callback. 290 // We must be able to set onWrite from the onWrite callback.
291 var handler = _socketWriteHandler; 291 var handler = _socketWriteHandler;
292 // Reset the one-shot handler. 292 // Reset the one-shot handler.
293 _socketWriteHandler = null; 293 _socketWriteHandler = null;
294 handler(); 294 handler();
295 } 295 }
296 } 296 }
297 297
298 void _tlsDataHandler() { 298 void _secureDataHandler() {
299 if (_status == HANDSHAKE) { 299 if (_status == HANDSHAKE) {
300 _tlsHandshake(); 300 _secureHandshake();
301 } else { 301 } else {
302 _writeEncryptedData(); // TODO(whesse): Removing this causes a failure. 302 _writeEncryptedData(); // TODO(whesse): Removing this causes a failure.
303 _readEncryptedData(); 303 _readEncryptedData();
304 if (!_filterReadEmpty) { 304 if (!_filterReadEmpty) {
305 // Call the onData event. 305 // Call the onData event.
306 if (scheduledDataEvent != null) { 306 if (scheduledDataEvent != null) {
307 scheduledDataEvent.cancel(); 307 scheduledDataEvent.cancel();
308 scheduledDataEvent = null; 308 scheduledDataEvent = null;
309 } 309 }
310 if (_socketDataHandler != null) { 310 if (_socketDataHandler != null) {
311 _socketDataHandler(); 311 _socketDataHandler();
312 } 312 }
313 } 313 }
314 } 314 }
315 } 315 }
316 316
317 void _tlsCloseHandler() { 317 void _secureCloseHandler() {
318 _socketClosedRead = true; 318 _socketClosedRead = true;
319 if (_filterReadEmpty) { 319 if (_filterReadEmpty) {
320 _closedRead = true; 320 _closedRead = true;
321 _fireCloseEvent(); 321 _fireCloseEvent();
322 if (_socketClosedWrite) { 322 if (_socketClosedWrite) {
323 _tlsFilter.destroy(); 323 _secureFilter.destroy();
324 _tlsFilter = null; 324 _secureFilter = null;
325 _status = CLOSED; 325 _status = CLOSED;
326 } 326 }
327 } 327 }
328 } 328 }
329 329
330 void _tlsHandshake() { 330 void _secureHandshake() {
331 _readEncryptedData(); 331 _readEncryptedData();
332 _tlsFilter.handshake(); 332 _secureFilter.handshake();
333 _writeEncryptedData(); 333 _writeEncryptedData();
334 if (_tlsFilter.buffers[WRITE_ENCRYPTED].length > 0) { 334 if (_secureFilter.buffers[WRITE_ENCRYPTED].length > 0) {
335 _socket.onWrite = _tlsWriteHandler; 335 _socket.onWrite = _secureWriteHandler;
336 } 336 }
337 } 337 }
338 338
339 void _tlsHandshakeCompleteHandler() { 339 void _secureHandshakeCompleteHandler() {
340 _status = CONNECTED; 340 _status = CONNECTED;
341 if (_connectPending && _socketConnectHandler != null) { 341 if (_connectPending && _socketConnectHandler != null) {
342 _connectPending = false; 342 _connectPending = false;
343 _socketConnectHandler(); 343 _socketConnectHandler();
344 } 344 }
345 if (_socketWriteHandler != null) { 345 if (_socketWriteHandler != null) {
346 _socket.onWrite = _tlsWriteHandler; 346 _socket.onWrite = _secureWriteHandler;
347 } 347 }
348 } 348 }
349 349
350 // True if the underlying socket is closed, the filter has been emptied of 350 // True if the underlying socket is closed, the filter has been emptied of
351 // all data, and the close event has been fired. 351 // all data, and the close event has been fired.
352 get _closed => _socketClosed && !_fireCloseEventPending; 352 get _closed => _socketClosed && !_fireCloseEventPending;
353 353
354 void _fireCloseEvent() { 354 void _fireCloseEvent() {
355 if (scheduledDataEvent != null) { 355 if (scheduledDataEvent != null) {
356 scheduledDataEvent.cancel(); 356 scheduledDataEvent.cancel();
357 } 357 }
358 if (_socketCloseHandler != null) { 358 if (_socketCloseHandler != null) {
359 _socketCloseHandler(); 359 _socketCloseHandler();
360 } 360 }
361 } 361 }
362 362
363 void _readEncryptedData() { 363 void _readEncryptedData() {
364 // Read from the socket, and push it through the filter as far as 364 // Read from the socket, and push it through the filter as far as
365 // possible. 365 // possible.
366 var encrypted = _tlsFilter.buffers[READ_ENCRYPTED]; 366 var encrypted = _secureFilter.buffers[READ_ENCRYPTED];
367 var plaintext = _tlsFilter.buffers[READ_PLAINTEXT]; 367 var plaintext = _secureFilter.buffers[READ_PLAINTEXT];
368 bool progress = true; 368 bool progress = true;
369 while (progress) { 369 while (progress) {
370 progress = false; 370 progress = false;
371 // Do not try to read plaintext from the filter while handshaking. 371 // Do not try to read plaintext from the filter while handshaking.
372 if ((_status == CONNECTED) && plaintext.free > 0) { 372 if ((_status == CONNECTED) && plaintext.free > 0) {
373 int bytes = _tlsFilter.processBuffer(READ_PLAINTEXT); 373 int bytes = _secureFilter.processBuffer(READ_PLAINTEXT);
374 if (bytes > 0) { 374 if (bytes > 0) {
375 plaintext.length += bytes; 375 plaintext.length += bytes;
376 progress = true; 376 progress = true;
377 } 377 }
378 } 378 }
379 if (encrypted.length > 0) { 379 if (encrypted.length > 0) {
380 int bytes = _tlsFilter.processBuffer(READ_ENCRYPTED); 380 int bytes = _secureFilter.processBuffer(READ_ENCRYPTED);
381 if (bytes > 0) { 381 if (bytes > 0) {
382 encrypted.advanceStart(bytes); 382 encrypted.advanceStart(bytes);
383 progress = true; 383 progress = true;
384 } 384 }
385 } 385 }
386 if (!_socketClosedRead) { 386 if (!_socketClosedRead) {
387 int bytes = _socket.readList(encrypted.data, 387 int bytes = _socket.readList(encrypted.data,
388 encrypted.start + encrypted.length, 388 encrypted.start + encrypted.length,
389 encrypted.free); 389 encrypted.free);
390 if (bytes > 0) { 390 if (bytes > 0) {
391 encrypted.length += bytes; 391 encrypted.length += bytes;
392 progress = true; 392 progress = true;
393 } 393 }
394 } 394 }
395 } 395 }
396 // If there is any data in any stages of the filter, there should 396 // If there is any data in any stages of the filter, there should
397 // be data in the plaintext buffer after this process. 397 // be data in the plaintext buffer after this process.
398 // TODO(whesse): Verify that this is true, and there can be no 398 // TODO(whesse): Verify that this is true, and there can be no
399 // partial encrypted block stuck in the tlsFilter. 399 // partial encrypted block stuck in the secureFilter.
400 _filterReadEmpty = (plaintext.length == 0); 400 _filterReadEmpty = (plaintext.length == 0);
401 } 401 }
402 402
403 void _writeEncryptedData() { 403 void _writeEncryptedData() {
404 if (_socketClosedWrite) return; 404 if (_socketClosedWrite) return;
405 var encrypted = _tlsFilter.buffers[WRITE_ENCRYPTED]; 405 var encrypted = _secureFilter.buffers[WRITE_ENCRYPTED];
406 var plaintext = _tlsFilter.buffers[WRITE_PLAINTEXT]; 406 var plaintext = _secureFilter.buffers[WRITE_PLAINTEXT];
407 while (true) { 407 while (true) {
408 if (encrypted.length > 0) { 408 if (encrypted.length > 0) {
409 // Write from the filter to the socket. 409 // Write from the filter to the socket.
410 int bytes = _socket.writeList(encrypted.data, 410 int bytes = _socket.writeList(encrypted.data,
411 encrypted.start, 411 encrypted.start,
412 encrypted.length); 412 encrypted.length);
413 if (bytes == 0) { 413 if (bytes == 0) {
414 // The socket has blocked while we have data to write. 414 // The socket has blocked while we have data to write.
415 // We must be notified when it becomes unblocked. 415 // We must be notified when it becomes unblocked.
416 _socket.onWrite = _tlsWriteHandler; 416 _socket.onWrite = _secureWriteHandler;
417 _filterWriteEmpty = false; 417 _filterWriteEmpty = false;
418 break; 418 break;
419 } 419 }
420 encrypted.advanceStart(bytes); 420 encrypted.advanceStart(bytes);
421 } else { 421 } else {
422 var plaintext = _tlsFilter.buffers[WRITE_PLAINTEXT]; 422 var plaintext = _secureFilter.buffers[WRITE_PLAINTEXT];
423 if (plaintext.length > 0) { 423 if (plaintext.length > 0) {
424 int plaintext_bytes = _tlsFilter.processBuffer(WRITE_PLAINTEXT); 424 int plaintext_bytes = _secureFilter.processBuffer(WRITE_PLAINTEXT);
425 plaintext.advanceStart(plaintext_bytes); 425 plaintext.advanceStart(plaintext_bytes);
426 } 426 }
427 int bytes = _tlsFilter.processBuffer(WRITE_ENCRYPTED); 427 int bytes = _secureFilter.processBuffer(WRITE_ENCRYPTED);
428 if (bytes <= 0) { 428 if (bytes <= 0) {
429 // We know the WRITE_ENCRYPTED buffer is empty, and the 429 // We know the WRITE_ENCRYPTED buffer is empty, and the
430 // filter wrote zero bytes to it, so the filter must be empty. 430 // filter wrote zero bytes to it, so the filter must be empty.
431 // Also, the WRITE_PLAINTEXT buffer must have been empty, or 431 // Also, the WRITE_PLAINTEXT buffer must have been empty, or
432 // it would have written to the filter. 432 // it would have written to the filter.
433 // TODO(whesse): Verify that the filter works this way. 433 // TODO(whesse): Verify that the filter works this way.
434 _filterWriteEmpty = true; 434 _filterWriteEmpty = true;
435 break; 435 break;
436 } 436 }
437 encrypted.length += bytes; 437 encrypted.length += bytes;
438 } 438 }
439 } 439 }
440 } 440 }
441 441
442 /* After a read, the onData handler is enabled to fire again. 442 /* After a read, the onData handler is enabled to fire again.
443 * We may also have a close event waiting for the TlsFilter to empty. 443 * We may also have a close event waiting for the SecureFilter to empty.
444 */ 444 */
445 void _setHandlersAfterRead() { 445 void _setHandlersAfterRead() {
446 // If the filter is empty, then we are guaranteed an event when it 446 // If the filter is empty, then we are guaranteed an event when it
447 // becomes unblocked. Cancel any _tlsDataHandler call. 447 // becomes unblocked. Cancel any _secureDataHandler call.
448 // Otherwise, schedule a _tlsDataHandler call since there may data 448 // Otherwise, schedule a _secureDataHandler call since there may data
449 // available, and this read call enables the data event. 449 // available, and this read call enables the data event.
450 if (_filterReadEmpty) { 450 if (_filterReadEmpty) {
451 if (scheduledDataEvent != null) { 451 if (scheduledDataEvent != null) {
452 scheduledDataEvent.cancel(); 452 scheduledDataEvent.cancel();
453 scheduledDataEvent = null; 453 scheduledDataEvent = null;
454 } 454 }
455 } else if (scheduledDataEvent == null) { 455 } else if (scheduledDataEvent == null) {
456 scheduledDataEvent = new Timer(0, (_) => _tlsDataHandler()); 456 scheduledDataEvent = new Timer(0, (_) => _secureDataHandler());
457 } 457 }
458 458
459 if (_socketClosedRead) { // An onClose event is pending. 459 if (_socketClosedRead) { // An onClose event is pending.
460 // _closedRead is false, since we are in a read or readList call. 460 // _closedRead is false, since we are in a read or readList call.
461 if (!_filterReadEmpty) { 461 if (!_filterReadEmpty) {
462 // _filterReadEmpty may be out of date since read and readList empty 462 // _filterReadEmpty may be out of date since read and readList empty
463 // the plaintext buffer after calling _readEncryptedData. 463 // the plaintext buffer after calling _readEncryptedData.
464 // TODO(whesse): Fix this as part of fixing read and readList. 464 // TODO(whesse): Fix this as part of fixing read and readList.
465 _readEncryptedData(); 465 _readEncryptedData();
466 } 466 }
467 if (_filterReadEmpty) { 467 if (_filterReadEmpty) {
468 // This can't be an else clause: the value of _filterReadEmpty changes. 468 // This can't be an else clause: the value of _filterReadEmpty changes.
469 // This must be asynchronous, because we are in a read or readList call. 469 // This must be asynchronous, because we are in a read or readList call.
470 new Timer(0, (_) => _fireCloseEvent()); 470 new Timer(0, (_) => _fireCloseEvent());
471 } 471 }
472 } 472 }
473 } 473 }
474 474
475 bool get _socketClosed => _closedRead; 475 bool get _socketClosed => _closedRead;
476 476
477 // _TlsSocket cannot extend _Socket and use _Socket's factory constructor. 477 // _SecureSocket cannot extend _Socket and use _Socket's factory constructor.
478 Socket _socket; 478 Socket _socket;
479 String _host; 479 String _host;
480 int _port; 480 int _port;
481 bool _is_server; 481 bool _is_server;
482 String _certificateName; 482 String _certificateName;
483 483
484 var _status = NOT_CONNECTED; 484 var _status = NOT_CONNECTED;
485 bool _socketClosedRead = false; // The network socket is closed for reading. 485 bool _socketClosedRead = false; // The network socket is closed for reading.
486 bool _socketClosedWrite = false; // The network socket is closed for writing. 486 bool _socketClosedWrite = false; // The network socket is closed for writing.
487 bool _closedRead = false; // The secure socket has fired an onClosed event. 487 bool _closedRead = false; // The secure socket has fired an onClosed event.
488 bool _closedWrite = false; // The secure socket has been closed for writing. 488 bool _closedWrite = false; // The secure socket has been closed for writing.
489 bool _filterReadEmpty = true; // There is no buffered data to read. 489 bool _filterReadEmpty = true; // There is no buffered data to read.
490 bool _filterWriteEmpty = true; // There is no buffered data to be written. 490 bool _filterWriteEmpty = true; // There is no buffered data to be written.
491 _SocketInputStream _inputStream; 491 _SocketInputStream _inputStream;
492 _SocketOutputStream _outputStream; 492 _SocketOutputStream _outputStream;
493 bool _connectPending = false; 493 bool _connectPending = false;
494 Function _socketConnectHandler; 494 Function _socketConnectHandler;
495 Function _socketWriteHandler; 495 Function _socketWriteHandler;
496 Function _socketDataHandler; 496 Function _socketDataHandler;
497 Function _socketCloseHandler; 497 Function _socketCloseHandler;
498 Timer scheduledDataEvent; 498 Timer scheduledDataEvent;
499 499
500 _TlsFilter _tlsFilter; 500 _SecureFilter _secureFilter;
501 } 501 }
502 502
503 503
504 class _TlsExternalBuffer { 504 class _ExternalBuffer {
505 static final int SIZE = 8 * 1024; 505 static final int SIZE = 8 * 1024;
506 _TlsExternalBuffer() : start = 0, length = 0; 506 _ExternalBuffer() : start = 0, length = 0;
507 507
508 // TODO(whesse): Consider making this a circular buffer. Only if it helps. 508 // TODO(whesse): Consider making this a circular buffer. Only if it helps.
509 void advanceStart(int numBytes) { 509 void advanceStart(int numBytes) {
510 start += numBytes; 510 start += numBytes;
511 length -= numBytes; 511 length -= numBytes;
512 if (length == 0) { 512 if (length == 0) {
513 start = 0; 513 start = 0;
514 } 514 }
515 } 515 }
516 516
517 int get free => SIZE - (start + length); 517 int get free => SIZE - (start + length);
518 518
519 List data; // This will be a ExternalByteArray, backed by C allocated data. 519 List data; // This will be a ExternalByteArray, backed by C allocated data.
520 int start; 520 int start;
521 int length; 521 int length;
522 } 522 }
523 523
524 524
525 abstract class _TlsFilter { 525 abstract class _SecureFilter {
526 external factory _TlsFilter(); 526 external factory _SecureFilter();
527 527
528 void connect(String hostName, 528 void connect(String hostName,
529 int port, 529 int port,
530 bool is_server, 530 bool is_server,
531 String certificateName); 531 String certificateName);
532 void destroy(); 532 void destroy();
533 void handshake(); 533 void handshake();
534 void init(); 534 void init();
535 int processBuffer(int bufferIndex); 535 int processBuffer(int bufferIndex);
536 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); 536 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);
537 537
538 List<_TlsExternalBuffer> get buffers; 538 List<_ExternalBuffer> get buffers;
539 } 539 }
OLDNEW
« no previous file with comments | « sdk/lib/io/secure_server_socket.dart ('k') | sdk/lib/io/tls_server_socket.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698