Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Unified Diff: sdk/lib/io/secure_socket.dart

Issue 13502004: Add the ability to secure an already established raw socket connection (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/socket_patch.dart ('k') | sdk/lib/io/socket.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/secure_socket.dart
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 41fdf59a81d0a1c8e77f8432e5a925d4c7978167..f23f267cc9f052e618d55e8d175b90160352bcd5 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -144,6 +144,78 @@ abstract class RawSecureSocket implements RawSocket {
}
/**
+ * Takes an already connected [socket] and starts client side TLS
+ * handshake to make the communication secure. When the returned
+ * future completes the [RawSecureSocket] has completed the TLS
+ * handshake. Using this function requires that the other end of the
+ * connection is prepared for TLS handshake.
+ *
+ * If the [socket] already has a subscription, pass the existing
+ * subscription in the [subscription] parameter. The secure socket
+ * will take over the subscription and process any subsequent
+ * events.
+ *
+ * See [connect] for more information on the arguments.
+ *
+ */
+ static Future<RawSecureSocket> secure(
+ RawSocket socket,
+ {StreamSubscription subscription,
+ bool sendClientCertificate: false,
+ String certificateName,
+ bool onBadCertificate(X509Certificate certificate)}) {
+ return _RawSecureSocket.connect(
+ socket.host,
+ socket.port,
+ certificateName,
+ is_server: false,
+ socket: socket,
+ subscription: subscription,
+ sendClientCertificate: sendClientCertificate,
+ onBadCertificate: onBadCertificate);
+ }
+
+ /**
+ * Takes an already connected [socket] and starts server side TLS
+ * handshake to make the communication secure. When the returned
+ * future completes the [RawSecureSocket] has completed the TLS
+ * handshake. Using this function requires that the other end of the
+ * connection is going to start the TLS handshake.
+ *
+ * If the [socket] already has a subscription, pass the existing
+ * subscription in the [subscription] parameter. The secure socket
+ * will take over the subscription and process any subsequent
+ * events.
+ *
+ * If some of the data of the TLS handshake has already been read
+ * from the socket this data can be passed in the [carryOverData]
+ * parameter. This data will be processed before any other data
+ * available on the socket.
+ *
+ * See [RawSecureServerSocket.bind] for more information on the
+ * arguments.
+ *
+ */
+ static Future<RawSecureSocket> secureServer(
+ RawSocket socket,
+ String certificateName,
+ {StreamSubscription subscription,
+ List<int> carryOverData,
+ bool requestClientCertificate: false,
+ bool requireClientCertificate: false}) {
+ return _RawSecureSocket.connect(
+ socket.remoteHost,
+ socket.remotePort,
+ certificateName,
+ is_server: true,
+ socket: socket,
+ subscription: subscription,
+ carryOverData: carryOverData,
+ requestClientCertificate: requestClientCertificate,
+ requireClientCertificate: requireClientCertificate);
+ }
+
+ /**
* Get the peer certificate for a connected RawSecureSocket. If this
* RawSecureSocket is the server end of a secure socket connection,
* [peerCertificate] will return the client certificate, or null, if no
@@ -192,6 +264,8 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
StreamController<RawSocketEvent> _controller;
Stream<RawSocketEvent> _stream;
StreamSubscription<RawSocketEvent> _socketSubscription;
+ List<int> _carryOverData;
+ int _carryOverDataIndex = 0;
final String host;
final bool is_server;
final String certificateName;
@@ -218,6 +292,8 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
String certificateName,
{bool is_server,
RawSocket socket,
+ StreamSubscription subscription,
+ List<int> carryOverData,
bool requestClientCertificate: false,
bool requireClientCertificate: false,
bool sendClientCertificate: false,
@@ -227,6 +303,8 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
certificateName,
is_server,
socket,
+ subscription,
+ carryOverData,
requestClientCertificate,
requireClientCertificate,
sendClientCertificate,
@@ -240,6 +318,8 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
String this.certificateName,
bool this.is_server,
RawSocket socket,
+ StreamSubscription this._socketSubscription,
+ List<int> this._carryOverData,
bool this.requestClientCertificate,
bool this.requireClientCertificate,
bool this.sendClientCertificate,
@@ -252,6 +332,7 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
// errors will be reported through the future or the stream.
_verifyFields();
_secureFilter.init();
+ if (_carryOverData != null) _readFromCarryOver();
_secureFilter.registerHandshakeCompleteCallback(
_secureHandshakeCompleteHandler);
if (onBadCertificate != null) {
@@ -266,9 +347,17 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
futureSocket.then((rawSocket) {
rawSocket.writeEventsEnabled = false;
_socket = rawSocket;
- _socketSubscription = _socket.listen(_eventDispatcher,
- onError: _errorHandler,
- onDone: _doneHandler);
+ if (_socketSubscription == null) {
+ // If a current subscription is provided use this otherwise
+ // create a new one.
+ _socketSubscription = _socket.listen(_eventDispatcher,
+ onError: _errorHandler,
+ onDone: _doneHandler);
+ } else {
+ _socketSubscription.onData(_eventDispatcher);
+ _socketSubscription.onError(_errorHandler);
+ _socketSubscription.onDone(_doneHandler);
+ }
_connectPending = true;
_secureFilter.connect(host,
port,
@@ -520,6 +609,21 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
}
}
+ void _readFromCarryOver() {
+ assert(_carryOverData != null);
+ var encrypted = _secureFilter.buffers[READ_ENCRYPTED];
+ var len = 1;//_carryOverData.length - _carryOverDataIndex;
+ encrypted.data.setRange(encrypted.start + encrypted.length,
+ len,
+ _carryOverData,
+ _carryOverDataIndex);
+ encrypted.length = len;
+ _carryOverDataIndex += len;
+ if (_carryOverData.length == _carryOverDataIndex) {
+ _carryOverData = null;
+ }
+ }
+
void _readHandler() {
if (_status == CLOSED) {
return;
@@ -657,14 +761,19 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
}
}
if (!_socketClosedRead && encrypted.free > 0) {
- List<int> data = _socket.read(encrypted.free);
- if (data != null) {
- int bytes = data.length;
- encrypted.data.setRange(encrypted.start + encrypted.length,
- bytes,
- data);
- encrypted.length += bytes;
+ if (_carryOverData != null) {
+ _readFromCarryOver();
progress = true;
+ } else {
+ List<int> data = _socket.read(encrypted.free);
+ if (data != null) {
+ int bytes = data.length;
+ encrypted.data.setRange(encrypted.start + encrypted.length,
+ bytes,
+ data);
+ encrypted.length += bytes;
+ progress = true;
+ }
}
}
}
« no previous file with comments | « runtime/bin/socket_patch.dart ('k') | sdk/lib/io/socket.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698