Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A high-level class for communicating securely over a TCP socket, using | 8 * A high-level class for communicating securely over a TCP socket, using |
| 9 * TLS and SSL. The [SecureSocket] exposes both a [Stream] and an | 9 * TLS and SSL. The [SecureSocket] exposes both a [Stream] and an |
| 10 * [IOSink] interface, making it ideal for using together with | 10 * [IOSink] interface, making it ideal for using together with |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 * appropriate certificate will be searched for in the database and | 28 * appropriate certificate will be searched for in the database and |
| 29 * sent automatically, based on what the server says it will accept. | 29 * sent automatically, based on what the server says it will accept. |
| 30 * | 30 * |
| 31 * [onBadCertificate] is an optional handler for unverifiable certificates. | 31 * [onBadCertificate] is an optional handler for unverifiable certificates. |
| 32 * The handler receives the [X509Certificate], and can inspect it and | 32 * The handler receives the [X509Certificate], and can inspect it and |
| 33 * decide (or let the user decide) whether to accept | 33 * decide (or let the user decide) whether to accept |
| 34 * the connection or not. The handler should return true | 34 * the connection or not. The handler should return true |
| 35 * to continue the [SecureSocket] connection. | 35 * to continue the [SecureSocket] connection. |
| 36 */ | 36 */ |
| 37 static Future<SecureSocket> connect( | 37 static Future<SecureSocket> connect( |
| 38 String host, | 38 host, |
| 39 int port, | 39 int port, |
| 40 {bool sendClientCertificate: false, | 40 {bool sendClientCertificate: false, |
| 41 String certificateName, | 41 String certificateName, |
| 42 bool onBadCertificate(X509Certificate certificate)}) { | 42 bool onBadCertificate(X509Certificate certificate)}) { |
| 43 return RawSecureSocket.connect(host, | 43 return RawSecureSocket.connect(host, |
| 44 port, | 44 port, |
| 45 sendClientCertificate: sendClientCertificate, | 45 sendClientCertificate: sendClientCertificate, |
| 46 certificateName: certificateName, | 46 certificateName: certificateName, |
| 47 onBadCertificate: onBadCertificate) | 47 onBadCertificate: onBadCertificate) |
| 48 .then((rawSocket) => new SecureSocket._(rawSocket)); | 48 .then((rawSocket) => new SecureSocket._(rawSocket)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 * appropriate certificate will be searched for in the database and | 122 * appropriate certificate will be searched for in the database and |
| 123 * sent automatically, based on what the server says it will accept. | 123 * sent automatically, based on what the server says it will accept. |
| 124 * | 124 * |
| 125 * [onBadCertificate] is an optional handler for unverifiable certificates. | 125 * [onBadCertificate] is an optional handler for unverifiable certificates. |
| 126 * The handler receives the [X509Certificate], and can inspect it and | 126 * The handler receives the [X509Certificate], and can inspect it and |
| 127 * decide (or let the user decide) whether to accept | 127 * decide (or let the user decide) whether to accept |
| 128 * the connection or not. The handler should return true | 128 * the connection or not. The handler should return true |
| 129 * to continue the [RawSecureSocket] connection. | 129 * to continue the [RawSecureSocket] connection. |
| 130 */ | 130 */ |
| 131 static Future<RawSecureSocket> connect( | 131 static Future<RawSecureSocket> connect( |
| 132 String host, | 132 host, |
| 133 int port, | 133 int port, |
| 134 {bool sendClientCertificate: false, | 134 {bool sendClientCertificate: false, |
| 135 String certificateName, | 135 String certificateName, |
| 136 bool onBadCertificate(X509Certificate certificate)}) { | 136 bool onBadCertificate(X509Certificate certificate)}) { |
| 137 return _RawSecureSocket.connect( | 137 return _RawSecureSocket.connect( |
| 138 host, | 138 host, |
| 139 port, | 139 port, |
| 140 certificateName, | 140 certificateName, |
| 141 is_server: false, | 141 is_server: false, |
| 142 sendClientCertificate: sendClientCertificate, | 142 sendClientCertificate: sendClientCertificate, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 158 * See [connect] for more information on the arguments. | 158 * See [connect] for more information on the arguments. |
| 159 * | 159 * |
| 160 */ | 160 */ |
| 161 static Future<RawSecureSocket> secure( | 161 static Future<RawSecureSocket> secure( |
| 162 RawSocket socket, | 162 RawSocket socket, |
| 163 {StreamSubscription subscription, | 163 {StreamSubscription subscription, |
| 164 bool sendClientCertificate: false, | 164 bool sendClientCertificate: false, |
| 165 String certificateName, | 165 String certificateName, |
| 166 bool onBadCertificate(X509Certificate certificate)}) { | 166 bool onBadCertificate(X509Certificate certificate)}) { |
| 167 return _RawSecureSocket.connect( | 167 return _RawSecureSocket.connect( |
| 168 socket.host, | 168 socket.address, |
| 169 socket.port, | 169 socket.port, |
| 170 certificateName, | 170 certificateName, |
| 171 is_server: false, | 171 is_server: false, |
| 172 socket: socket, | 172 socket: socket, |
| 173 subscription: subscription, | 173 subscription: subscription, |
| 174 sendClientCertificate: sendClientCertificate, | 174 sendClientCertificate: sendClientCertificate, |
| 175 onBadCertificate: onBadCertificate); | 175 onBadCertificate: onBadCertificate); |
| 176 } | 176 } |
| 177 | 177 |
| 178 /** | 178 /** |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 static final int NUM_BUFFERS = 4; | 259 static final int NUM_BUFFERS = 4; |
| 260 | 260 |
| 261 RawSocket _socket; | 261 RawSocket _socket; |
| 262 final Completer<_RawSecureSocket> _handshakeComplete = | 262 final Completer<_RawSecureSocket> _handshakeComplete = |
| 263 new Completer<_RawSecureSocket>(); | 263 new Completer<_RawSecureSocket>(); |
| 264 StreamController<RawSocketEvent> _controller; | 264 StreamController<RawSocketEvent> _controller; |
| 265 Stream<RawSocketEvent> _stream; | 265 Stream<RawSocketEvent> _stream; |
| 266 StreamSubscription<RawSocketEvent> _socketSubscription; | 266 StreamSubscription<RawSocketEvent> _socketSubscription; |
| 267 List<int> _carryOverData; | 267 List<int> _carryOverData; |
| 268 int _carryOverDataIndex = 0; | 268 int _carryOverDataIndex = 0; |
| 269 final String host; | 269 final InternetAddress address; |
| 270 final bool is_server; | 270 final bool is_server; |
| 271 final String certificateName; | 271 final String certificateName; |
| 272 final bool requestClientCertificate; | 272 final bool requestClientCertificate; |
| 273 final bool requireClientCertificate; | 273 final bool requireClientCertificate; |
| 274 final bool sendClientCertificate; | 274 final bool sendClientCertificate; |
| 275 final Function onBadCertificate; | 275 final Function onBadCertificate; |
| 276 | 276 |
| 277 var _status = NOT_CONNECTED; | 277 var _status = NOT_CONNECTED; |
| 278 bool _writeEventsEnabled = true; | 278 bool _writeEventsEnabled = true; |
| 279 bool _readEventsEnabled = true; | 279 bool _readEventsEnabled = true; |
| 280 bool _socketClosedRead = false; // The network socket is closed for reading. | 280 bool _socketClosedRead = false; // The network socket is closed for reading. |
| 281 bool _socketClosedWrite = false; // The network socket is closed for writing. | 281 bool _socketClosedWrite = false; // The network socket is closed for writing. |
| 282 bool _closedRead = false; // The secure socket has fired an onClosed event. | 282 bool _closedRead = false; // The secure socket has fired an onClosed event. |
| 283 bool _closedWrite = false; // The secure socket has been closed for writing. | 283 bool _closedWrite = false; // The secure socket has been closed for writing. |
| 284 bool _filterReadEmpty = true; // There is no buffered data to read. | 284 bool _filterReadEmpty = true; // There is no buffered data to read. |
| 285 bool _filterWriteEmpty = true; // There is no buffered data to be written. | 285 bool _filterWriteEmpty = true; // There is no buffered data to be written. |
| 286 bool _connectPending = false; | 286 bool _connectPending = false; |
| 287 _SecureFilter _secureFilter = new _SecureFilter(); | 287 _SecureFilter _secureFilter = new _SecureFilter(); |
| 288 | 288 |
| 289 static Future<_RawSecureSocket> connect( | 289 static Future<_RawSecureSocket> connect( |
| 290 String host, | 290 host, |
| 291 int requestedPort, | 291 int requestedPort, |
| 292 String certificateName, | 292 String certificateName, |
| 293 {bool is_server, | 293 {bool is_server, |
| 294 RawSocket socket, | 294 RawSocket socket, |
| 295 StreamSubscription subscription, | 295 StreamSubscription subscription, |
| 296 List<int> carryOverData, | 296 List<int> carryOverData, |
| 297 bool requestClientCertificate: false, | 297 bool requestClientCertificate: false, |
| 298 bool requireClientCertificate: false, | 298 bool requireClientCertificate: false, |
| 299 bool sendClientCertificate: false, | 299 bool sendClientCertificate: false, |
| 300 bool onBadCertificate(X509Certificate certificate)}){ | 300 bool onBadCertificate(X509Certificate certificate)}) { |
|
Søren Gjesse
2013/04/22 15:02:08
Move this new Future to an else block?
Anders Johnsen
2013/04/23 08:03:57
Done.
| |
| 301 return new _RawSecureSocket(host, | 301 var future = new Future.value(host); |
| 302 if (host is String) { | |
| 303 future = InternetAddress.lookup(host).then((addrs) => addrs.first); | |
| 304 } | |
| 305 return future.then((addr) { | |
| 306 return new _RawSecureSocket(addr, | |
| 302 requestedPort, | 307 requestedPort, |
| 303 certificateName, | 308 certificateName, |
| 304 is_server, | 309 is_server, |
| 305 socket, | 310 socket, |
| 306 subscription, | 311 subscription, |
| 307 carryOverData, | 312 carryOverData, |
| 308 requestClientCertificate, | 313 requestClientCertificate, |
| 309 requireClientCertificate, | 314 requireClientCertificate, |
| 310 sendClientCertificate, | 315 sendClientCertificate, |
| 311 onBadCertificate) | 316 onBadCertificate) |
| 312 ._handshakeComplete.future; | 317 ._handshakeComplete.future; |
| 318 }); | |
| 313 } | 319 } |
| 314 | 320 |
| 315 _RawSecureSocket( | 321 _RawSecureSocket( |
| 316 String this.host, | 322 InternetAddress this.address, |
| 317 int requestedPort, | 323 int requestedPort, |
| 318 String this.certificateName, | 324 String this.certificateName, |
| 319 bool this.is_server, | 325 bool this.is_server, |
| 320 RawSocket socket, | 326 RawSocket socket, |
| 321 StreamSubscription this._socketSubscription, | 327 StreamSubscription this._socketSubscription, |
| 322 List<int> this._carryOverData, | 328 List<int> this._carryOverData, |
| 323 bool this.requestClientCertificate, | 329 bool this.requestClientCertificate, |
| 324 bool this.requireClientCertificate, | 330 bool this.requireClientCertificate, |
| 325 bool this.sendClientCertificate, | 331 bool this.sendClientCertificate, |
| 326 bool this.onBadCertificate(X509Certificate certificate)) { | 332 bool this.onBadCertificate(X509Certificate certificate)) { |
| 327 _controller = new StreamController<RawSocketEvent>( | 333 _controller = new StreamController<RawSocketEvent>( |
| 328 onListen: _onSubscriptionStateChange, | 334 onListen: _onSubscriptionStateChange, |
| 329 onPause: _onPauseStateChange, | 335 onPause: _onPauseStateChange, |
| 330 onResume: _onPauseStateChange, | 336 onResume: _onPauseStateChange, |
| 331 onCancel: _onSubscriptionStateChange); | 337 onCancel: _onSubscriptionStateChange); |
| 332 _stream = _controller.stream; | 338 _stream = _controller.stream; |
| 333 // Throw an ArgumentError if any field is invalid. After this, all | 339 // Throw an ArgumentError if any field is invalid. After this, all |
| 334 // errors will be reported through the future or the stream. | 340 // errors will be reported through the future or the stream. |
| 335 _verifyFields(); | 341 _verifyFields(); |
| 336 _secureFilter.init(); | 342 _secureFilter.init(); |
| 337 if (_carryOverData != null) _readFromCarryOver(); | 343 if (_carryOverData != null) _readFromCarryOver(); |
| 338 _secureFilter.registerHandshakeCompleteCallback( | 344 _secureFilter.registerHandshakeCompleteCallback( |
| 339 _secureHandshakeCompleteHandler); | 345 _secureHandshakeCompleteHandler); |
| 340 if (onBadCertificate != null) { | 346 if (onBadCertificate != null) { |
| 341 _secureFilter.registerBadCertificateCallback(onBadCertificate); | 347 _secureFilter.registerBadCertificateCallback(onBadCertificate); |
| 342 } | 348 } |
| 343 var futureSocket; | 349 var futureSocket; |
| 344 if (socket == null) { | 350 if (socket == null) { |
| 345 futureSocket = RawSocket.connect(host, requestedPort); | 351 futureSocket = RawSocket.connect(address, requestedPort); |
| 346 } else { | 352 } else { |
| 347 futureSocket = new Future.value(socket); | 353 futureSocket = new Future.value(socket); |
| 348 } | 354 } |
| 349 futureSocket.then((rawSocket) { | 355 futureSocket.then((rawSocket) { |
| 350 rawSocket.writeEventsEnabled = false; | 356 rawSocket.writeEventsEnabled = false; |
| 351 _socket = rawSocket; | 357 _socket = rawSocket; |
| 352 if (_socketSubscription == null) { | 358 if (_socketSubscription == null) { |
| 353 // If a current subscription is provided use this otherwise | 359 // If a current subscription is provided use this otherwise |
| 354 // create a new one. | 360 // create a new one. |
| 355 _socketSubscription = _socket.listen(_eventDispatcher, | 361 _socketSubscription = _socket.listen(_eventDispatcher, |
| 356 onError: _errorHandler, | 362 onError: _errorHandler, |
| 357 onDone: _doneHandler); | 363 onDone: _doneHandler); |
| 358 } else { | 364 } else { |
| 359 _socketSubscription.onData(_eventDispatcher); | 365 _socketSubscription.onData(_eventDispatcher); |
| 360 _socketSubscription.onError(_errorHandler); | 366 _socketSubscription.onError(_errorHandler); |
| 361 _socketSubscription.onDone(_doneHandler); | 367 _socketSubscription.onDone(_doneHandler); |
| 362 } | 368 } |
| 363 _connectPending = true; | 369 _connectPending = true; |
| 364 _secureFilter.connect(host, | 370 _secureFilter.connect(rawSocket.address.host, |
| 365 port, | 371 port, |
| 366 is_server, | 372 is_server, |
| 367 certificateName, | 373 certificateName, |
| 368 requestClientCertificate || | 374 requestClientCertificate || |
| 369 requireClientCertificate, | 375 requireClientCertificate, |
| 370 requireClientCertificate, | 376 requireClientCertificate, |
| 371 sendClientCertificate); | 377 sendClientCertificate); |
| 372 _status = HANDSHAKE; | 378 _status = HANDSHAKE; |
| 373 _secureHandshake(); | 379 _secureHandshake(); |
| 374 }) | 380 }) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 388 } | 394 } |
| 389 return _stream.listen(onData, | 395 return _stream.listen(onData, |
| 390 onError: onError, | 396 onError: onError, |
| 391 onDone: onDone, | 397 onDone: onDone, |
| 392 cancelOnError: cancelOnError); | 398 cancelOnError: cancelOnError); |
| 393 } | 399 } |
| 394 | 400 |
| 395 void _verifyFields() { | 401 void _verifyFields() { |
| 396 assert(is_server is bool); | 402 assert(is_server is bool); |
| 397 assert(_socket == null || _socket is RawSocket); | 403 assert(_socket == null || _socket is RawSocket); |
| 398 if (host is! String) { | 404 if (address is! InternetAddress) { |
| 399 throw new ArgumentError( | 405 throw new ArgumentError( |
| 400 "RawSecureSocket constructor: host is not a String"); | 406 "RawSecureSocket constructor: host is not an InternetAddress"); |
| 401 } | 407 } |
| 402 if (certificateName != null && certificateName is! String) { | 408 if (certificateName != null && certificateName is! String) { |
| 403 throw new ArgumentError("certificateName is not null or a String"); | 409 throw new ArgumentError("certificateName is not null or a String"); |
| 404 } | 410 } |
| 405 if (certificateName == null && is_server) { | 411 if (certificateName == null && is_server) { |
| 406 throw new ArgumentError("certificateName is null on a server"); | 412 throw new ArgumentError("certificateName is null on a server"); |
| 407 } | 413 } |
| 408 if (requestClientCertificate is! bool) { | 414 if (requestClientCertificate is! bool) { |
| 409 throw new ArgumentError("requestClientCertificate is not a bool"); | 415 throw new ArgumentError("requestClientCertificate is not a bool"); |
| 410 } | 416 } |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 865 void destroy(); | 871 void destroy(); |
| 866 void handshake(); | 872 void handshake(); |
| 867 void init(); | 873 void init(); |
| 868 X509Certificate get peerCertificate; | 874 X509Certificate get peerCertificate; |
| 869 int processBuffer(int bufferIndex); | 875 int processBuffer(int bufferIndex); |
| 870 void registerBadCertificateCallback(Function callback); | 876 void registerBadCertificateCallback(Function callback); |
| 871 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); | 877 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); |
| 872 | 878 |
| 873 List<_ExternalBuffer> get buffers; | 879 List<_ExternalBuffer> get buffers; |
| 874 } | 880 } |
| OLD | NEW |