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

Side by Side Diff: sdk/lib/io/secure_socket.dart

Issue 2754013002: Format all dart: library files (Closed)
Patch Set: Format all dart: library files Created 3 years, 9 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 unified diff | Download patch
« no previous file with comments | « sdk/lib/io/secure_server_socket.dart ('k') | sdk/lib/io/security_context.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11 matching lines...) Expand all
22 * using the trusted certificates set in the SecurityContext object. 22 * using the trusted certificates set in the SecurityContext object.
23 * The default SecurityContext object contains a built-in set of trusted 23 * The default SecurityContext object contains a built-in set of trusted
24 * root certificates for well-known certificate authorities. 24 * root certificates for well-known certificate authorities.
25 * 25 *
26 * [onBadCertificate] is an optional handler for unverifiable certificates. 26 * [onBadCertificate] is an optional handler for unverifiable certificates.
27 * The handler receives the [X509Certificate], and can inspect it and 27 * The handler receives the [X509Certificate], and can inspect it and
28 * decide (or let the user decide) whether to accept 28 * decide (or let the user decide) whether to accept
29 * the connection or not. The handler should return true 29 * the connection or not. The handler should return true
30 * to continue the [SecureSocket] connection. 30 * to continue the [SecureSocket] connection.
31 */ 31 */
32 static Future<SecureSocket> connect( 32 static Future<SecureSocket> connect(host, int port,
33 host,
34 int port,
35 {SecurityContext context, 33 {SecurityContext context,
36 bool onBadCertificate(X509Certificate certificate), 34 bool onBadCertificate(X509Certificate certificate),
37 List<String> supportedProtocols}) { 35 List<String> supportedProtocols}) {
38 return RawSecureSocket.connect(host, 36 return RawSecureSocket
39 port, 37 .connect(host, port,
40 context: context, 38 context: context,
41 onBadCertificate: onBadCertificate, 39 onBadCertificate: onBadCertificate,
42 supportedProtocols: supportedProtocols) 40 supportedProtocols: supportedProtocols)
43 .then((rawSocket) => new SecureSocket._(rawSocket)); 41 .then((rawSocket) => new SecureSocket._(rawSocket));
44 } 42 }
45 43
46 /** 44 /**
47 * Takes an already connected [socket] and starts client side TLS 45 * Takes an already connected [socket] and starts client side TLS
48 * handshake to make the communication secure. When the returned 46 * handshake to make the communication secure. When the returned
49 * future completes the [SecureSocket] has completed the TLS 47 * future completes the [SecureSocket] has completed the TLS
50 * handshake. Using this function requires that the other end of the 48 * handshake. Using this function requires that the other end of the
51 * connection is prepared for TLS handshake. 49 * connection is prepared for TLS handshake.
52 * 50 *
53 * If the [socket] already has a subscription, this subscription 51 * If the [socket] already has a subscription, this subscription
54 * will no longer receive and events. In most cases calling 52 * will no longer receive and events. In most cases calling
55 * `pause` on this subscription before starting TLS handshake is 53 * `pause` on this subscription before starting TLS handshake is
56 * the right thing to do. 54 * the right thing to do.
57 * 55 *
58 * If the [host] argument is passed it will be used as the host name 56 * If the [host] argument is passed it will be used as the host name
59 * for the TLS handshake. If [host] is not passed the host name from 57 * for the TLS handshake. If [host] is not passed the host name from
60 * the [socket] will be used. The [host] can be either a [String] or 58 * the [socket] will be used. The [host] can be either a [String] or
61 * an [InternetAddress]. 59 * an [InternetAddress].
62 * 60 *
63 * Calling this function will _not_ cause a DNS host lookup. If the 61 * Calling this function will _not_ cause a DNS host lookup. If the
64 * [host] passed is a [String] the [InternetAddress] for the 62 * [host] passed is a [String] the [InternetAddress] for the
65 * resulting [SecureSocket] will have the passed in [host] as its 63 * resulting [SecureSocket] will have the passed in [host] as its
66 * host value and the internet address of the already connected 64 * host value and the internet address of the already connected
67 * socket as its address value. 65 * socket as its address value.
68 * 66 *
69 * See [connect] for more information on the arguments. 67 * See [connect] for more information on the arguments.
70 * 68 *
71 */ 69 */
72 static Future<SecureSocket> secure( 70 static Future<SecureSocket> secure(Socket socket,
73 Socket socket,
74 {host, 71 {host,
75 SecurityContext context, 72 SecurityContext context,
76 bool onBadCertificate(X509Certificate certificate)}) { 73 bool onBadCertificate(X509Certificate certificate)}) {
77 return ((socket as dynamic/*_Socket*/)._detachRaw() as Future) 74 return ((socket as dynamic /*_Socket*/)._detachRaw() as Future)
78 .then<RawSecureSocket>((detachedRaw) { 75 .then<RawSecureSocket>((detachedRaw) {
79 return RawSecureSocket.secure( 76 return RawSecureSocket.secure(detachedRaw[0] as RawSocket,
80 detachedRaw[0] as RawSocket, 77 subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>,
81 subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>, 78 host: host,
82 host: host, 79 context: context,
83 context: context, 80 onBadCertificate: onBadCertificate);
84 onBadCertificate: onBadCertificate); 81 }).then<SecureSocket>((raw) => new SecureSocket._(raw));
85 }) 82 }
86 .then<SecureSocket>((raw) => new SecureSocket._(raw));
87 }
88 83
89 /** 84 /**
90 * Takes an already connected [socket] and starts server side TLS 85 * Takes an already connected [socket] and starts server side TLS
91 * handshake to make the communication secure. When the returned 86 * handshake to make the communication secure. When the returned
92 * future completes the [SecureSocket] has completed the TLS 87 * future completes the [SecureSocket] has completed the TLS
93 * handshake. Using this function requires that the other end of the 88 * handshake. Using this function requires that the other end of the
94 * connection is going to start the TLS handshake. 89 * connection is going to start the TLS handshake.
95 * 90 *
96 * If the [socket] already has a subscription, this subscription 91 * If the [socket] already has a subscription, this subscription
97 * will no longer receive and events. In most cases calling 92 * will no longer receive and events. In most cases calling
98 * [:pause:] on this subscription before starting TLS handshake is 93 * [:pause:] on this subscription before starting TLS handshake is
99 * the right thing to do. 94 * the right thing to do.
100 * 95 *
101 * If some of the data of the TLS handshake has already been read 96 * If some of the data of the TLS handshake has already been read
102 * from the socket this data can be passed in the [bufferedData] 97 * from the socket this data can be passed in the [bufferedData]
103 * parameter. This data will be processed before any other data 98 * parameter. This data will be processed before any other data
104 * available on the socket. 99 * available on the socket.
105 * 100 *
106 * See [SecureServerSocket.bind] for more information on the 101 * See [SecureServerSocket.bind] for more information on the
107 * arguments. 102 * arguments.
108 * 103 *
109 */ 104 */
110 static Future<SecureSocket> secureServer( 105 static Future<SecureSocket> secureServer(
111 Socket socket, 106 Socket socket, SecurityContext context,
112 SecurityContext context,
113 {List<int> bufferedData, 107 {List<int> bufferedData,
114 bool requestClientCertificate: false, 108 bool requestClientCertificate: false,
115 bool requireClientCertificate: false, 109 bool requireClientCertificate: false,
116 List<String> supportedProtocols}) { 110 List<String> supportedProtocols}) {
117 return ((socket as dynamic/*_Socket*/)._detachRaw() as Future) 111 return ((socket as dynamic /*_Socket*/)._detachRaw() as Future)
118 .then<RawSecureSocket>((detachedRaw) { 112 .then<RawSecureSocket>((detachedRaw) {
119 return RawSecureSocket.secureServer( 113 return RawSecureSocket.secureServer(detachedRaw[0] as RawSocket, context,
120 detachedRaw[0] as RawSocket, 114 subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>,
121 context, 115 bufferedData: bufferedData,
122 subscription: detachedRaw[1] as StreamSubscription<RawSocketEvent>, 116 requestClientCertificate: requestClientCertificate,
123 bufferedData: bufferedData, 117 requireClientCertificate: requireClientCertificate,
124 requestClientCertificate: requestClientCertificate, 118 supportedProtocols: supportedProtocols);
125 requireClientCertificate: requireClientCertificate, 119 }).then<SecureSocket>((raw) => new SecureSocket._(raw));
126 supportedProtocols: supportedProtocols);
127 })
128 .then<SecureSocket>((raw) => new SecureSocket._(raw));
129 } 120 }
130 121
131 /** 122 /**
132 * Get the peer certificate for a connected SecureSocket. If this 123 * Get the peer certificate for a connected SecureSocket. If this
133 * SecureSocket is the server end of a secure socket connection, 124 * SecureSocket is the server end of a secure socket connection,
134 * [peerCertificate] will return the client certificate, or null, if no 125 * [peerCertificate] will return the client certificate, or null, if no
135 * client certificate was received. If it is the client end, 126 * client certificate was received. If it is the client end,
136 * [peerCertificate] will return the server's certificate. 127 * [peerCertificate] will return the server's certificate.
137 */ 128 */
138 X509Certificate get peerCertificate; 129 X509Certificate get peerCertificate;
139 130
140 /** 131 /**
141 * Get the protocol which was selected during protocol negotiation. 132 * Get the protocol which was selected during protocol negotiation.
142 */ 133 */
143 String get selectedProtocol; 134 String get selectedProtocol;
144 135
145 /** 136 /**
146 * Renegotiate an existing secure connection, renewing the session keys 137 * Renegotiate an existing secure connection, renewing the session keys
147 * and possibly changing the connection properties. 138 * and possibly changing the connection properties.
148 * 139 *
149 * This repeats the SSL or TLS handshake, with options that allow clearing 140 * This repeats the SSL or TLS handshake, with options that allow clearing
150 * the session cache and requesting a client certificate. 141 * the session cache and requesting a client certificate.
151 */ 142 */
152 void renegotiate({bool useSessionCache: true, 143 void renegotiate(
153 bool requestClientCertificate: false, 144 {bool useSessionCache: true,
154 bool requireClientCertificate: false}); 145 bool requestClientCertificate: false,
146 bool requireClientCertificate: false});
155 } 147 }
156 148
157
158 /** 149 /**
159 * RawSecureSocket provides a secure (SSL or TLS) network connection. 150 * RawSecureSocket provides a secure (SSL or TLS) network connection.
160 * Client connections to a server are provided by calling 151 * Client connections to a server are provided by calling
161 * RawSecureSocket.connect. A secure server, created with 152 * RawSecureSocket.connect. A secure server, created with
162 * [RawSecureServerSocket], also returns RawSecureSocket objects representing 153 * [RawSecureServerSocket], also returns RawSecureSocket objects representing
163 * the server end of a secure connection. 154 * the server end of a secure connection.
164 * The certificate provided by the server is checked 155 * The certificate provided by the server is checked
165 * using the trusted certificates set in the SecurityContext object. 156 * using the trusted certificates set in the SecurityContext object.
166 * The default [SecurityContext] object contains a built-in set of trusted 157 * The default [SecurityContext] object contains a built-in set of trusted
167 * root certificates for well-known certificate authorities. 158 * root certificates for well-known certificate authorities.
168 */ 159 */
169 abstract class RawSecureSocket implements RawSocket { 160 abstract class RawSecureSocket implements RawSocket {
170 /** 161 /**
171 * Constructs a new secure client socket and connect it to the given 162 * Constructs a new secure client socket and connect it to the given
172 * host on the given port. The returned [Future] is completed with the 163 * host on the given port. The returned [Future] is completed with the
173 * RawSecureSocket when it is connected and ready for subscription. 164 * RawSecureSocket when it is connected and ready for subscription.
174 * 165 *
175 * The certificate provided by the server is checked using the trusted 166 * The certificate provided by the server is checked using the trusted
176 * certificates set in the SecurityContext object If a certificate and key are 167 * certificates set in the SecurityContext object If a certificate and key are
177 * set on the client, using [SecurityContext.useCertificateChain] and 168 * set on the client, using [SecurityContext.useCertificateChain] and
178 * [SecurityContext.usePrivateKey], and the server asks for a client 169 * [SecurityContext.usePrivateKey], and the server asks for a client
179 * certificate, then that client certificate is sent to the server. 170 * certificate, then that client certificate is sent to the server.
180 * 171 *
181 * [onBadCertificate] is an optional handler for unverifiable certificates. 172 * [onBadCertificate] is an optional handler for unverifiable certificates.
182 * The handler receives the [X509Certificate], and can inspect it and 173 * The handler receives the [X509Certificate], and can inspect it and
183 * decide (or let the user decide) whether to accept 174 * decide (or let the user decide) whether to accept
184 * the connection or not. The handler should return true 175 * the connection or not. The handler should return true
185 * to continue the [RawSecureSocket] connection. 176 * to continue the [RawSecureSocket] connection.
186 */ 177 */
187 static Future<RawSecureSocket> connect( 178 static Future<RawSecureSocket> connect(host, int port,
188 host,
189 int port,
190 {SecurityContext context, 179 {SecurityContext context,
191 bool onBadCertificate(X509Certificate certificate), 180 bool onBadCertificate(X509Certificate certificate),
192 List<String> supportedProtocols}) { 181 List<String> supportedProtocols}) {
193 _RawSecureSocket._verifyFields( 182 _RawSecureSocket._verifyFields(
194 host, 183 host, port, false, false, false, onBadCertificate);
195 port, 184 return RawSocket.connect(host, port).then((socket) {
196 false, 185 return secure(socket,
197 false, 186 context: context,
198 false, 187 onBadCertificate: onBadCertificate,
199 onBadCertificate); 188 supportedProtocols: supportedProtocols);
200 return RawSocket.connect(host, port) 189 });
201 .then((socket) {
202 return secure(socket,
203 context: context,
204 onBadCertificate: onBadCertificate,
205 supportedProtocols: supportedProtocols);
206 });
207 } 190 }
208 191
209 /** 192 /**
210 * Takes an already connected [socket] and starts client side TLS 193 * Takes an already connected [socket] and starts client side TLS
211 * handshake to make the communication secure. When the returned 194 * handshake to make the communication secure. When the returned
212 * future completes the [RawSecureSocket] has completed the TLS 195 * future completes the [RawSecureSocket] has completed the TLS
213 * handshake. Using this function requires that the other end of the 196 * handshake. Using this function requires that the other end of the
214 * connection is prepared for TLS handshake. 197 * connection is prepared for TLS handshake.
215 * 198 *
216 * If the [socket] already has a subscription, pass the existing 199 * If the [socket] already has a subscription, pass the existing
(...skipping 10 matching lines...) Expand all
227 * 210 *
228 * Calling this function will _not_ cause a DNS host lookup. If the 211 * Calling this function will _not_ cause a DNS host lookup. If the
229 * [host] passed is a [String] the [InternetAddress] for the 212 * [host] passed is a [String] the [InternetAddress] for the
230 * resulting [SecureSocket] will have this passed in [host] as its 213 * resulting [SecureSocket] will have this passed in [host] as its
231 * host value and the internet address of the already connected 214 * host value and the internet address of the already connected
232 * socket as its address value. 215 * socket as its address value.
233 * 216 *
234 * See [connect] for more information on the arguments. 217 * See [connect] for more information on the arguments.
235 * 218 *
236 */ 219 */
237 static Future<RawSecureSocket> secure( 220 static Future<RawSecureSocket> secure(RawSocket socket,
238 RawSocket socket,
239 {StreamSubscription<RawSocketEvent> subscription, 221 {StreamSubscription<RawSocketEvent> subscription,
240 host, 222 host,
241 SecurityContext context, 223 SecurityContext context,
242 bool onBadCertificate(X509Certificate certificate), 224 bool onBadCertificate(X509Certificate certificate),
243 List<String> supportedProtocols}) { 225 List<String> supportedProtocols}) {
244 socket.readEventsEnabled = false; 226 socket.readEventsEnabled = false;
245 socket.writeEventsEnabled = false; 227 socket.writeEventsEnabled = false;
246 return _RawSecureSocket.connect( 228 return _RawSecureSocket.connect(
247 host != null ? host : socket.address.host, 229 host != null ? host : socket.address.host, socket.port,
248 socket.port,
249 is_server: false, 230 is_server: false,
250 socket: socket, 231 socket: socket,
251 subscription: subscription, 232 subscription: subscription,
252 context: context, 233 context: context,
253 onBadCertificate: onBadCertificate, 234 onBadCertificate: onBadCertificate,
254 supportedProtocols: supportedProtocols); 235 supportedProtocols: supportedProtocols);
255 } 236 }
256 237
257 /** 238 /**
258 * Takes an already connected [socket] and starts server side TLS 239 * Takes an already connected [socket] and starts server side TLS
(...skipping 12 matching lines...) Expand all
271 * If some of the data of the TLS handshake has already been read 252 * If some of the data of the TLS handshake has already been read
272 * from the socket this data can be passed in the [bufferedData] 253 * from the socket this data can be passed in the [bufferedData]
273 * parameter. This data will be processed before any other data 254 * parameter. This data will be processed before any other data
274 * available on the socket. 255 * available on the socket.
275 * 256 *
276 * See [RawSecureServerSocket.bind] for more information on the 257 * See [RawSecureServerSocket.bind] for more information on the
277 * arguments. 258 * arguments.
278 * 259 *
279 */ 260 */
280 static Future<RawSecureSocket> secureServer( 261 static Future<RawSecureSocket> secureServer(
281 RawSocket socket, 262 RawSocket socket, SecurityContext context,
282 SecurityContext context,
283 {StreamSubscription<RawSocketEvent> subscription, 263 {StreamSubscription<RawSocketEvent> subscription,
284 List<int> bufferedData, 264 List<int> bufferedData,
285 bool requestClientCertificate: false, 265 bool requestClientCertificate: false,
286 bool requireClientCertificate: false, 266 bool requireClientCertificate: false,
287 List<String> supportedProtocols}) { 267 List<String> supportedProtocols}) {
288 socket.readEventsEnabled = false; 268 socket.readEventsEnabled = false;
289 socket.writeEventsEnabled = false; 269 socket.writeEventsEnabled = false;
290 return _RawSecureSocket.connect( 270 return _RawSecureSocket.connect(socket.address, socket.remotePort,
291 socket.address,
292 socket.remotePort,
293 context: context, 271 context: context,
294 is_server: true, 272 is_server: true,
295 socket: socket, 273 socket: socket,
296 subscription: subscription, 274 subscription: subscription,
297 bufferedData: bufferedData, 275 bufferedData: bufferedData,
298 requestClientCertificate: requestClientCertificate, 276 requestClientCertificate: requestClientCertificate,
299 requireClientCertificate: requireClientCertificate, 277 requireClientCertificate: requireClientCertificate,
300 supportedProtocols: supportedProtocols); 278 supportedProtocols: supportedProtocols);
301 } 279 }
302 280
303 /** 281 /**
304 * Renegotiate an existing secure connection, renewing the session keys 282 * Renegotiate an existing secure connection, renewing the session keys
305 * and possibly changing the connection properties. 283 * and possibly changing the connection properties.
306 * 284 *
307 * This repeats the SSL or TLS handshake, with options that allow clearing 285 * This repeats the SSL or TLS handshake, with options that allow clearing
308 * the session cache and requesting a client certificate. 286 * the session cache and requesting a client certificate.
309 */ 287 */
310 void renegotiate({bool useSessionCache: true, 288 void renegotiate(
311 bool requestClientCertificate: false, 289 {bool useSessionCache: true,
312 bool requireClientCertificate: false}); 290 bool requestClientCertificate: false,
291 bool requireClientCertificate: false});
313 292
314 /** 293 /**
315 * Get the peer certificate for a connected RawSecureSocket. If this 294 * Get the peer certificate for a connected RawSecureSocket. If this
316 * RawSecureSocket is the server end of a secure socket connection, 295 * RawSecureSocket is the server end of a secure socket connection,
317 * [peerCertificate] will return the client certificate, or null, if no 296 * [peerCertificate] will return the client certificate, or null, if no
318 * client certificate was received. If it is the client end, 297 * client certificate was received. If it is the client end,
319 * [peerCertificate] will return the server's certificate. 298 * [peerCertificate] will return the server's certificate.
320 */ 299 */
321 X509Certificate get peerCertificate; 300 X509Certificate get peerCertificate;
322 301
323 /** 302 /**
324 * Get the protocol which was selected during protocol negotiation. 303 * Get the protocol which was selected during protocol negotiation.
325 */ 304 */
326 String get selectedProtocol; 305 String get selectedProtocol;
327 } 306 }
328 307
329
330 /** 308 /**
331 * X509Certificate represents an SSL certificate, with accessors to 309 * X509Certificate represents an SSL certificate, with accessors to
332 * get the fields of the certificate. 310 * get the fields of the certificate.
333 */ 311 */
334 abstract class X509Certificate { 312 abstract class X509Certificate {
335 external factory X509Certificate._(); 313 external factory X509Certificate._();
336 314
337 String get subject; 315 String get subject;
338 String get issuer; 316 String get issuer;
339 DateTime get startValidity; 317 DateTime get startValidity;
340 DateTime get endValidity; 318 DateTime get endValidity;
341 } 319 }
342 320
343
344 class _FilterStatus { 321 class _FilterStatus {
345 bool progress = false; // The filter read or wrote data to the buffers. 322 bool progress = false; // The filter read or wrote data to the buffers.
346 bool readEmpty = true; // The read buffers and decryption filter are empty. 323 bool readEmpty = true; // The read buffers and decryption filter are empty.
347 bool writeEmpty = true; // The write buffers and encryption filter are empty. 324 bool writeEmpty = true; // The write buffers and encryption filter are empty.
348 // These are set if a buffer changes state from empty or full. 325 // These are set if a buffer changes state from empty or full.
349 bool readPlaintextNoLongerEmpty = false; 326 bool readPlaintextNoLongerEmpty = false;
350 bool writePlaintextNoLongerFull = false; 327 bool writePlaintextNoLongerFull = false;
351 bool readEncryptedNoLongerFull = false; 328 bool readEncryptedNoLongerFull = false;
352 bool writeEncryptedNoLongerEmpty = false; 329 bool writeEncryptedNoLongerEmpty = false;
353 330
354 _FilterStatus(); 331 _FilterStatus();
355 } 332 }
356 333
357
358 class _RawSecureSocket extends Stream<RawSocketEvent> 334 class _RawSecureSocket extends Stream<RawSocketEvent>
359 implements RawSecureSocket { 335 implements RawSecureSocket {
360 // Status states 336 // Status states
361 static final int HANDSHAKE = 201; 337 static final int HANDSHAKE = 201;
362 static final int CONNECTED = 202; 338 static final int CONNECTED = 202;
363 static final int CLOSED = 203; 339 static final int CLOSED = 203;
364 340
365 // Buffer identifiers. 341 // Buffer identifiers.
366 // These must agree with those in the native C++ implementation. 342 // These must agree with those in the native C++ implementation.
367 static final int READ_PLAINTEXT = 0; 343 static final int READ_PLAINTEXT = 0;
368 static final int WRITE_PLAINTEXT = 1; 344 static final int WRITE_PLAINTEXT = 1;
369 static final int READ_ENCRYPTED = 2; 345 static final int READ_ENCRYPTED = 2;
370 static final int WRITE_ENCRYPTED = 3; 346 static final int WRITE_ENCRYPTED = 3;
371 static final int NUM_BUFFERS = 4; 347 static final int NUM_BUFFERS = 4;
372 348
373 // Is a buffer identifier for an encrypted buffer? 349 // Is a buffer identifier for an encrypted buffer?
374 static bool _isBufferEncrypted(int identifier) => identifier >= READ_ENCRYPTED ; 350 static bool _isBufferEncrypted(int identifier) =>
351 identifier >= READ_ENCRYPTED;
375 352
376 RawSocket _socket; 353 RawSocket _socket;
377 final Completer<_RawSecureSocket> _handshakeComplete = 354 final Completer<_RawSecureSocket> _handshakeComplete =
378 new Completer<_RawSecureSocket>(); 355 new Completer<_RawSecureSocket>();
379 StreamController<RawSocketEvent> _controller; 356 StreamController<RawSocketEvent> _controller;
380 Stream<RawSocketEvent> _stream; 357 Stream<RawSocketEvent> _stream;
381 StreamSubscription<RawSocketEvent> _socketSubscription; 358 StreamSubscription<RawSocketEvent> _socketSubscription;
382 List<int> _bufferedData; 359 List<int> _bufferedData;
383 int _bufferedDataIndex = 0; 360 int _bufferedDataIndex = 0;
384 final InternetAddress address; 361 final InternetAddress address;
385 final bool is_server; 362 final bool is_server;
386 SecurityContext context; 363 SecurityContext context;
387 final bool requestClientCertificate; 364 final bool requestClientCertificate;
388 final bool requireClientCertificate; 365 final bool requireClientCertificate;
389 final Function onBadCertificate; 366 final Function onBadCertificate;
390 367
391 var _status = HANDSHAKE; 368 var _status = HANDSHAKE;
392 bool _writeEventsEnabled = true; 369 bool _writeEventsEnabled = true;
393 bool _readEventsEnabled = true; 370 bool _readEventsEnabled = true;
394 int _pauseCount = 0; 371 int _pauseCount = 0;
395 bool _pendingReadEvent = false; 372 bool _pendingReadEvent = false;
396 bool _socketClosedRead = false; // The network socket is closed for reading. 373 bool _socketClosedRead = false; // The network socket is closed for reading.
397 bool _socketClosedWrite = false; // The network socket is closed for writing. 374 bool _socketClosedWrite = false; // The network socket is closed for writing.
398 bool _closedRead = false; // The secure socket has fired an onClosed event. 375 bool _closedRead = false; // The secure socket has fired an onClosed event.
399 bool _closedWrite = false; // The secure socket has been closed for writing. 376 bool _closedWrite = false; // The secure socket has been closed for writing.
400 // The network socket is gone. 377 // The network socket is gone.
401 Completer<RawSecureSocket> _closeCompleter = new Completer<RawSecureSocket>(); 378 Completer<RawSecureSocket> _closeCompleter = new Completer<RawSecureSocket>();
402 _FilterStatus _filterStatus = new _FilterStatus(); 379 _FilterStatus _filterStatus = new _FilterStatus();
403 bool _connectPending = true; 380 bool _connectPending = true;
404 bool _filterPending = false; 381 bool _filterPending = false;
405 bool _filterActive = false; 382 bool _filterActive = false;
406 383
407 _SecureFilter _secureFilter = new _SecureFilter(); 384 _SecureFilter _secureFilter = new _SecureFilter();
408 String _selectedProtocol; 385 String _selectedProtocol;
409 386
410 static Future<_RawSecureSocket> connect( 387 static Future<_RawSecureSocket> connect(
411 dynamic/*String|InternetAddress*/ host, 388 dynamic /*String|InternetAddress*/ host, int requestedPort,
412 int requestedPort,
413 {bool is_server, 389 {bool is_server,
414 SecurityContext context, 390 SecurityContext context,
415 RawSocket socket, 391 RawSocket socket,
416 StreamSubscription<RawSocketEvent> subscription, 392 StreamSubscription<RawSocketEvent> subscription,
417 List<int> bufferedData, 393 List<int> bufferedData,
418 bool requestClientCertificate: false, 394 bool requestClientCertificate: false,
419 bool requireClientCertificate: false, 395 bool requireClientCertificate: false,
420 bool onBadCertificate(X509Certificate certificate), 396 bool onBadCertificate(X509Certificate certificate),
421 List<String> supportedProtocols}) { 397 List<String> supportedProtocols}) {
422 _verifyFields(host, requestedPort, is_server, 398 _verifyFields(host, requestedPort, is_server, requestClientCertificate,
423 requestClientCertificate, requireClientCertificate, 399 requireClientCertificate, onBadCertificate);
424 onBadCertificate);
425 if (host is InternetAddress) host = host.host; 400 if (host is InternetAddress) host = host.host;
426 InternetAddress address = socket.address; 401 InternetAddress address = socket.address;
427 if (host != null) { 402 if (host != null) {
428 address = InternetAddress._cloneWithNewHost(address, host); 403 address = InternetAddress._cloneWithNewHost(address, host);
429 } 404 }
430 return new _RawSecureSocket(address, 405 return new _RawSecureSocket(
431 requestedPort, 406 address,
432 is_server, 407 requestedPort,
433 context, 408 is_server,
434 socket, 409 context,
435 subscription, 410 socket,
436 bufferedData, 411 subscription,
437 requestClientCertificate, 412 bufferedData,
438 requireClientCertificate, 413 requestClientCertificate,
439 onBadCertificate, 414 requireClientCertificate,
440 supportedProtocols) 415 onBadCertificate,
441 ._handshakeComplete.future; 416 supportedProtocols)
417 ._handshakeComplete
418 .future;
442 } 419 }
443 420
444 _RawSecureSocket( 421 _RawSecureSocket(
445 this.address, 422 this.address,
446 int requestedPort, 423 int requestedPort,
447 this.is_server, 424 this.is_server,
448 this.context, 425 this.context,
449 this._socket, 426 this._socket,
450 this._socketSubscription, 427 this._socketSubscription,
451 this._bufferedData, 428 this._bufferedData,
452 this.requestClientCertificate, 429 this.requestClientCertificate,
453 this.requireClientCertificate, 430 this.requireClientCertificate,
454 this.onBadCertificate, 431 this.onBadCertificate,
455 List<String> supportedProtocols) { 432 List<String> supportedProtocols) {
456 if (context == null) { 433 if (context == null) {
457 context = SecurityContext.defaultContext; 434 context = SecurityContext.defaultContext;
458 } 435 }
459 _controller = new StreamController<RawSocketEvent>( 436 _controller = new StreamController<RawSocketEvent>(
460 sync: true, 437 sync: true,
461 onListen: _onSubscriptionStateChange, 438 onListen: _onSubscriptionStateChange,
462 onPause: _onPauseStateChange, 439 onPause: _onPauseStateChange,
463 onResume: _onPauseStateChange, 440 onResume: _onPauseStateChange,
464 onCancel: _onSubscriptionStateChange); 441 onCancel: _onSubscriptionStateChange);
465 _stream = _controller.stream; 442 _stream = _controller.stream;
466 // Throw an ArgumentError if any field is invalid. After this, all 443 // Throw an ArgumentError if any field is invalid. After this, all
467 // errors will be reported through the future or the stream. 444 // errors will be reported through the future or the stream.
468 _secureFilter.init(); 445 _secureFilter.init();
469 _secureFilter.registerHandshakeCompleteCallback( 446 _secureFilter
470 _secureHandshakeCompleteHandler); 447 .registerHandshakeCompleteCallback(_secureHandshakeCompleteHandler);
471 if (onBadCertificate != null) { 448 if (onBadCertificate != null) {
472 _secureFilter.registerBadCertificateCallback(_onBadCertificateWrapper); 449 _secureFilter.registerBadCertificateCallback(_onBadCertificateWrapper);
473 } 450 }
474 _socket.readEventsEnabled = true; 451 _socket.readEventsEnabled = true;
475 _socket.writeEventsEnabled = false; 452 _socket.writeEventsEnabled = false;
476 if (_socketSubscription == null) { 453 if (_socketSubscription == null) {
477 // If a current subscription is provided use this otherwise 454 // If a current subscription is provided use this otherwise
478 // create a new one. 455 // create a new one.
479 _socketSubscription = _socket.listen(_eventDispatcher, 456 _socketSubscription = _socket.listen(_eventDispatcher,
480 onError: _reportError, 457 onError: _reportError, onDone: _doneHandler);
481 onDone: _doneHandler);
482 } else { 458 } else {
483 if (_socketSubscription.isPaused) { 459 if (_socketSubscription.isPaused) {
484 _socket.close(); 460 _socket.close();
485 throw new ArgumentError( 461 throw new ArgumentError("Subscription passed to TLS upgrade is paused");
486 "Subscription passed to TLS upgrade is paused");
487 } 462 }
488 // If we are upgrading a socket that is already closed for read, 463 // If we are upgrading a socket that is already closed for read,
489 // report an error as if we received READ_CLOSED during the handshake. 464 // report an error as if we received READ_CLOSED during the handshake.
490 dynamic s = _socket; // Cast to dynamic to avoid warning. 465 dynamic s = _socket; // Cast to dynamic to avoid warning.
491 if (s._socket.closedReadEventSent) { 466 if (s._socket.closedReadEventSent) {
492 _eventDispatcher(RawSocketEvent.READ_CLOSED); 467 _eventDispatcher(RawSocketEvent.READ_CLOSED);
493 } 468 }
494 _socketSubscription 469 _socketSubscription
495 ..onData(_eventDispatcher) 470 ..onData(_eventDispatcher)
496 ..onError(_reportError) 471 ..onError(_reportError)
497 ..onDone(_doneHandler); 472 ..onDone(_doneHandler);
498 } 473 }
499 try { 474 try {
500 var encodedProtocols = 475 var encodedProtocols =
501 SecurityContext._protocolsToLengthEncoding(supportedProtocols); 476 SecurityContext._protocolsToLengthEncoding(supportedProtocols);
502 _secureFilter.connect(address.host, 477 _secureFilter.connect(
503 context, 478 address.host,
504 is_server, 479 context,
505 requestClientCertificate || 480 is_server,
506 requireClientCertificate, 481 requestClientCertificate || requireClientCertificate,
507 requireClientCertificate, 482 requireClientCertificate,
508 encodedProtocols); 483 encodedProtocols);
509 _secureHandshake(); 484 _secureHandshake();
510 } catch (e, s) { 485 } catch (e, s) {
511 _reportError(e, s); 486 _reportError(e, s);
512 } 487 }
513 } 488 }
514 489
515 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent data), 490 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent data),
516 {Function onError, 491 {Function onError, void onDone(), bool cancelOnError}) {
517 void onDone(),
518 bool cancelOnError}) {
519 _sendWriteEvent(); 492 _sendWriteEvent();
520 return _stream.listen(onData, 493 return _stream.listen(onData,
521 onError: onError, 494 onError: onError, onDone: onDone, cancelOnError: cancelOnError);
522 onDone: onDone,
523 cancelOnError: cancelOnError);
524 } 495 }
525 496
526 static void _verifyFields(host, 497 static void _verifyFields(
527 int requestedPort, 498 host,
528 bool is_server, 499 int requestedPort,
529 bool requestClientCertificate, 500 bool is_server,
530 bool requireClientCertificate, 501 bool requestClientCertificate,
531 Function onBadCertificate) { 502 bool requireClientCertificate,
503 Function onBadCertificate) {
532 if (host is! String && host is! InternetAddress) { 504 if (host is! String && host is! InternetAddress) {
533 throw new ArgumentError("host is not a String or an InternetAddress"); 505 throw new ArgumentError("host is not a String or an InternetAddress");
534 } 506 }
535 if (requestedPort is! int) { 507 if (requestedPort is! int) {
536 throw new ArgumentError("requestedPort is not an int"); 508 throw new ArgumentError("requestedPort is not an int");
537 } 509 }
538 if (requestedPort < 0 || requestedPort > 65535) { 510 if (requestedPort < 0 || requestedPort > 65535) {
539 throw new ArgumentError("requestedPort is not in the range 0..65535"); 511 throw new ArgumentError("requestedPort is not in the range 0..65535");
540 } 512 }
541 if (requestClientCertificate is! bool) { 513 if (requestClientCertificate is! bool) {
542 throw new ArgumentError("requestClientCertificate is not a bool"); 514 throw new ArgumentError("requestClientCertificate is not a bool");
543 } 515 }
544 if (requireClientCertificate is! bool) { 516 if (requireClientCertificate is! bool) {
545 throw new ArgumentError("requireClientCertificate is not a bool"); 517 throw new ArgumentError("requireClientCertificate is not a bool");
546 } 518 }
547 if (onBadCertificate != null && onBadCertificate is! Function) { 519 if (onBadCertificate != null && onBadCertificate is! Function) {
548 throw new ArgumentError("onBadCertificate is not null or a Function"); 520 throw new ArgumentError("onBadCertificate is not null or a Function");
549 } 521 }
550 } 522 }
551 523
552 int get port => _socket.port; 524 int get port => _socket.port;
553 525
554 InternetAddress get remoteAddress => _socket.remoteAddress; 526 InternetAddress get remoteAddress => _socket.remoteAddress;
555 527
556 int get remotePort => _socket.remotePort; 528 int get remotePort => _socket.remotePort;
557 529
558 void set _owner(owner) { 530 void set _owner(owner) {
559 (_socket as dynamic)._owner = owner; 531 (_socket as dynamic)._owner = owner;
560 } 532 }
561 533
562 int available() { 534 int available() {
563 return _status != CONNECTED ? 0 535 return _status != CONNECTED
564 : _secureFilter.buffers[READ_PLAINTEXT].length; 536 ? 0
537 : _secureFilter.buffers[READ_PLAINTEXT].length;
565 } 538 }
566 539
567 Future<RawSecureSocket> close() { 540 Future<RawSecureSocket> close() {
568 shutdown(SocketDirection.BOTH); 541 shutdown(SocketDirection.BOTH);
569 return _closeCompleter.future; 542 return _closeCompleter.future;
570 } 543 }
571 544
572 void _completeCloseCompleter([RawSocket dummy]) { 545 void _completeCloseCompleter([RawSocket dummy]) {
573 if (!_closeCompleter.isCompleted) _closeCompleter.complete(this); 546 if (!_closeCompleter.isCompleted) _closeCompleter.complete(this);
574 } 547 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 void set writeEventsEnabled(bool value) { 595 void set writeEventsEnabled(bool value) {
623 _writeEventsEnabled = value; 596 _writeEventsEnabled = value;
624 if (value) { 597 if (value) {
625 Timer.run(() => _sendWriteEvent()); 598 Timer.run(() => _sendWriteEvent());
626 } 599 }
627 } 600 }
628 601
629 bool get readEventsEnabled => _readEventsEnabled; 602 bool get readEventsEnabled => _readEventsEnabled;
630 603
631 void set readEventsEnabled(bool value) { 604 void set readEventsEnabled(bool value) {
632 _readEventsEnabled = value; 605 _readEventsEnabled = value;
633 _scheduleReadEvent(); 606 _scheduleReadEvent();
634 } 607 }
635 608
636 List<int> read([int length]) { 609 List<int> read([int length]) {
637 if (length != null && (length is! int || length < 0)) { 610 if (length != null && (length is! int || length < 0)) {
638 throw new ArgumentError( 611 throw new ArgumentError(
639 "Invalid length parameter in SecureSocket.read (length: $length)"); 612 "Invalid length parameter in SecureSocket.read (length: $length)");
640 } 613 }
641 if (_closedRead) { 614 if (_closedRead) {
642 throw new SocketException("Reading from a closed socket"); 615 throw new SocketException("Reading from a closed socket");
643 } 616 }
644 if (_status != CONNECTED) { 617 if (_status != CONNECTED) {
645 return null; 618 return null;
646 } 619 }
647 var result = _secureFilter.buffers[READ_PLAINTEXT].read(length); 620 var result = _secureFilter.buffers[READ_PLAINTEXT].read(length);
648 _scheduleFilter(); 621 _scheduleFilter();
649 return result; 622 return result;
650 } 623 }
651 624
652 // Write the data to the socket, and schedule the filter to encrypt it. 625 // Write the data to the socket, and schedule the filter to encrypt it.
653 int write(List<int> data, [int offset, int bytes]) { 626 int write(List<int> data, [int offset, int bytes]) {
654 if (bytes != null && (bytes is! int || bytes < 0)) { 627 if (bytes != null && (bytes is! int || bytes < 0)) {
655 throw new ArgumentError( 628 throw new ArgumentError(
656 "Invalid bytes parameter in SecureSocket.read (bytes: $bytes)"); 629 "Invalid bytes parameter in SecureSocket.read (bytes: $bytes)");
657 } 630 }
658 if (offset != null && (offset is! int || offset < 0)) { 631 if (offset != null && (offset is! int || offset < 0)) {
659 throw new ArgumentError( 632 throw new ArgumentError(
660 "Invalid offset parameter in SecureSocket.read (offset: $offset)"); 633 "Invalid offset parameter in SecureSocket.read (offset: $offset)");
661 } 634 }
662 if (_closedWrite) { 635 if (_closedWrite) {
663 _controller.addError(new SocketException("Writing to a closed socket")); 636 _controller.addError(new SocketException("Writing to a closed socket"));
664 return 0; 637 return 0;
665 } 638 }
666 if (_status != CONNECTED) return 0; 639 if (_status != CONNECTED) return 0;
667 if (offset == null) offset = 0; 640 if (offset == null) offset = 0;
668 if (bytes == null) bytes = data.length - offset; 641 if (bytes == null) bytes = data.length - offset;
669 642
670 int written = 643 int written =
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 // _handshakeComplete future returned from SecureSocket.connect has 704 // _handshakeComplete future returned from SecureSocket.connect has
732 // completed. Before this point, we must complete it with an error. 705 // completed. Before this point, we must complete it with an error.
733 _handshakeComplete.completeError(e, stackTrace); 706 _handshakeComplete.completeError(e, stackTrace);
734 } else { 707 } else {
735 _controller.addError(e, stackTrace); 708 _controller.addError(e, stackTrace);
736 } 709 }
737 _close(); 710 _close();
738 } 711 }
739 712
740 void _closeHandler() { 713 void _closeHandler() {
741 if (_status == CONNECTED) { 714 if (_status == CONNECTED) {
742 if (_closedRead) return; 715 if (_closedRead) return;
743 _socketClosedRead = true; 716 _socketClosedRead = true;
744 if (_filterStatus.readEmpty) { 717 if (_filterStatus.readEmpty) {
745 _closedRead = true; 718 _closedRead = true;
746 _controller.add(RawSocketEvent.READ_CLOSED); 719 _controller.add(RawSocketEvent.READ_CLOSED);
747 if (_socketClosedWrite) { 720 if (_socketClosedWrite) {
748 _close(); 721 _close();
749 } 722 }
750 } else { 723 } else {
751 _scheduleFilter(); 724 _scheduleFilter();
752 } 725 }
753 } else if (_status == HANDSHAKE) { 726 } else if (_status == HANDSHAKE) {
754 _socketClosedRead = true; 727 _socketClosedRead = true;
755 if (_filterStatus.readEmpty) { 728 if (_filterStatus.readEmpty) {
756 _reportError( 729 _reportError(
757 new HandshakeException('Connection terminated during handshake'), 730 new HandshakeException('Connection terminated during handshake'),
758 null); 731 null);
759 } else { 732 } else {
760 _secureHandshake(); 733 _secureHandshake();
761 } 734 }
762 } 735 }
763 } 736 }
764 737
765 void _secureHandshake() { 738 void _secureHandshake() {
766 try { 739 try {
767 _secureFilter.handshake(); 740 _secureFilter.handshake();
768 _filterStatus.writeEmpty = false; 741 _filterStatus.writeEmpty = false;
769 _readSocket(); 742 _readSocket();
770 _writeSocket(); 743 _writeSocket();
771 _scheduleFilter(); 744 _scheduleFilter();
772 } catch (e, stackTrace) { 745 } catch (e, stackTrace) {
773 _reportError(e, stackTrace); 746 _reportError(e, stackTrace);
774 } 747 }
775 } 748 }
776 749
777 void renegotiate({bool useSessionCache: true, 750 void renegotiate(
778 bool requestClientCertificate: false, 751 {bool useSessionCache: true,
779 bool requireClientCertificate: false}) { 752 bool requestClientCertificate: false,
753 bool requireClientCertificate: false}) {
780 if (_status != CONNECTED) { 754 if (_status != CONNECTED) {
781 throw new HandshakeException( 755 throw new HandshakeException(
782 "Called renegotiate on a non-connected socket"); 756 "Called renegotiate on a non-connected socket");
783 } 757 }
784 _secureFilter.renegotiate(useSessionCache, 758 _secureFilter.renegotiate(
785 requestClientCertificate, 759 useSessionCache, requestClientCertificate, requireClientCertificate);
786 requireClientCertificate);
787 _status = HANDSHAKE; 760 _status = HANDSHAKE;
788 _filterStatus.writeEmpty = false; 761 _filterStatus.writeEmpty = false;
789 _scheduleFilter(); 762 _scheduleFilter();
790 } 763 }
791 764
792 void _secureHandshakeCompleteHandler() { 765 void _secureHandshakeCompleteHandler() {
793 _status = CONNECTED; 766 _status = CONNECTED;
794 if (_connectPending) { 767 if (_connectPending) {
795 _connectPending = false; 768 _connectPending = false;
796 try { 769 try {
797 _selectedProtocol = _secureFilter.selectedProtocol(); 770 _selectedProtocol = _secureFilter.selectedProtocol();
798 // We don't want user code to run synchronously in this callback. 771 // We don't want user code to run synchronously in this callback.
799 Timer.run(() => _handshakeComplete.complete(this)); 772 Timer.run(() => _handshakeComplete.complete(this));
800 } catch (error, stack) { 773 } catch (error, stack) {
801 _handshakeComplete.completeError(error, stack); 774 _handshakeComplete.completeError(error, stack);
802 } 775 }
803 } 776 }
804 } 777 }
805 778
806 void _onPauseStateChange() { 779 void _onPauseStateChange() {
807 if (_controller.isPaused) { 780 if (_controller.isPaused) {
808 _pauseCount++; 781 _pauseCount++;
809 } else { 782 } else {
810 _pauseCount--; 783 _pauseCount--;
811 if (_pauseCount == 0) { 784 if (_pauseCount == 0) {
812 _scheduleReadEvent(); 785 _scheduleReadEvent();
813 _sendWriteEvent(); // Can send event synchronously. 786 _sendWriteEvent(); // Can send event synchronously.
814 } 787 }
815 } 788 }
816 789
817 if (!_socketClosedRead || !_socketClosedWrite) { 790 if (!_socketClosedRead || !_socketClosedWrite) {
818 if (_controller.isPaused) { 791 if (_controller.isPaused) {
819 _socketSubscription.pause(); 792 _socketSubscription.pause();
820 } else { 793 } else {
821 _socketSubscription.resume(); 794 _socketSubscription.resume();
822 } 795 }
823 } 796 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 _tryFilter(); 864 _tryFilter();
892 }).catchError(_reportError); 865 }).catchError(_reportError);
893 } 866 }
894 } 867 }
895 868
896 List<int> _readSocketOrBufferedData(int bytes) { 869 List<int> _readSocketOrBufferedData(int bytes) {
897 if (_bufferedData != null) { 870 if (_bufferedData != null) {
898 if (bytes > _bufferedData.length - _bufferedDataIndex) { 871 if (bytes > _bufferedData.length - _bufferedDataIndex) {
899 bytes = _bufferedData.length - _bufferedDataIndex; 872 bytes = _bufferedData.length - _bufferedDataIndex;
900 } 873 }
901 var result = _bufferedData.sublist(_bufferedDataIndex, 874 var result =
902 _bufferedDataIndex + bytes); 875 _bufferedData.sublist(_bufferedDataIndex, _bufferedDataIndex + bytes);
903 _bufferedDataIndex += bytes; 876 _bufferedDataIndex += bytes;
904 if (_bufferedData.length == _bufferedDataIndex) { 877 if (_bufferedData.length == _bufferedDataIndex) {
905 _bufferedData = null; 878 _bufferedData = null;
906 } 879 }
907 return result; 880 return result;
908 } else if (!_socketClosedRead) { 881 } else if (!_socketClosedRead) {
909 return _socket.read(bytes); 882 return _socket.read(bytes);
910 } else { 883 } else {
911 return null; 884 return null;
912 } 885 }
913 } 886 }
914 887
915 void _readSocket() { 888 void _readSocket() {
916 if (_status == CLOSED) return; 889 if (_status == CLOSED) return;
917 var buffer = _secureFilter.buffers[READ_ENCRYPTED]; 890 var buffer = _secureFilter.buffers[READ_ENCRYPTED];
918 if (buffer.writeFromSource(_readSocketOrBufferedData) > 0) { 891 if (buffer.writeFromSource(_readSocketOrBufferedData) > 0) {
919 _filterStatus.readEmpty = false; 892 _filterStatus.readEmpty = false;
920 } else { 893 } else {
921 _socket.readEventsEnabled = false; 894 _socket.readEventsEnabled = false;
922 } 895 }
923 } 896 }
924 897
925 void _writeSocket() { 898 void _writeSocket() {
926 if (_socketClosedWrite) return; 899 if (_socketClosedWrite) return;
927 var buffer = _secureFilter.buffers[WRITE_ENCRYPTED]; 900 var buffer = _secureFilter.buffers[WRITE_ENCRYPTED];
928 if (buffer.readToSocket(_socket)) { // Returns true if blocked 901 if (buffer.readToSocket(_socket)) {
902 // Returns true if blocked
929 _socket.writeEventsEnabled = true; 903 _socket.writeEventsEnabled = true;
930 } 904 }
931 } 905 }
932 906
933 // If a read event should be sent, add it to the controller. 907 // If a read event should be sent, add it to the controller.
934 _scheduleReadEvent() { 908 _scheduleReadEvent() {
935 if (!_pendingReadEvent && 909 if (!_pendingReadEvent &&
936 _readEventsEnabled && 910 _readEventsEnabled &&
937 _pauseCount == 0 && 911 _pauseCount == 0 &&
938 _secureFilter != null && 912 _secureFilter != null &&
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 953
980 return _IOService._dispatch(_SSL_PROCESS_FILTER, args).then((response) { 954 return _IOService._dispatch(_SSL_PROCESS_FILTER, args).then((response) {
981 if (response.length == 2) { 955 if (response.length == 2) {
982 if (wasInHandshake) { 956 if (wasInHandshake) {
983 // If we're in handshake, throw a handshake error. 957 // If we're in handshake, throw a handshake error.
984 _reportError( 958 _reportError(
985 new HandshakeException('${response[1]} error ${response[0]}'), 959 new HandshakeException('${response[1]} error ${response[0]}'),
986 null); 960 null);
987 } else { 961 } else {
988 // If we're connected, throw a TLS error. 962 // If we're connected, throw a TLS error.
989 _reportError(new TlsException('${response[1]} error ${response[0]}'), 963 _reportError(
990 null); 964 new TlsException('${response[1]} error ${response[0]}'), null);
991 } 965 }
992 } 966 }
993 int start(int index) => response[2 * index]; 967 int start(int index) => response[2 * index];
994 int end(int index) => response[2 * index + 1]; 968 int end(int index) => response[2 * index + 1];
995 969
996 _FilterStatus status = new _FilterStatus(); 970 _FilterStatus status = new _FilterStatus();
997 // Compute writeEmpty as "write plaintext buffer and write encrypted 971 // Compute writeEmpty as "write plaintext buffer and write encrypted
998 // buffer were empty when we started and are empty now". 972 // buffer were empty when we started and are empty now".
999 status.writeEmpty = bufs[WRITE_PLAINTEXT].isEmpty && 973 status.writeEmpty = bufs[WRITE_PLAINTEXT].isEmpty &&
1000 start(WRITE_ENCRYPTED) == end(WRITE_ENCRYPTED); 974 start(WRITE_ENCRYPTED) == end(WRITE_ENCRYPTED);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 if (buffer.length == 0) { 1015 if (buffer.length == 0) {
1042 status.readPlaintextNoLongerEmpty = true; 1016 status.readPlaintextNoLongerEmpty = true;
1043 } 1017 }
1044 buffer.end = new_end; 1018 buffer.end = new_end;
1045 } 1019 }
1046 return status; 1020 return status;
1047 }); 1021 });
1048 } 1022 }
1049 } 1023 }
1050 1024
1051
1052 /** 1025 /**
1053 * A circular buffer backed by an external byte array. Accessed from 1026 * A circular buffer backed by an external byte array. Accessed from
1054 * both C++ and Dart code in an unsynchronized way, with one reading 1027 * both C++ and Dart code in an unsynchronized way, with one reading
1055 * and one writing. All updates to start and end are done by Dart code. 1028 * and one writing. All updates to start and end are done by Dart code.
1056 */ 1029 */
1057 class _ExternalBuffer { 1030 class _ExternalBuffer {
1058 // This will be an ExternalByteArray, backed by C allocated data. 1031 // This will be an ExternalByteArray, backed by C allocated data.
1059 List<int> data; 1032 List<int> data;
1060 int start; 1033 int start;
1061 int end; 1034 int end;
(...skipping 18 matching lines...) Expand all
1080 end += bytes; 1053 end += bytes;
1081 if (end >= size) { 1054 if (end >= size) {
1082 end -= size; 1055 end -= size;
1083 assert(end < start); 1056 assert(end < start);
1084 assert(end < size); 1057 assert(end < size);
1085 } 1058 }
1086 } 1059 }
1087 1060
1088 bool get isEmpty => end == start; 1061 bool get isEmpty => end == start;
1089 1062
1090 int get length => 1063 int get length => start > end ? size + end - start : end - start;
1091 start > end ? size + end - start : end - start;
1092 1064
1093 int get linearLength => 1065 int get linearLength => start > end ? size - start : end - start;
1094 start > end ? size - start : end - start;
1095 1066
1096 int get free => 1067 int get free => start > end ? start - end - 1 : size + start - end - 1;
1097 start > end ? start - end - 1 : size + start - end - 1;
1098 1068
1099 int get linearFree { 1069 int get linearFree {
1100 if (start > end) return start - end - 1; 1070 if (start > end) return start - end - 1;
1101 if (start == 0) return size - end - 1; 1071 if (start == 0) return size - end - 1;
1102 return size - end; 1072 return size - end;
1103 } 1073 }
1104 1074
1105 List<int> read(int bytes) { 1075 List<int> read(int bytes) {
1106 if (bytes == null) { 1076 if (bytes == null) {
1107 bytes = length; 1077 bytes = length;
1108 } else { 1078 } else {
1109 bytes = min(bytes, length); 1079 bytes = min(bytes, length);
1110 } 1080 }
1111 if (bytes == 0) return null; 1081 if (bytes == 0) return null;
1112 List<int> result = new Uint8List(bytes); 1082 List<int> result = new Uint8List(bytes);
1113 int bytesRead = 0; 1083 int bytesRead = 0;
1114 // Loop over zero, one, or two linear data ranges. 1084 // Loop over zero, one, or two linear data ranges.
1115 while (bytesRead < bytes) { 1085 while (bytesRead < bytes) {
1116 int toRead = min(bytes - bytesRead, linearLength); 1086 int toRead = min(bytes - bytesRead, linearLength);
1117 result.setRange(bytesRead, 1087 result.setRange(bytesRead, bytesRead + toRead, data, start);
1118 bytesRead + toRead,
1119 data,
1120 start);
1121 advanceStart(toRead); 1088 advanceStart(toRead);
1122 bytesRead += toRead; 1089 bytesRead += toRead;
1123 } 1090 }
1124 return result; 1091 return result;
1125 } 1092 }
1126 1093
1127 int write(List<int> inputData, int offset, int bytes) { 1094 int write(List<int> inputData, int offset, int bytes) {
1128 if (bytes > free) { 1095 if (bytes > free) {
1129 bytes = free; 1096 bytes = free;
1130 } 1097 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 int bytes = socket.write(data, start, toWrite); 1133 int bytes = socket.write(data, start, toWrite);
1167 advanceStart(bytes); 1134 advanceStart(bytes);
1168 if (bytes < toWrite) { 1135 if (bytes < toWrite) {
1169 // The socket has blocked while we have data to write. 1136 // The socket has blocked while we have data to write.
1170 return true; 1137 return true;
1171 } 1138 }
1172 } 1139 }
1173 } 1140 }
1174 } 1141 }
1175 1142
1176
1177 abstract class _SecureFilter { 1143 abstract class _SecureFilter {
1178 external factory _SecureFilter(); 1144 external factory _SecureFilter();
1179 1145
1180 void connect(String hostName, 1146 void connect(
1181 SecurityContext context, 1147 String hostName,
1182 bool is_server, 1148 SecurityContext context,
1183 bool requestClientCertificate, 1149 bool is_server,
1184 bool requireClientCertificate, 1150 bool requestClientCertificate,
1185 Uint8List protocols); 1151 bool requireClientCertificate,
1152 Uint8List protocols);
1186 void destroy(); 1153 void destroy();
1187 void handshake(); 1154 void handshake();
1188 String selectedProtocol(); 1155 String selectedProtocol();
1189 void rehandshake(); 1156 void rehandshake();
1190 void renegotiate(bool useSessionCache, 1157 void renegotiate(bool useSessionCache, bool requestClientCertificate,
1191 bool requestClientCertificate, 1158 bool requireClientCertificate);
1192 bool requireClientCertificate);
1193 void init(); 1159 void init();
1194 X509Certificate get peerCertificate; 1160 X509Certificate get peerCertificate;
1195 int processBuffer(int bufferIndex); 1161 int processBuffer(int bufferIndex);
1196 void registerBadCertificateCallback(Function callback); 1162 void registerBadCertificateCallback(Function callback);
1197 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); 1163 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);
1198 1164
1199 // This call may cause a reference counted pointer in the native 1165 // This call may cause a reference counted pointer in the native
1200 // implementation to be retained. It should only be called when the resulting 1166 // implementation to be retained. It should only be called when the resulting
1201 // value is passed to the IO service through a call to dispatch(). 1167 // value is passed to the IO service through a call to dispatch().
1202 int _pointer(); 1168 int _pointer();
1203 1169
1204 List<_ExternalBuffer> get buffers; 1170 List<_ExternalBuffer> get buffers;
1205 } 1171 }
1206 1172
1207 /** A secure networking exception caused by a failure in the 1173 /** A secure networking exception caused by a failure in the
1208 * TLS/SSL protocol. 1174 * TLS/SSL protocol.
1209 */ 1175 */
1210 class TlsException implements IOException { 1176 class TlsException implements IOException {
1211 final String type; 1177 final String type;
1212 final String message; 1178 final String message;
1213 final OSError osError; 1179 final OSError osError;
1214 1180
1215 const TlsException([String message = "", 1181 const TlsException([String message = "", OSError osError = null])
1216 OSError osError = null]) 1182 : this._("TlsException", message, osError);
1217 : this._("TlsException", message, osError);
1218 1183
1219 const TlsException._(this.type, this.message, this.osError); 1184 const TlsException._(this.type, this.message, this.osError);
1220 1185
1221 String toString() { 1186 String toString() {
1222 StringBuffer sb = new StringBuffer(); 1187 StringBuffer sb = new StringBuffer();
1223 sb.write(type); 1188 sb.write(type);
1224 if (!message.isEmpty) { 1189 if (!message.isEmpty) {
1225 sb.write(": $message"); 1190 sb.write(": $message");
1226 if (osError != null) { 1191 if (osError != null) {
1227 sb.write(" ($osError)"); 1192 sb.write(" ($osError)");
1228 } 1193 }
1229 } else if (osError != null) { 1194 } else if (osError != null) {
1230 sb.write(": $osError"); 1195 sb.write(": $osError");
1231 } 1196 }
1232 return sb.toString(); 1197 return sb.toString();
1233 } 1198 }
1234 } 1199 }
1235 1200
1236
1237 /** 1201 /**
1238 * An exception that happens in the handshake phase of establishing 1202 * An exception that happens in the handshake phase of establishing
1239 * a secure network connection. 1203 * a secure network connection.
1240 */ 1204 */
1241 class HandshakeException extends TlsException { 1205 class HandshakeException extends TlsException {
1242 const HandshakeException([String message = "", 1206 const HandshakeException([String message = "", OSError osError = null])
1243 OSError osError = null]) 1207 : super._("HandshakeException", message, osError);
1244 : super._("HandshakeException", message, osError);
1245 } 1208 }
1246 1209
1247
1248 /** 1210 /**
1249 * An exception that happens in the handshake phase of establishing 1211 * An exception that happens in the handshake phase of establishing
1250 * a secure network connection, when looking up or verifying a 1212 * a secure network connection, when looking up or verifying a
1251 * certificate. 1213 * certificate.
1252 */ 1214 */
1253 class CertificateException extends TlsException { 1215 class CertificateException extends TlsException {
1254 const CertificateException([String message = "", 1216 const CertificateException([String message = "", OSError osError = null])
1255 OSError osError = null]) 1217 : super._("CertificateException", message, osError);
1256 : super._("CertificateException", message, osError);
1257 } 1218 }
OLDNEW
« no previous file with comments | « sdk/lib/io/secure_server_socket.dart ('k') | sdk/lib/io/security_context.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698