| 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 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 requestClientCertificate || | 547 requestClientCertificate || |
| 548 requireClientCertificate, | 548 requireClientCertificate, |
| 549 requireClientCertificate, | 549 requireClientCertificate, |
| 550 sendClientCertificate); | 550 sendClientCertificate); |
| 551 _secureHandshake(); | 551 _secureHandshake(); |
| 552 }) | 552 }) |
| 553 .catchError(_reportError); | 553 .catchError(_reportError); |
| 554 } | 554 } |
| 555 | 555 |
| 556 StreamSubscription listen(void onData(RawSocketEvent data), | 556 StreamSubscription listen(void onData(RawSocketEvent data), |
| 557 {void onError(error), | 557 {Function onError, |
| 558 void onDone(), | 558 void onDone(), |
| 559 bool cancelOnError}) { | 559 bool cancelOnError}) { |
| 560 _sendWriteEvent(); | 560 _sendWriteEvent(); |
| 561 return _stream.listen(onData, | 561 return _stream.listen(onData, |
| 562 onError: onError, | 562 onError: onError, |
| 563 onDone: onDone, | 563 onDone: onDone, |
| 564 cancelOnError: cancelOnError); | 564 cancelOnError: cancelOnError); |
| 565 } | 565 } |
| 566 | 566 |
| 567 static void _verifyFields(host, | 567 static void _verifyFields(host, |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 | 741 |
| 742 void _eventDispatcher(RawSocketEvent event) { | 742 void _eventDispatcher(RawSocketEvent event) { |
| 743 try { | 743 try { |
| 744 if (event == RawSocketEvent.READ) { | 744 if (event == RawSocketEvent.READ) { |
| 745 _readHandler(); | 745 _readHandler(); |
| 746 } else if (event == RawSocketEvent.WRITE) { | 746 } else if (event == RawSocketEvent.WRITE) { |
| 747 _writeHandler(); | 747 _writeHandler(); |
| 748 } else if (event == RawSocketEvent.READ_CLOSED) { | 748 } else if (event == RawSocketEvent.READ_CLOSED) { |
| 749 _closeHandler(); | 749 _closeHandler(); |
| 750 } | 750 } |
| 751 } catch (e) { | 751 } catch (e, stackTrace) { |
| 752 _reportError(e); | 752 _reportError(e, stackTrace); |
| 753 } | 753 } |
| 754 } | 754 } |
| 755 | 755 |
| 756 void _readHandler() { | 756 void _readHandler() { |
| 757 _readSocket(); | 757 _readSocket(); |
| 758 _scheduleFilter(); | 758 _scheduleFilter(); |
| 759 } | 759 } |
| 760 | 760 |
| 761 void _writeHandler() { | 761 void _writeHandler() { |
| 762 _writeSocket(); | 762 _writeSocket(); |
| 763 _scheduleFilter(); | 763 _scheduleFilter(); |
| 764 } | 764 } |
| 765 | 765 |
| 766 void _doneHandler() { | 766 void _doneHandler() { |
| 767 if (_filterStatus.readEmpty) { | 767 if (_filterStatus.readEmpty) { |
| 768 _close(); | 768 _close(); |
| 769 } | 769 } |
| 770 } | 770 } |
| 771 | 771 |
| 772 void _reportError(e) { | 772 void _reportError(e, [StackTrace stackTrace]) { |
| 773 if (_status == CLOSED) { | 773 if (_status == CLOSED) { |
| 774 return; | 774 return; |
| 775 } else if (_connectPending) { | 775 } else if (_connectPending) { |
| 776 // _connectPending is true until the handshake has completed, and the | 776 // _connectPending is true until the handshake has completed, and the |
| 777 // _handshakeComplete future returned from SecureSocket.connect has | 777 // _handshakeComplete future returned from SecureSocket.connect has |
| 778 // completed. Before this point, we must complete it with an error. | 778 // completed. Before this point, we must complete it with an error. |
| 779 _handshakeComplete.completeError(e); | 779 _handshakeComplete.completeError(e, stackTrace); |
| 780 } else { | 780 } else { |
| 781 _controller.addError(e); | 781 _controller.addError(e, stackTrace); |
| 782 } | 782 } |
| 783 _close(); | 783 _close(); |
| 784 } | 784 } |
| 785 | 785 |
| 786 void _closeHandler() { | 786 void _closeHandler() { |
| 787 if (_status == CONNECTED) { | 787 if (_status == CONNECTED) { |
| 788 if (_closedRead) return; | 788 if (_closedRead) return; |
| 789 _socketClosedRead = true; | 789 _socketClosedRead = true; |
| 790 if (_filterStatus.readEmpty) { | 790 if (_filterStatus.readEmpty) { |
| 791 _closedRead = true; | 791 _closedRead = true; |
| 792 _controller.add(RawSocketEvent.READ_CLOSED); | 792 _controller.add(RawSocketEvent.READ_CLOSED); |
| 793 if (_socketClosedWrite) { | 793 if (_socketClosedWrite) { |
| 794 _close(); | 794 _close(); |
| 795 } | 795 } |
| 796 } else { | 796 } else { |
| 797 _scheduleFilter(); | 797 _scheduleFilter(); |
| 798 } | 798 } |
| 799 } else if (_status == HANDSHAKE) { | 799 } else if (_status == HANDSHAKE) { |
| 800 _socketClosedRead = true; | 800 _socketClosedRead = true; |
| 801 if (_filterStatus.readEmpty) { | 801 if (_filterStatus.readEmpty) { |
| 802 _reportError( | 802 _reportError( |
| 803 new HandshakeException('Connection terminated during handshake')); | 803 new HandshakeException('Connection terminated during handshake'), |
| 804 null); |
| 804 } else { | 805 } else { |
| 805 _secureHandshake(); | 806 _secureHandshake(); |
| 806 } | 807 } |
| 807 } | 808 } |
| 808 } | 809 } |
| 809 | 810 |
| 810 void _secureHandshake() { | 811 void _secureHandshake() { |
| 811 try { | 812 try { |
| 812 _secureFilter.handshake(); | 813 _secureFilter.handshake(); |
| 813 _filterStatus.writeEmpty = false; | 814 _filterStatus.writeEmpty = false; |
| 814 _readSocket(); | 815 _readSocket(); |
| 815 _writeSocket(); | 816 _writeSocket(); |
| 816 _scheduleFilter(); | 817 _scheduleFilter(); |
| 817 } catch (e) { | 818 } catch (e, stackTrace) { |
| 818 _reportError(e); | 819 _reportError(e, stackTrace); |
| 819 } | 820 } |
| 820 } | 821 } |
| 821 | 822 |
| 822 void renegotiate({bool useSessionCache: true, | 823 void renegotiate({bool useSessionCache: true, |
| 823 bool requestClientCertificate: false, | 824 bool requestClientCertificate: false, |
| 824 bool requireClientCertificate: false}) { | 825 bool requireClientCertificate: false}) { |
| 825 if (_status != CONNECTED) { | 826 if (_status != CONNECTED) { |
| 826 throw new HandshakeException( | 827 throw new HandshakeException( |
| 827 "Called renegotiate on a non-connected socket"); | 828 "Called renegotiate on a non-connected socket"); |
| 828 } | 829 } |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 args[0] = _filterPointer; | 993 args[0] = _filterPointer; |
| 993 args[1] = wasInHandshake; | 994 args[1] = wasInHandshake; |
| 994 var bufs = _secureFilter.buffers; | 995 var bufs = _secureFilter.buffers; |
| 995 for (var i = 0; i < NUM_BUFFERS; ++i) { | 996 for (var i = 0; i < NUM_BUFFERS; ++i) { |
| 996 args[2 * i + 2] = bufs[i].start; | 997 args[2 * i + 2] = bufs[i].start; |
| 997 args[2 * i + 3] = bufs[i].end; | 998 args[2 * i + 3] = bufs[i].end; |
| 998 } | 999 } |
| 999 | 1000 |
| 1000 return _IOService.dispatch(_SSL_PROCESS_FILTER, args).then((response) { | 1001 return _IOService.dispatch(_SSL_PROCESS_FILTER, args).then((response) { |
| 1001 if (response.length == 2) { | 1002 if (response.length == 2) { |
| 1002 _reportError(new TlsException('${response[1]} error ${response[0]}')); | 1003 _reportError(new TlsException('${response[1]} error ${response[0]}'), |
| 1004 null); |
| 1003 } | 1005 } |
| 1004 int start(int index) => response[2 * index]; | 1006 int start(int index) => response[2 * index]; |
| 1005 int end(int index) => response[2 * index + 1]; | 1007 int end(int index) => response[2 * index + 1]; |
| 1006 | 1008 |
| 1007 _FilterStatus status = new _FilterStatus(); | 1009 _FilterStatus status = new _FilterStatus(); |
| 1008 // Compute writeEmpty as "write plaintext buffer and write encrypted | 1010 // Compute writeEmpty as "write plaintext buffer and write encrypted |
| 1009 // buffer were empty when we started and are empty now". | 1011 // buffer were empty when we started and are empty now". |
| 1010 status.writeEmpty = bufs[WRITE_PLAINTEXT].isEmpty && | 1012 status.writeEmpty = bufs[WRITE_PLAINTEXT].isEmpty && |
| 1011 start(WRITE_ENCRYPTED) == end(WRITE_ENCRYPTED); | 1013 start(WRITE_ENCRYPTED) == end(WRITE_ENCRYPTED); |
| 1012 // If we were in handshake when this started, _writeEmpty may be false | 1014 // If we were in handshake when this started, _writeEmpty may be false |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 /** | 1266 /** |
| 1265 * An exception that happens in the handshake phase of establishing | 1267 * An exception that happens in the handshake phase of establishing |
| 1266 * a secure network connection, when looking up or verifying a | 1268 * a secure network connection, when looking up or verifying a |
| 1267 * certificate. | 1269 * certificate. |
| 1268 */ | 1270 */ |
| 1269 class CertificateException extends TlsException { | 1271 class CertificateException extends TlsException { |
| 1270 const CertificateException([String message = "", | 1272 const CertificateException([String message = "", |
| 1271 OSError osError = null]) | 1273 OSError osError = null]) |
| 1272 : super._("CertificateException", message, osError); | 1274 : super._("CertificateException", message, osError); |
| 1273 } | 1275 } |
| OLD | NEW |