OLD | NEW |
---|---|
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 part of dart_io; | 5 part of dart_io; |
6 | 6 |
7 /** | 7 /** |
8 * SecureSocket provides a secure (SSL or TLS) client connection to a server. | 8 * SecureSocket provides a secure (SSL or TLS) client connection to a server. |
9 * The certificate provided by the server is checked | 9 * The certificate provided by the server is checked |
10 * using the certificate database provided in setCertificateDatabase. | 10 * using the certificate database provided in setCertificateDatabase. |
11 */ | 11 */ |
12 abstract class SecureSocket implements Socket { | 12 abstract class SecureSocket implements Socket { |
13 /** | 13 /** |
14 * Constructs a new secure client socket and connect it to the given | 14 * Constructs a new secure client socket and connect it to the given |
15 * host on the given port. The returned socket is not yet connected | 15 * host on the given port. The returned socket is not yet connected |
16 * but ready for registration of callbacks. | 16 * but ready for registration of callbacks. |
17 */ | 17 */ |
18 factory SecureSocket(String host, int port) => new _SecureSocket(host, port); | 18 factory SecureSocket(String host, int port) => new _SecureSocket(host, port); |
19 | 19 |
20 /** | 20 /** |
21 * Initializes the NSS library with the path to a certificate database | 21 * Initializes the NSS library with the path to a certificate database |
22 * containing root certificates for verifying certificate paths on | 22 * containing root certificates for verifying certificate paths on |
23 * client connections, and server certificates to provide on server | 23 * client connections, and server certificates to provide on server |
24 * connections. The password argument should be used when creating | 24 * connections. The password argument should be used when creating |
25 * secure server sockets, to allow the private key of the server | 25 * secure server sockets, to allow the private key of the server |
26 * certificate to be fetched. | 26 * certificate to be fetched. If useBuiltinRoots is true (the default), |
27 * then an built-in set of root certificates for trusted certificate | |
Mads Ager (google)
2012/11/29 20:13:05
an built-in set -> a built-in set?
Bill Hesse
2012/11/30 12:51:16
Done.
| |
28 * authorities is merged with the certificates in the database. | |
27 * | 29 * |
28 * The database should be an NSS certificate database directory | 30 * The database should be an NSS certificate database directory |
29 * containing a cert9.db file, not a cert8.db file. This version of | 31 * containing a cert9.db file, not a cert8.db file. This version of |
30 * the database can be created using the NSS certutil tool with "sql:" in | 32 * the database can be created using the NSS certutil tool with "sql:" in |
31 * front of the absolute path of the database directory, or setting the | 33 * front of the absolute path of the database directory, or setting the |
32 * environment variable NSS_DEFAULT_DB_TYPE to "sql". | 34 * environment variable NSS_DEFAULT_DB_TYPE to "sql". |
33 */ | 35 */ |
34 external static void setCertificateDatabase(String certificateDatabase, | 36 external static void setCertificateDatabase(String certificateDatabase, |
Mads Ager (google)
2012/11/29 20:13:05
How do you get away with only using the built-in s
Bill Hesse
2012/11/30 12:51:16
Done.
| |
35 [String password]); | 37 {String password, |
38 bool useBuiltinRoots: true}); | |
36 } | 39 } |
37 | 40 |
38 | 41 |
39 class _SecureSocket implements SecureSocket { | 42 class _SecureSocket implements SecureSocket { |
40 // Status states | 43 // Status states |
41 static final int NOT_CONNECTED = 200; | 44 static final int NOT_CONNECTED = 200; |
42 static final int HANDSHAKE = 201; | 45 static final int HANDSHAKE = 201; |
43 static final int CONNECTED = 202; | 46 static final int CONNECTED = 202; |
44 static final int CLOSED = 203; | 47 static final int CLOSED = 203; |
45 | 48 |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) { | 295 _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) { |
293 // We must be able to set onWrite from the onWrite callback. | 296 // We must be able to set onWrite from the onWrite callback. |
294 var handler = _socketWriteHandler; | 297 var handler = _socketWriteHandler; |
295 // Reset the one-shot handler. | 298 // Reset the one-shot handler. |
296 _socketWriteHandler = null; | 299 _socketWriteHandler = null; |
297 handler(); | 300 handler(); |
298 } | 301 } |
299 } | 302 } |
300 | 303 |
301 void _secureDataHandler() { | 304 void _secureDataHandler() { |
302 if (_status == HANDSHAKE) { | 305 bool inUserCode = false; |
303 _secureHandshake(); | 306 try { |
Mads Ager (google)
2012/11/29 20:13:05
I think we should do our best to avoid this type o
Bill Hesse
2012/11/30 12:51:16
In the socket class, the onError handler can be ca
| |
304 } else { | 307 if (_status == HANDSHAKE) { |
305 _writeEncryptedData(); // TODO(whesse): Removing this causes a failure. | 308 _secureHandshake(); |
306 _readEncryptedData(); | 309 } else { |
307 if (!_filterReadEmpty) { | 310 _writeEncryptedData(); // TODO(whesse): Removing this causes a failure. |
308 // Call the onData event. | 311 _readEncryptedData(); |
309 if (scheduledDataEvent != null) { | 312 if (!_filterReadEmpty) { |
310 scheduledDataEvent.cancel(); | 313 // Call the onData event. |
311 scheduledDataEvent = null; | 314 if (scheduledDataEvent != null) { |
315 scheduledDataEvent.cancel(); | |
316 scheduledDataEvent = null; | |
317 } | |
318 if (_socketDataHandler != null) { | |
319 inUserCode = true; | |
320 _socketDataHandler(); | |
321 } | |
312 } | 322 } |
313 if (_socketDataHandler != null) { | 323 } |
314 _socketDataHandler(); | 324 } catch (e) { |
315 } | 325 if (inUserCode) { |
326 throw e; | |
327 } else { | |
328 _reportError(e, "SecureSocket error"); | |
316 } | 329 } |
317 } | 330 } |
318 } | 331 } |
319 | 332 |
320 void _secureErrorHandler(e) { | 333 void _secureErrorHandler(e) { |
321 _reportError(e, 'Error on underlying Socket'); | 334 _reportError(e, 'Error on underlying Socket'); |
322 } | 335 } |
323 | 336 |
324 void _reportError(error, String message) { | 337 void _reportError(error, String message) { |
325 // TODO(whesse): Call _reportError from all internal functions that throw. | 338 // TODO(whesse): Call _reportError from all internal functions that throw. |
326 var e; | 339 var e; |
327 if (error is SocketIOException) { | 340 if (error is SocketIOException) { |
328 e = new SocketIOException('$message (${error.message})', error.osError); | 341 e = new SocketIOException('$message (${error.message})', error.osError); |
329 } else if (error is OSError) { | 342 } else if (error is OSError) { |
330 e = new SocketIOException(message, error); | 343 e = new SocketIOException(message, error); |
331 } else { | 344 } else { |
332 e = new SocketIOException('$message (${error.toString()})', null); | 345 e = new SocketIOException('$message (${error.toString()})', null); |
333 } | 346 } |
347 close(false); | |
334 bool reported = false; | 348 bool reported = false; |
335 if (_socketErrorHandler != null) { | 349 if (_socketErrorHandler != null) { |
336 reported = true; | 350 reported = true; |
337 _socketErrorHandler(e); | 351 _socketErrorHandler(e); |
338 } | 352 } |
339 if (_inputStream != null) { | 353 if (_inputStream != null) { |
340 reported = reported || _inputStream._onSocketError(e); | 354 reported = reported || _inputStream._onSocketError(e); |
341 } | 355 } |
342 if (_outputStream != null) { | 356 if (_outputStream != null) { |
343 reported = reported || _outputStream._onSocketError(e); | 357 reported = reported || _outputStream._onSocketError(e); |
344 } | 358 } |
345 | |
346 if (!reported) throw e; | 359 if (!reported) throw e; |
347 } | 360 } |
348 | 361 |
349 void _secureCloseHandler() { | 362 void _secureCloseHandler() { |
350 _socketClosedRead = true; | 363 _socketClosedRead = true; |
351 if (_filterReadEmpty) { | 364 if (_filterReadEmpty) { |
352 _closedRead = true; | 365 _closedRead = true; |
353 _fireCloseEvent(); | 366 _fireCloseEvent(); |
354 if (_socketClosedWrite) { | 367 if (_socketClosedWrite) { |
355 _secureFilter.destroy(); | 368 _secureFilter.destroy(); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
563 bool is_server, | 576 bool is_server, |
564 String certificateName); | 577 String certificateName); |
565 void destroy(); | 578 void destroy(); |
566 void handshake(); | 579 void handshake(); |
567 void init(); | 580 void init(); |
568 int processBuffer(int bufferIndex); | 581 int processBuffer(int bufferIndex); |
569 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); | 582 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); |
570 | 583 |
571 List<_ExternalBuffer> get buffers; | 584 List<_ExternalBuffer> get buffers; |
572 } | 585 } |
OLD | NEW |