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 |