| 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 host, | 38 String 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 * appropriate certificate will be searched for in the database and | 201 * appropriate certificate will be searched for in the database and |
| 202 * sent automatically, based on what the server says it will accept. | 202 * sent automatically, based on what the server says it will accept. |
| 203 * | 203 * |
| 204 * [onBadCertificate] is an optional handler for unverifiable certificates. | 204 * [onBadCertificate] is an optional handler for unverifiable certificates. |
| 205 * The handler receives the [X509Certificate], and can inspect it and | 205 * The handler receives the [X509Certificate], and can inspect it and |
| 206 * decide (or let the user decide) whether to accept | 206 * decide (or let the user decide) whether to accept |
| 207 * the connection or not. The handler should return true | 207 * the connection or not. The handler should return true |
| 208 * to continue the [RawSecureSocket] connection. | 208 * to continue the [RawSecureSocket] connection. |
| 209 */ | 209 */ |
| 210 static Future<RawSecureSocket> connect( | 210 static Future<RawSecureSocket> connect( |
| 211 host, | 211 String host, |
| 212 int port, | 212 int port, |
| 213 {bool sendClientCertificate: false, | 213 {bool sendClientCertificate: false, |
| 214 String certificateName, | 214 String certificateName, |
| 215 bool onBadCertificate(X509Certificate certificate)}) { | 215 bool onBadCertificate(X509Certificate certificate)}) { |
| 216 return _RawSecureSocket.connect( | 216 return _RawSecureSocket.connect( |
| 217 host, | 217 host, |
| 218 port, | 218 port, |
| 219 certificateName, | 219 certificateName, |
| 220 is_server: false, | 220 is_server: false, |
| 221 sendClientCertificate: sendClientCertificate, | 221 sendClientCertificate: sendClientCertificate, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 237 * See [connect] for more information on the arguments. | 237 * See [connect] for more information on the arguments. |
| 238 * | 238 * |
| 239 */ | 239 */ |
| 240 static Future<RawSecureSocket> secure( | 240 static Future<RawSecureSocket> secure( |
| 241 RawSocket socket, | 241 RawSocket socket, |
| 242 {StreamSubscription subscription, | 242 {StreamSubscription subscription, |
| 243 bool sendClientCertificate: false, | 243 bool sendClientCertificate: false, |
| 244 String certificateName, | 244 String certificateName, |
| 245 bool onBadCertificate(X509Certificate certificate)}) { | 245 bool onBadCertificate(X509Certificate certificate)}) { |
| 246 return _RawSecureSocket.connect( | 246 return _RawSecureSocket.connect( |
| 247 socket.address, | 247 socket.host, |
| 248 socket.port, | 248 socket.port, |
| 249 certificateName, | 249 certificateName, |
| 250 is_server: false, | 250 is_server: false, |
| 251 socket: socket, | 251 socket: socket, |
| 252 subscription: subscription, | 252 subscription: subscription, |
| 253 sendClientCertificate: sendClientCertificate, | 253 sendClientCertificate: sendClientCertificate, |
| 254 onBadCertificate: onBadCertificate); | 254 onBadCertificate: onBadCertificate); |
| 255 } | 255 } |
| 256 | 256 |
| 257 /** | 257 /** |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 static final int NUM_BUFFERS = 4; | 338 static final int NUM_BUFFERS = 4; |
| 339 | 339 |
| 340 RawSocket _socket; | 340 RawSocket _socket; |
| 341 final Completer<_RawSecureSocket> _handshakeComplete = | 341 final Completer<_RawSecureSocket> _handshakeComplete = |
| 342 new Completer<_RawSecureSocket>(); | 342 new Completer<_RawSecureSocket>(); |
| 343 StreamController<RawSocketEvent> _controller; | 343 StreamController<RawSocketEvent> _controller; |
| 344 Stream<RawSocketEvent> _stream; | 344 Stream<RawSocketEvent> _stream; |
| 345 StreamSubscription<RawSocketEvent> _socketSubscription; | 345 StreamSubscription<RawSocketEvent> _socketSubscription; |
| 346 List<int> _carryOverData; | 346 List<int> _carryOverData; |
| 347 int _carryOverDataIndex = 0; | 347 int _carryOverDataIndex = 0; |
| 348 final InternetAddress address; | 348 final String host; |
| 349 final bool is_server; | 349 final bool is_server; |
| 350 final String certificateName; | 350 final String certificateName; |
| 351 final bool requestClientCertificate; | 351 final bool requestClientCertificate; |
| 352 final bool requireClientCertificate; | 352 final bool requireClientCertificate; |
| 353 final bool sendClientCertificate; | 353 final bool sendClientCertificate; |
| 354 final Function onBadCertificate; | 354 final Function onBadCertificate; |
| 355 | 355 |
| 356 var _status = NOT_CONNECTED; | 356 var _status = NOT_CONNECTED; |
| 357 bool _writeEventsEnabled = true; | 357 bool _writeEventsEnabled = true; |
| 358 bool _readEventsEnabled = true; | 358 bool _readEventsEnabled = true; |
| 359 bool _socketClosedRead = false; // The network socket is closed for reading. | 359 bool _socketClosedRead = false; // The network socket is closed for reading. |
| 360 bool _socketClosedWrite = false; // The network socket is closed for writing. | 360 bool _socketClosedWrite = false; // The network socket is closed for writing. |
| 361 bool _closedRead = false; // The secure socket has fired an onClosed event. | 361 bool _closedRead = false; // The secure socket has fired an onClosed event. |
| 362 bool _closedWrite = false; // The secure socket has been closed for writing. | 362 bool _closedWrite = false; // The secure socket has been closed for writing. |
| 363 bool _filterReadEmpty = true; // There is no buffered data to read. | 363 bool _filterReadEmpty = true; // There is no buffered data to read. |
| 364 bool _filterWriteEmpty = true; // There is no buffered data to be written. | 364 bool _filterWriteEmpty = true; // There is no buffered data to be written. |
| 365 bool _connectPending = false; | 365 bool _connectPending = false; |
| 366 _SecureFilter _secureFilter = new _SecureFilter(); | 366 _SecureFilter _secureFilter = new _SecureFilter(); |
| 367 | 367 |
| 368 static Future<_RawSecureSocket> connect( | 368 static Future<_RawSecureSocket> connect( |
| 369 host, | 369 String host, |
| 370 int requestedPort, | 370 int requestedPort, |
| 371 String certificateName, | 371 String certificateName, |
| 372 {bool is_server, | 372 {bool is_server, |
| 373 RawSocket socket, | 373 RawSocket socket, |
| 374 StreamSubscription subscription, | 374 StreamSubscription subscription, |
| 375 List<int> carryOverData, | 375 List<int> carryOverData, |
| 376 bool requestClientCertificate: false, | 376 bool requestClientCertificate: false, |
| 377 bool requireClientCertificate: false, | 377 bool requireClientCertificate: false, |
| 378 bool sendClientCertificate: false, | 378 bool sendClientCertificate: false, |
| 379 bool onBadCertificate(X509Certificate certificate)}) { | 379 bool onBadCertificate(X509Certificate certificate)}){ |
| 380 var future; | 380 return new _RawSecureSocket(host, |
| 381 if (host is String) { | |
| 382 future = InternetAddress.lookup(host).then((addrs) => addrs.first); | |
| 383 } else { | |
| 384 future = new Future.value(host); | |
| 385 } | |
| 386 return future.then((addr) { | |
| 387 return new _RawSecureSocket(addr, | |
| 388 requestedPort, | 381 requestedPort, |
| 389 certificateName, | 382 certificateName, |
| 390 is_server, | 383 is_server, |
| 391 socket, | 384 socket, |
| 392 subscription, | 385 subscription, |
| 393 carryOverData, | 386 carryOverData, |
| 394 requestClientCertificate, | 387 requestClientCertificate, |
| 395 requireClientCertificate, | 388 requireClientCertificate, |
| 396 sendClientCertificate, | 389 sendClientCertificate, |
| 397 onBadCertificate) | 390 onBadCertificate) |
| 398 ._handshakeComplete.future; | 391 ._handshakeComplete.future; |
| 399 }); | |
| 400 } | 392 } |
| 401 | 393 |
| 402 _RawSecureSocket( | 394 _RawSecureSocket( |
| 403 InternetAddress this.address, | 395 String this.host, |
| 404 int requestedPort, | 396 int requestedPort, |
| 405 String this.certificateName, | 397 String this.certificateName, |
| 406 bool this.is_server, | 398 bool this.is_server, |
| 407 RawSocket socket, | 399 RawSocket socket, |
| 408 StreamSubscription this._socketSubscription, | 400 StreamSubscription this._socketSubscription, |
| 409 List<int> this._carryOverData, | 401 List<int> this._carryOverData, |
| 410 bool this.requestClientCertificate, | 402 bool this.requestClientCertificate, |
| 411 bool this.requireClientCertificate, | 403 bool this.requireClientCertificate, |
| 412 bool this.sendClientCertificate, | 404 bool this.sendClientCertificate, |
| 413 bool this.onBadCertificate(X509Certificate certificate)) { | 405 bool this.onBadCertificate(X509Certificate certificate)) { |
| 414 _controller = new StreamController<RawSocketEvent>( | 406 _controller = new StreamController<RawSocketEvent>( |
| 415 onListen: _onSubscriptionStateChange, | 407 onListen: _onSubscriptionStateChange, |
| 416 onPause: _onPauseStateChange, | 408 onPause: _onPauseStateChange, |
| 417 onResume: _onPauseStateChange, | 409 onResume: _onPauseStateChange, |
| 418 onCancel: _onSubscriptionStateChange); | 410 onCancel: _onSubscriptionStateChange); |
| 419 _stream = _controller.stream; | 411 _stream = _controller.stream; |
| 420 // Throw an ArgumentError if any field is invalid. After this, all | 412 // Throw an ArgumentError if any field is invalid. After this, all |
| 421 // errors will be reported through the future or the stream. | 413 // errors will be reported through the future or the stream. |
| 422 _verifyFields(); | 414 _verifyFields(); |
| 423 _secureFilter.init(); | 415 _secureFilter.init(); |
| 424 if (_carryOverData != null) _readFromCarryOver(); | 416 if (_carryOverData != null) _readFromCarryOver(); |
| 425 _secureFilter.registerHandshakeCompleteCallback( | 417 _secureFilter.registerHandshakeCompleteCallback( |
| 426 _secureHandshakeCompleteHandler); | 418 _secureHandshakeCompleteHandler); |
| 427 if (onBadCertificate != null) { | 419 if (onBadCertificate != null) { |
| 428 _secureFilter.registerBadCertificateCallback(onBadCertificate); | 420 _secureFilter.registerBadCertificateCallback(onBadCertificate); |
| 429 } | 421 } |
| 430 var futureSocket; | 422 var futureSocket; |
| 431 if (socket == null) { | 423 if (socket == null) { |
| 432 futureSocket = RawSocket.connect(address, requestedPort); | 424 futureSocket = RawSocket.connect(host, requestedPort); |
| 433 } else { | 425 } else { |
| 434 futureSocket = new Future.value(socket); | 426 futureSocket = new Future.value(socket); |
| 435 } | 427 } |
| 436 futureSocket.then((rawSocket) { | 428 futureSocket.then((rawSocket) { |
| 437 _socket = rawSocket; | 429 _socket = rawSocket; |
| 438 _socket.readEventsEnabled = true; | 430 _socket.readEventsEnabled = true; |
| 439 _socket.writeEventsEnabled = false; | 431 _socket.writeEventsEnabled = false; |
| 440 if (_socketSubscription == null) { | 432 if (_socketSubscription == null) { |
| 441 // If a current subscription is provided use this otherwise | 433 // If a current subscription is provided use this otherwise |
| 442 // create a new one. | 434 // create a new one. |
| 443 _socketSubscription = _socket.listen(_eventDispatcher, | 435 _socketSubscription = _socket.listen(_eventDispatcher, |
| 444 onError: _errorHandler, | 436 onError: _errorHandler, |
| 445 onDone: _doneHandler); | 437 onDone: _doneHandler); |
| 446 } else { | 438 } else { |
| 447 _socketSubscription.onData(_eventDispatcher); | 439 _socketSubscription.onData(_eventDispatcher); |
| 448 _socketSubscription.onError(_errorHandler); | 440 _socketSubscription.onError(_errorHandler); |
| 449 _socketSubscription.onDone(_doneHandler); | 441 _socketSubscription.onDone(_doneHandler); |
| 450 } | 442 } |
| 451 _connectPending = true; | 443 _connectPending = true; |
| 452 _secureFilter.connect(rawSocket.address.host, | 444 _secureFilter.connect(host, |
| 453 port, | 445 port, |
| 454 is_server, | 446 is_server, |
| 455 certificateName, | 447 certificateName, |
| 456 requestClientCertificate || | 448 requestClientCertificate || |
| 457 requireClientCertificate, | 449 requireClientCertificate, |
| 458 requireClientCertificate, | 450 requireClientCertificate, |
| 459 sendClientCertificate); | 451 sendClientCertificate); |
| 460 _status = HANDSHAKE; | 452 _status = HANDSHAKE; |
| 461 _secureHandshake(); | 453 _secureHandshake(); |
| 462 }) | 454 }) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 476 } | 468 } |
| 477 return _stream.listen(onData, | 469 return _stream.listen(onData, |
| 478 onError: onError, | 470 onError: onError, |
| 479 onDone: onDone, | 471 onDone: onDone, |
| 480 cancelOnError: cancelOnError); | 472 cancelOnError: cancelOnError); |
| 481 } | 473 } |
| 482 | 474 |
| 483 void _verifyFields() { | 475 void _verifyFields() { |
| 484 assert(is_server is bool); | 476 assert(is_server is bool); |
| 485 assert(_socket == null || _socket is RawSocket); | 477 assert(_socket == null || _socket is RawSocket); |
| 486 if (address is! InternetAddress) { | 478 if (host is! String) { |
| 487 throw new ArgumentError( | 479 throw new ArgumentError( |
| 488 "RawSecureSocket constructor: host is not an InternetAddress"); | 480 "RawSecureSocket constructor: host is not a String"); |
| 489 } | 481 } |
| 490 if (certificateName != null && certificateName is! String) { | 482 if (certificateName != null && certificateName is! String) { |
| 491 throw new ArgumentError("certificateName is not null or a String"); | 483 throw new ArgumentError("certificateName is not null or a String"); |
| 492 } | 484 } |
| 493 if (certificateName == null && is_server) { | 485 if (certificateName == null && is_server) { |
| 494 throw new ArgumentError("certificateName is null on a server"); | 486 throw new ArgumentError("certificateName is null on a server"); |
| 495 } | 487 } |
| 496 if (requestClientCertificate is! bool) { | 488 if (requestClientCertificate is! bool) { |
| 497 throw new ArgumentError("requestClientCertificate is not a bool"); | 489 throw new ArgumentError("requestClientCertificate is not a bool"); |
| 498 } | 490 } |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 void destroy(); | 945 void destroy(); |
| 954 void handshake(); | 946 void handshake(); |
| 955 void init(); | 947 void init(); |
| 956 X509Certificate get peerCertificate; | 948 X509Certificate get peerCertificate; |
| 957 int processBuffer(int bufferIndex); | 949 int processBuffer(int bufferIndex); |
| 958 void registerBadCertificateCallback(Function callback); | 950 void registerBadCertificateCallback(Function callback); |
| 959 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); | 951 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); |
| 960 | 952 |
| 961 List<_ExternalBuffer> get buffers; | 953 List<_ExternalBuffer> get buffers; |
| 962 } | 954 } |
| OLD | NEW |