| 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 port, | 251 port, |
| 252 certificateName, | 252 certificateName, |
| 253 false, | 253 false, |
| 254 false, | 254 false, |
| 255 false, | 255 false, |
| 256 sendClientCertificate, | 256 sendClientCertificate, |
| 257 onBadCertificate); | 257 onBadCertificate); |
| 258 return RawSocket.connect(host, port) | 258 return RawSocket.connect(host, port) |
| 259 .then((socket) { | 259 .then((socket) { |
| 260 return secure(socket, | 260 return secure(socket, |
| 261 host: host, | |
| 262 sendClientCertificate: sendClientCertificate, | 261 sendClientCertificate: sendClientCertificate, |
| 263 certificateName: certificateName, | 262 certificateName: certificateName, |
| 264 onBadCertificate: onBadCertificate); | 263 onBadCertificate: onBadCertificate); |
| 265 }); | 264 }); |
| 266 } | 265 } |
| 267 | 266 |
| 268 /** | 267 /** |
| 269 * Takes an already connected [socket] and starts client side TLS | 268 * Takes an already connected [socket] and starts client side TLS |
| 270 * handshake to make the communication secure. When the returned | 269 * handshake to make the communication secure. When the returned |
| 271 * future completes the [RawSecureSocket] has completed the TLS | 270 * future completes the [RawSecureSocket] has completed the TLS |
| (...skipping 24 matching lines...) Expand all Loading... |
| 296 static Future<RawSecureSocket> secure( | 295 static Future<RawSecureSocket> secure( |
| 297 RawSocket socket, | 296 RawSocket socket, |
| 298 {StreamSubscription subscription, | 297 {StreamSubscription subscription, |
| 299 host, | 298 host, |
| 300 bool sendClientCertificate: false, | 299 bool sendClientCertificate: false, |
| 301 String certificateName, | 300 String certificateName, |
| 302 bool onBadCertificate(X509Certificate certificate)}) { | 301 bool onBadCertificate(X509Certificate certificate)}) { |
| 303 socket.readEventsEnabled = false; | 302 socket.readEventsEnabled = false; |
| 304 socket.writeEventsEnabled = false; | 303 socket.writeEventsEnabled = false; |
| 305 return _RawSecureSocket.connect( | 304 return _RawSecureSocket.connect( |
| 306 host != null ? host : socket.address, | 305 host != null ? host : socket.address.host, |
| 307 socket.port, | 306 socket.port, |
| 308 certificateName, | 307 certificateName, |
| 309 is_server: false, | 308 is_server: false, |
| 310 socket: socket, | 309 socket: socket, |
| 311 subscription: subscription, | 310 subscription: subscription, |
| 312 sendClientCertificate: sendClientCertificate, | 311 sendClientCertificate: sendClientCertificate, |
| 313 onBadCertificate: onBadCertificate); | 312 onBadCertificate: onBadCertificate); |
| 314 } | 313 } |
| 315 | 314 |
| 316 /** | 315 /** |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 int requestedPort, | 465 int requestedPort, |
| 467 String certificateName, | 466 String certificateName, |
| 468 {bool is_server, | 467 {bool is_server, |
| 469 RawSocket socket, | 468 RawSocket socket, |
| 470 StreamSubscription subscription, | 469 StreamSubscription subscription, |
| 471 List<int> bufferedData, | 470 List<int> bufferedData, |
| 472 bool requestClientCertificate: false, | 471 bool requestClientCertificate: false, |
| 473 bool requireClientCertificate: false, | 472 bool requireClientCertificate: false, |
| 474 bool sendClientCertificate: false, | 473 bool sendClientCertificate: false, |
| 475 bool onBadCertificate(X509Certificate certificate)}) { | 474 bool onBadCertificate(X509Certificate certificate)}) { |
| 476 var future; | |
| 477 _verifyFields(host, requestedPort, certificateName, is_server, | 475 _verifyFields(host, requestedPort, certificateName, is_server, |
| 478 requestClientCertificate, requireClientCertificate, | 476 requestClientCertificate, requireClientCertificate, |
| 479 sendClientCertificate, onBadCertificate); | 477 sendClientCertificate, onBadCertificate); |
| 480 if (host is String) { | 478 if (host is InternetAddress) host = host.host; |
| 481 if (socket != null) { | 479 var address = socket.address; |
| 482 future = new Future.value( | 480 if (host != null) address = address._cloneWithNewHost(host); |
| 483 (socket.address as dynamic)._cloneWithNewHost(host)); | 481 return new _RawSecureSocket(address, |
| 484 } else { | 482 requestedPort, |
| 485 future = InternetAddress.lookup(host).then((addrs) => addrs.first); | 483 certificateName, |
| 486 } | 484 is_server, |
| 487 } else { | 485 socket, |
| 488 future = new Future.value(host); | 486 subscription, |
| 489 } | 487 bufferedData, |
| 490 return future.then((addr) { | 488 requestClientCertificate, |
| 491 return new _RawSecureSocket(addr, | 489 requireClientCertificate, |
| 492 requestedPort, | 490 sendClientCertificate, |
| 493 certificateName, | 491 onBadCertificate) |
| 494 is_server, | 492 ._handshakeComplete.future; |
| 495 socket, | |
| 496 subscription, | |
| 497 bufferedData, | |
| 498 requestClientCertificate, | |
| 499 requireClientCertificate, | |
| 500 sendClientCertificate, | |
| 501 onBadCertificate) | |
| 502 ._handshakeComplete.future; | |
| 503 }); | |
| 504 } | 493 } |
| 505 | 494 |
| 506 _RawSecureSocket( | 495 _RawSecureSocket( |
| 507 this.address, | 496 this.address, |
| 508 int requestedPort, | 497 int requestedPort, |
| 509 this.certificateName, | 498 this.certificateName, |
| 510 this.is_server, | 499 this.is_server, |
| 511 RawSocket socket, | 500 RawSocket this._socket, |
| 512 this._socketSubscription, | 501 this._socketSubscription, |
| 513 this._bufferedData, | 502 this._bufferedData, |
| 514 this.requestClientCertificate, | 503 this.requestClientCertificate, |
| 515 this.requireClientCertificate, | 504 this.requireClientCertificate, |
| 516 this.sendClientCertificate, | 505 this.sendClientCertificate, |
| 517 this.onBadCertificate(X509Certificate certificate)) { | 506 this.onBadCertificate(X509Certificate certificate)) { |
| 518 _controller = new StreamController<RawSocketEvent>( | 507 _controller = new StreamController<RawSocketEvent>( |
| 519 sync: true, | 508 sync: true, |
| 520 onListen: _onSubscriptionStateChange, | 509 onListen: _onSubscriptionStateChange, |
| 521 onPause: _onPauseStateChange, | 510 onPause: _onPauseStateChange, |
| 522 onResume: _onPauseStateChange, | 511 onResume: _onPauseStateChange, |
| 523 onCancel: _onSubscriptionStateChange); | 512 onCancel: _onSubscriptionStateChange); |
| 524 _stream = _controller.stream; | 513 _stream = _controller.stream; |
| 525 // Throw an ArgumentError if any field is invalid. After this, all | 514 // Throw an ArgumentError if any field is invalid. After this, all |
| 526 // errors will be reported through the future or the stream. | 515 // errors will be reported through the future or the stream. |
| 527 _secureFilter.init(); | 516 _secureFilter.init(); |
| 528 _filterPointer = _secureFilter._pointer(); | 517 _filterPointer = _secureFilter._pointer(); |
| 529 _secureFilter.registerHandshakeCompleteCallback( | 518 _secureFilter.registerHandshakeCompleteCallback( |
| 530 _secureHandshakeCompleteHandler); | 519 _secureHandshakeCompleteHandler); |
| 531 if (onBadCertificate != null) { | 520 if (onBadCertificate != null) { |
| 532 _secureFilter.registerBadCertificateCallback(_onBadCertificateWrapper); | 521 _secureFilter.registerBadCertificateCallback(_onBadCertificateWrapper); |
| 533 } | 522 } |
| 534 var futureSocket; | 523 _socket.readEventsEnabled = true; |
| 535 if (socket == null) { | 524 _socket.writeEventsEnabled = false; |
| 536 futureSocket = RawSocket.connect(address, requestedPort); | 525 if (_socketSubscription == null) { |
| 526 // If a current subscription is provided use this otherwise |
| 527 // create a new one. |
| 528 _socketSubscription = _socket.listen(_eventDispatcher, |
| 529 onError: _reportError, |
| 530 onDone: _doneHandler); |
| 537 } else { | 531 } else { |
| 538 futureSocket = new Future.value(socket); | 532 if (_socketSubscription.isPaused) { |
| 533 _socket.close(); |
| 534 throw new ArgumentError( |
| 535 "Subscription passed to TLS upgrade is paused"); |
| 536 } |
| 537 _socketSubscription |
| 538 ..onData(_eventDispatcher) |
| 539 ..onError(_reportError) |
| 540 ..onDone(_doneHandler); |
| 539 } | 541 } |
| 540 futureSocket.then((rawSocket) { | 542 try { |
| 541 _socket = rawSocket; | |
| 542 _socket.readEventsEnabled = true; | |
| 543 _socket.writeEventsEnabled = false; | |
| 544 if (_socketSubscription == null) { | |
| 545 // If a current subscription is provided use this otherwise | |
| 546 // create a new one. | |
| 547 _socketSubscription = _socket.listen(_eventDispatcher, | |
| 548 onError: _reportError, | |
| 549 onDone: _doneHandler); | |
| 550 } else { | |
| 551 if (_socketSubscription.isPaused) { | |
| 552 throw new StateError("Subscription passed to TLS upgrade is paused"); | |
| 553 } | |
| 554 _socketSubscription | |
| 555 ..onData(_eventDispatcher) | |
| 556 ..onError(_reportError) | |
| 557 ..onDone(_doneHandler); | |
| 558 } | |
| 559 _secureFilter.connect(address.host, | 543 _secureFilter.connect(address.host, |
| 560 (address as dynamic)._in_addr, | 544 (address as dynamic)._in_addr, |
| 561 port, | 545 port, |
| 562 is_server, | 546 is_server, |
| 563 certificateName, | 547 certificateName, |
| 564 requestClientCertificate || | 548 requestClientCertificate || |
| 565 requireClientCertificate, | 549 requireClientCertificate, |
| 566 requireClientCertificate, | 550 requireClientCertificate, |
| 567 sendClientCertificate); | 551 sendClientCertificate); |
| 568 _secureHandshake(); | 552 _secureHandshake(); |
| 569 }) | 553 } catch (e, s) { |
| 570 .catchError(_reportError); | 554 _reportError(e, s); |
| 555 } |
| 571 } | 556 } |
| 572 | 557 |
| 573 StreamSubscription listen(void onData(RawSocketEvent data), | 558 StreamSubscription listen(void onData(RawSocketEvent data), |
| 574 {Function onError, | 559 {Function onError, |
| 575 void onDone(), | 560 void onDone(), |
| 576 bool cancelOnError}) { | 561 bool cancelOnError}) { |
| 577 _sendWriteEvent(); | 562 _sendWriteEvent(); |
| 578 return _stream.listen(onData, | 563 return _stream.listen(onData, |
| 579 onError: onError, | 564 onError: onError, |
| 580 onDone: onDone, | 565 onDone: onDone, |
| (...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 /** | 1263 /** |
| 1279 * An exception that happens in the handshake phase of establishing | 1264 * An exception that happens in the handshake phase of establishing |
| 1280 * a secure network connection, when looking up or verifying a | 1265 * a secure network connection, when looking up or verifying a |
| 1281 * certificate. | 1266 * certificate. |
| 1282 */ | 1267 */ |
| 1283 class CertificateException extends TlsException { | 1268 class CertificateException extends TlsException { |
| 1284 const CertificateException([String message = "", | 1269 const CertificateException([String message = "", |
| 1285 OSError osError = null]) | 1270 OSError osError = null]) |
| 1286 : super._("CertificateException", message, osError); | 1271 : super._("CertificateException", message, osError); |
| 1287 } | 1272 } |
| OLD | NEW |