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

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

Issue 625953002: Support for the ALPN extension of the TLS protocol for Client and Server (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add test for ALPN negotiation Created 6 years, 2 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 | Annotate | Revision Log
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 21 matching lines...) Expand all
32 * The handler receives the [X509Certificate], and can inspect it and 32 * The handler receives the [X509Certificate], and can inspect it and
33 * decide (or let the user decide) whether to accept 33 * decide (or let the user decide) whether to accept
34 * the connection or not. The handler should return true 34 * the connection or not. The handler should return true
35 * to continue the [SecureSocket] connection. 35 * to continue the [SecureSocket] connection.
36 */ 36 */
37 static Future<SecureSocket> connect( 37 static Future<SecureSocket> connect(
38 host, 38 host,
39 int port, 39 int port,
40 {bool sendClientCertificate: false, 40 {bool sendClientCertificate: false,
41 String certificateName, 41 String certificateName,
42 bool onBadCertificate(X509Certificate certificate)}) { 42 bool onBadCertificate(X509Certificate certificate),
43 List<String> supportedProtocols}) {
43 return RawSecureSocket.connect(host, 44 return RawSecureSocket.connect(host,
44 port, 45 port,
45 sendClientCertificate: sendClientCertificate, 46 sendClientCertificate: sendClientCertificate,
46 certificateName: certificateName, 47 certificateName: certificateName,
47 onBadCertificate: onBadCertificate) 48 onBadCertificate: onBadCertificate,
49 supportedProtocols: supportedProtocols)
48 .then((rawSocket) => new SecureSocket._(rawSocket)); 50 .then((rawSocket) => new SecureSocket._(rawSocket));
49 } 51 }
50 52
51 /** 53 /**
52 * Takes an already connected [socket] and starts client side TLS 54 * Takes an already connected [socket] and starts client side TLS
53 * handshake to make the communication secure. When the returned 55 * handshake to make the communication secure. When the returned
54 * future completes the [SecureSocket] has completed the TLS 56 * future completes the [SecureSocket] has completed the TLS
55 * handshake. Using this function requires that the other end of the 57 * handshake. Using this function requires that the other end of the
56 * connection is prepared for TLS handshake. 58 * connection is prepared for TLS handshake.
57 * 59 *
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 * 117 *
116 * See [SecureServerSocket.bind] for more information on the 118 * See [SecureServerSocket.bind] for more information on the
117 * arguments. 119 * arguments.
118 * 120 *
119 */ 121 */
120 static Future<SecureSocket> secureServer( 122 static Future<SecureSocket> secureServer(
121 Socket socket, 123 Socket socket,
122 String certificateName, 124 String certificateName,
123 {List<int> bufferedData, 125 {List<int> bufferedData,
124 bool requestClientCertificate: false, 126 bool requestClientCertificate: false,
125 bool requireClientCertificate: false}) { 127 bool requireClientCertificate: false,
128 List<String> supportedProtocols}) {
126 var completer = new Completer(); 129 var completer = new Completer();
127 (socket as dynamic)._detachRaw() 130 (socket as dynamic)._detachRaw()
128 .then((detachedRaw) { 131 .then((detachedRaw) {
129 return RawSecureSocket.secureServer( 132 return RawSecureSocket.secureServer(
130 detachedRaw[0], 133 detachedRaw[0],
131 certificateName, 134 certificateName,
132 subscription: detachedRaw[1], 135 subscription: detachedRaw[1],
133 bufferedData: bufferedData, 136 bufferedData: bufferedData,
134 requestClientCertificate: requestClientCertificate, 137 requestClientCertificate: requestClientCertificate,
135 requireClientCertificate: requireClientCertificate); 138 requireClientCertificate: requireClientCertificate,
139 supportedProtocols: supportedProtocols);
136 }) 140 })
137 .then((raw) { 141 .then((raw) {
138 completer.complete(new SecureSocket._(raw)); 142 completer.complete(new SecureSocket._(raw));
139 }); 143 });
140 return completer.future; 144 return completer.future;
141 } 145 }
142 146
143 /** 147 /**
144 * Get the peer certificate for a connected SecureSocket. If this 148 * Get the peer certificate for a connected SecureSocket. If this
145 * SecureSocket is the server end of a secure socket connection, 149 * SecureSocket is the server end of a secure socket connection,
146 * [peerCertificate] will return the client certificate, or null, if no 150 * [peerCertificate] will return the client certificate, or null, if no
147 * client certificate was received. If it is the client end, 151 * client certificate was received. If it is the client end,
148 * [peerCertificate] will return the server's certificate. 152 * [peerCertificate] will return the server's certificate.
149 */ 153 */
150 X509Certificate get peerCertificate; 154 X509Certificate get peerCertificate;
151 155
152 /** 156 /**
157 * Get the protocol which was selected during protocol negotiation.
158 */
159 String get selectedProtocol;
160
161 /**
153 * Renegotiate an existing secure connection, renewing the session keys 162 * Renegotiate an existing secure connection, renewing the session keys
154 * and possibly changing the connection properties. 163 * and possibly changing the connection properties.
155 * 164 *
156 * This repeats the SSL or TLS handshake, with options that allow clearing 165 * This repeats the SSL or TLS handshake, with options that allow clearing
157 * the session cache and requesting a client certificate. 166 * the session cache and requesting a client certificate.
158 */ 167 */
159 void renegotiate({bool useSessionCache: true, 168 void renegotiate({bool useSessionCache: true,
160 bool requestClientCertificate: false, 169 bool requestClientCertificate: false,
161 bool requireClientCertificate: false}); 170 bool requireClientCertificate: false});
162 171
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 * The handler receives the [X509Certificate], and can inspect it and 247 * The handler receives the [X509Certificate], and can inspect it and
239 * decide (or let the user decide) whether to accept 248 * decide (or let the user decide) whether to accept
240 * the connection or not. The handler should return true 249 * the connection or not. The handler should return true
241 * to continue the [RawSecureSocket] connection. 250 * to continue the [RawSecureSocket] connection.
242 */ 251 */
243 static Future<RawSecureSocket> connect( 252 static Future<RawSecureSocket> connect(
244 host, 253 host,
245 int port, 254 int port,
246 {bool sendClientCertificate: false, 255 {bool sendClientCertificate: false,
247 String certificateName, 256 String certificateName,
248 bool onBadCertificate(X509Certificate certificate)}) { 257 bool onBadCertificate(X509Certificate certificate),
258 List<String> supportedProtocols}) {
249 _RawSecureSocket._verifyFields( 259 _RawSecureSocket._verifyFields(
250 host, 260 host,
251 port, 261 port,
252 certificateName, 262 certificateName,
253 false, 263 false,
254 false, 264 false,
255 false, 265 false,
256 sendClientCertificate, 266 sendClientCertificate,
257 onBadCertificate); 267 onBadCertificate);
258 return RawSocket.connect(host, port) 268 return RawSocket.connect(host, port)
259 .then((socket) { 269 .then((socket) {
260 return secure(socket, 270 return secure(socket,
261 sendClientCertificate: sendClientCertificate, 271 sendClientCertificate: sendClientCertificate,
262 certificateName: certificateName, 272 certificateName: certificateName,
263 onBadCertificate: onBadCertificate); 273 onBadCertificate: onBadCertificate,
274 supportedProtocols: supportedProtocols);
264 }); 275 });
265 } 276 }
266 277
267 /** 278 /**
268 * Takes an already connected [socket] and starts client side TLS 279 * Takes an already connected [socket] and starts client side TLS
269 * handshake to make the communication secure. When the returned 280 * handshake to make the communication secure. When the returned
270 * future completes the [RawSecureSocket] has completed the TLS 281 * future completes the [RawSecureSocket] has completed the TLS
271 * handshake. Using this function requires that the other end of the 282 * handshake. Using this function requires that the other end of the
272 * connection is prepared for TLS handshake. 283 * connection is prepared for TLS handshake.
273 * 284 *
(...skipping 17 matching lines...) Expand all
291 * 302 *
292 * See [connect] for more information on the arguments. 303 * See [connect] for more information on the arguments.
293 * 304 *
294 */ 305 */
295 static Future<RawSecureSocket> secure( 306 static Future<RawSecureSocket> secure(
296 RawSocket socket, 307 RawSocket socket,
297 {StreamSubscription subscription, 308 {StreamSubscription subscription,
298 host, 309 host,
299 bool sendClientCertificate: false, 310 bool sendClientCertificate: false,
300 String certificateName, 311 String certificateName,
301 bool onBadCertificate(X509Certificate certificate)}) { 312 bool onBadCertificate(X509Certificate certificate),
313 List<String> supportedProtocols}) {
302 socket.readEventsEnabled = false; 314 socket.readEventsEnabled = false;
303 socket.writeEventsEnabled = false; 315 socket.writeEventsEnabled = false;
304 return _RawSecureSocket.connect( 316 return _RawSecureSocket.connect(
305 host != null ? host : socket.address.host, 317 host != null ? host : socket.address.host,
306 socket.port, 318 socket.port,
307 certificateName, 319 certificateName,
308 is_server: false, 320 is_server: false,
309 socket: socket, 321 socket: socket,
310 subscription: subscription, 322 subscription: subscription,
311 sendClientCertificate: sendClientCertificate, 323 sendClientCertificate: sendClientCertificate,
312 onBadCertificate: onBadCertificate); 324 onBadCertificate: onBadCertificate,
325 supportedProtocols: supportedProtocols);
313 } 326 }
314 327
315 /** 328 /**
316 * Takes an already connected [socket] and starts server side TLS 329 * Takes an already connected [socket] and starts server side TLS
317 * handshake to make the communication secure. When the returned 330 * handshake to make the communication secure. When the returned
318 * future completes the [RawSecureSocket] has completed the TLS 331 * future completes the [RawSecureSocket] has completed the TLS
319 * handshake. Using this function requires that the other end of the 332 * handshake. Using this function requires that the other end of the
320 * connection is going to start the TLS handshake. 333 * connection is going to start the TLS handshake.
321 * 334 *
322 * If the [socket] already has a subscription, pass the existing 335 * If the [socket] already has a subscription, pass the existing
(...skipping 11 matching lines...) Expand all
334 * See [RawSecureServerSocket.bind] for more information on the 347 * See [RawSecureServerSocket.bind] for more information on the
335 * arguments. 348 * arguments.
336 * 349 *
337 */ 350 */
338 static Future<RawSecureSocket> secureServer( 351 static Future<RawSecureSocket> secureServer(
339 RawSocket socket, 352 RawSocket socket,
340 String certificateName, 353 String certificateName,
341 {StreamSubscription subscription, 354 {StreamSubscription subscription,
342 List<int> bufferedData, 355 List<int> bufferedData,
343 bool requestClientCertificate: false, 356 bool requestClientCertificate: false,
344 bool requireClientCertificate: false}) { 357 bool requireClientCertificate: false,
358 List<String> supportedProtocols}) {
345 socket.readEventsEnabled = false; 359 socket.readEventsEnabled = false;
346 socket.writeEventsEnabled = false; 360 socket.writeEventsEnabled = false;
347 return _RawSecureSocket.connect( 361 return _RawSecureSocket.connect(
348 socket.address, 362 socket.address,
349 socket.remotePort, 363 socket.remotePort,
350 certificateName, 364 certificateName,
351 is_server: true, 365 is_server: true,
352 socket: socket, 366 socket: socket,
353 subscription: subscription, 367 subscription: subscription,
354 bufferedData: bufferedData, 368 bufferedData: bufferedData,
355 requestClientCertificate: requestClientCertificate, 369 requestClientCertificate: requestClientCertificate,
356 requireClientCertificate: requireClientCertificate); 370 requireClientCertificate: requireClientCertificate,
371 supportedProtocols: supportedProtocols);
357 } 372 }
358 373
359 /** 374 /**
360 * Renegotiate an existing secure connection, renewing the session keys 375 * Renegotiate an existing secure connection, renewing the session keys
361 * and possibly changing the connection properties. 376 * and possibly changing the connection properties.
362 * 377 *
363 * This repeats the SSL or TLS handshake, with options that allow clearing 378 * This repeats the SSL or TLS handshake, with options that allow clearing
364 * the session cache and requesting a client certificate. 379 * the session cache and requesting a client certificate.
365 */ 380 */
366 void renegotiate({bool useSessionCache: true, 381 void renegotiate({bool useSessionCache: true,
367 bool requestClientCertificate: false, 382 bool requestClientCertificate: false,
368 bool requireClientCertificate: false}); 383 bool requireClientCertificate: false});
369 384
370 /** 385 /**
371 * Get the peer certificate for a connected RawSecureSocket. If this 386 * Get the peer certificate for a connected RawSecureSocket. If this
372 * RawSecureSocket is the server end of a secure socket connection, 387 * RawSecureSocket is the server end of a secure socket connection,
373 * [peerCertificate] will return the client certificate, or null, if no 388 * [peerCertificate] will return the client certificate, or null, if no
374 * client certificate was received. If it is the client end, 389 * client certificate was received. If it is the client end,
375 * [peerCertificate] will return the server's certificate. 390 * [peerCertificate] will return the server's certificate.
376 */ 391 */
377 X509Certificate get peerCertificate; 392 X509Certificate get peerCertificate;
393
394 /**
395 * Get the protocol which was selected during protocol negotiation.
396 */
397 String get selectedProtocol;
378 } 398 }
379 399
380 400
381 /** 401 /**
382 * X509Certificate represents an SSL certificate, with accessors to 402 * X509Certificate represents an SSL certificate, with accessors to
383 * get the fields of the certificate. 403 * get the fields of the certificate.
384 */ 404 */
385 class X509Certificate { 405 class X509Certificate {
386 X509Certificate(this.subject, 406 X509Certificate(this.subject,
387 this.issuer, 407 this.issuer,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 bool _closedRead = false; // The secure socket has fired an onClosed event. 472 bool _closedRead = false; // The secure socket has fired an onClosed event.
453 bool _closedWrite = false; // The secure socket has been closed for writing. 473 bool _closedWrite = false; // The secure socket has been closed for writing.
454 Completer _closeCompleter = new Completer(); // The network socket is gone. 474 Completer _closeCompleter = new Completer(); // The network socket is gone.
455 _FilterStatus _filterStatus = new _FilterStatus(); 475 _FilterStatus _filterStatus = new _FilterStatus();
456 bool _connectPending = true; 476 bool _connectPending = true;
457 bool _filterPending = false; 477 bool _filterPending = false;
458 bool _filterActive = false; 478 bool _filterActive = false;
459 479
460 _SecureFilter _secureFilter = new _SecureFilter(); 480 _SecureFilter _secureFilter = new _SecureFilter();
461 int _filterPointer; 481 int _filterPointer;
482 String _selectedProtocol;
462 483
463 static Future<_RawSecureSocket> connect( 484 static Future<_RawSecureSocket> connect(
464 host, 485 host,
465 int requestedPort, 486 int requestedPort,
466 String certificateName, 487 String certificateName,
467 {bool is_server, 488 {bool is_server,
468 RawSocket socket, 489 RawSocket socket,
469 StreamSubscription subscription, 490 StreamSubscription subscription,
470 List<int> bufferedData, 491 List<int> bufferedData,
471 bool requestClientCertificate: false, 492 bool requestClientCertificate: false,
472 bool requireClientCertificate: false, 493 bool requireClientCertificate: false,
473 bool sendClientCertificate: false, 494 bool sendClientCertificate: false,
474 bool onBadCertificate(X509Certificate certificate)}) { 495 bool onBadCertificate(X509Certificate certificate),
496 List<String> supportedProtocols}) {
475 _verifyFields(host, requestedPort, certificateName, is_server, 497 _verifyFields(host, requestedPort, certificateName, is_server,
476 requestClientCertificate, requireClientCertificate, 498 requestClientCertificate, requireClientCertificate,
477 sendClientCertificate, onBadCertificate); 499 sendClientCertificate, onBadCertificate);
478 if (host is InternetAddress) host = host.host; 500 if (host is InternetAddress) host = host.host;
479 var address = socket.address; 501 var address = socket.address;
480 if (host != null) address = address._cloneWithNewHost(host); 502 if (host != null) address = address._cloneWithNewHost(host);
481 return new _RawSecureSocket(address, 503 return new _RawSecureSocket(address,
482 requestedPort, 504 requestedPort,
483 certificateName, 505 certificateName,
484 is_server, 506 is_server,
485 socket, 507 socket,
486 subscription, 508 subscription,
487 bufferedData, 509 bufferedData,
488 requestClientCertificate, 510 requestClientCertificate,
489 requireClientCertificate, 511 requireClientCertificate,
490 sendClientCertificate, 512 sendClientCertificate,
491 onBadCertificate) 513 onBadCertificate,
514 supportedProtocols)
492 ._handshakeComplete.future; 515 ._handshakeComplete.future;
493 } 516 }
494 517
495 _RawSecureSocket( 518 _RawSecureSocket(
496 this.address, 519 this.address,
497 int requestedPort, 520 int requestedPort,
498 this.certificateName, 521 this.certificateName,
499 this.is_server, 522 this.is_server,
500 RawSocket this._socket, 523 RawSocket this._socket,
501 this._socketSubscription, 524 this._socketSubscription,
502 this._bufferedData, 525 this._bufferedData,
503 this.requestClientCertificate, 526 this.requestClientCertificate,
504 this.requireClientCertificate, 527 this.requireClientCertificate,
505 this.sendClientCertificate, 528 this.sendClientCertificate,
506 this.onBadCertificate(X509Certificate certificate)) { 529 this.onBadCertificate(X509Certificate certificate),
530 List<String> supportedProtocols) {
507 _controller = new StreamController<RawSocketEvent>( 531 _controller = new StreamController<RawSocketEvent>(
508 sync: true, 532 sync: true,
509 onListen: _onSubscriptionStateChange, 533 onListen: _onSubscriptionStateChange,
510 onPause: _onPauseStateChange, 534 onPause: _onPauseStateChange,
511 onResume: _onPauseStateChange, 535 onResume: _onPauseStateChange,
512 onCancel: _onSubscriptionStateChange); 536 onCancel: _onSubscriptionStateChange);
513 _stream = _controller.stream; 537 _stream = _controller.stream;
514 // Throw an ArgumentError if any field is invalid. After this, all 538 // Throw an ArgumentError if any field is invalid. After this, all
515 // errors will be reported through the future or the stream. 539 // errors will be reported through the future or the stream.
516 _secureFilter.init(); 540 _secureFilter.init();
(...skipping 24 matching lines...) Expand all
541 } 565 }
542 try { 566 try {
543 _secureFilter.connect(address.host, 567 _secureFilter.connect(address.host,
544 (address as dynamic)._in_addr, 568 (address as dynamic)._in_addr,
545 port, 569 port,
546 is_server, 570 is_server,
547 certificateName, 571 certificateName,
548 requestClientCertificate || 572 requestClientCertificate ||
549 requireClientCertificate, 573 requireClientCertificate,
550 requireClientCertificate, 574 requireClientCertificate,
551 sendClientCertificate); 575 sendClientCertificate,
576 _protocolsToLengthEncoding(supportedProtocols));
552 _secureHandshake(); 577 _secureHandshake();
553 } catch (e, s) { 578 } catch (e, s) {
554 _reportError(e, s); 579 _reportError(e, s);
555 } 580 }
556 } 581 }
557 582
583 Uint8List _protocolsToLengthEncoding(List<String> protocols) {
584 if (protocols == null || protocols.length == 0) {
585 return new Uint8List(0);
586 }
587
588 // NOTE: The NSS library will treat the first protocol as the fallback
589 // protocol. The remaining ones are sorted in priority order.
590 // We therefore put the protocol least desired at the front, to make it the
591 // default.
592 List<int> bytes = [];
Søren Gjesse 2014/10/03 15:47:04 You could allocate a 255 byte Uint8List here and r
kustermann 2014/11/07 16:20:03 Did something similar. Had some discussions with L
593 _addProtocolBytes(bytes, protocols.last);
594 for (var i = 0; i < protocols.length -1; i++) {
595 _addProtocolBytes(bytes, protocols[i]);
596 }
597
598 return new Uint8List.fromList(bytes);
599 }
600
601 void _addProtocolBytes(List<int> outBytes, String protocol) {
602 var protocolBytes = UTF8.encode(protocol);
603 var len = protocolBytes.length;
604
605 if (len > 255) {
606 throw new ArgumentError(
607 'Cannot support protocols with more than 255 characters');
608 }
609 outBytes.add(len);
610 outBytes.addAll(protocolBytes);
611 }
612
558 StreamSubscription listen(void onData(RawSocketEvent data), 613 StreamSubscription listen(void onData(RawSocketEvent data),
559 {Function onError, 614 {Function onError,
560 void onDone(), 615 void onDone(),
561 bool cancelOnError}) { 616 bool cancelOnError}) {
562 _sendWriteEvent(); 617 _sendWriteEvent();
563 return _stream.listen(onData, 618 return _stream.listen(onData,
564 onError: onError, 619 onError: onError,
565 onDone: onDone, 620 onDone: onDone,
566 cancelOnError: cancelOnError); 621 cancelOnError: cancelOnError);
567 } 622 }
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 _secureFilter.buffers[WRITE_PLAINTEXT].write(data, offset, bytes); 780 _secureFilter.buffers[WRITE_PLAINTEXT].write(data, offset, bytes);
726 if (written > 0) { 781 if (written > 0) {
727 _filterStatus.writeEmpty = false; 782 _filterStatus.writeEmpty = false;
728 } 783 }
729 _scheduleFilter(); 784 _scheduleFilter();
730 return written; 785 return written;
731 } 786 }
732 787
733 X509Certificate get peerCertificate => _secureFilter.peerCertificate; 788 X509Certificate get peerCertificate => _secureFilter.peerCertificate;
734 789
790 String get selectedProtocol => _selectedProtocol;
791
735 bool _onBadCertificateWrapper(X509Certificate certificate) { 792 bool _onBadCertificateWrapper(X509Certificate certificate) {
736 if (onBadCertificate == null) return false; 793 if (onBadCertificate == null) return false;
737 var result = onBadCertificate(certificate); 794 var result = onBadCertificate(certificate);
738 if (result is bool) return result; 795 if (result is bool) return result;
739 throw new ArgumentError( 796 throw new ArgumentError(
740 "onBadCertificate callback returned non-boolean $result"); 797 "onBadCertificate callback returned non-boolean $result");
741 } 798 }
742 799
743 bool setOption(SocketOption option, bool enabled) { 800 bool setOption(SocketOption option, bool enabled) {
744 if (_socket == null) return false; 801 if (_socket == null) return false;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 requireClientCertificate); 895 requireClientCertificate);
839 _status = HANDSHAKE; 896 _status = HANDSHAKE;
840 _filterStatus.writeEmpty = false; 897 _filterStatus.writeEmpty = false;
841 _scheduleFilter(); 898 _scheduleFilter();
842 } 899 }
843 900
844 void _secureHandshakeCompleteHandler() { 901 void _secureHandshakeCompleteHandler() {
845 _status = CONNECTED; 902 _status = CONNECTED;
846 if (_connectPending) { 903 if (_connectPending) {
847 _connectPending = false; 904 _connectPending = false;
848 // We don't want user code to run synchronously in this callback. 905 try {
849 Timer.run(() => _handshakeComplete.complete(this)); 906 _selectedProtocol = _secureFilter.selectedProtocol();
907 // We don't want user code to run synchronously in this callback.
908 Timer.run(() => _handshakeComplete.complete(this));
909 } catch (error, stack) {
910 _handshakeComplete.completeError(error, stack);
911 }
850 } 912 }
851 } 913 }
852 914
853 void _onPauseStateChange() { 915 void _onPauseStateChange() {
854 if (_controller.isPaused) { 916 if (_controller.isPaused) {
855 _pauseCount++; 917 _pauseCount++;
856 } else { 918 } else {
857 _pauseCount--; 919 _pauseCount--;
858 if (_pauseCount == 0) { 920 if (_pauseCount == 0) {
859 _scheduleReadEvent(); 921 _scheduleReadEvent();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 if (_filterStatus.writeEmpty && _closedWrite && !_socketClosedWrite) { 960 if (_filterStatus.writeEmpty && _closedWrite && !_socketClosedWrite) {
899 // Checks for and handles all cases of partially closed sockets. 961 // Checks for and handles all cases of partially closed sockets.
900 shutdown(SocketDirection.SEND); 962 shutdown(SocketDirection.SEND);
901 if (_status == CLOSED) return; 963 if (_status == CLOSED) return;
902 } 964 }
903 if (_filterStatus.readEmpty && _socketClosedRead && !_closedRead) { 965 if (_filterStatus.readEmpty && _socketClosedRead && !_closedRead) {
904 if (_status == HANDSHAKE) { 966 if (_status == HANDSHAKE) {
905 _secureFilter.handshake(); 967 _secureFilter.handshake();
906 if (_status == HANDSHAKE) { 968 if (_status == HANDSHAKE) {
907 throw new HandshakeException( 969 throw new HandshakeException(
908 'Connection terminated during handshake'); 970 'xConnection terminated during handshake');
Søren Gjesse 2014/10/03 15:47:04 Accidental edit.
kustermann 2014/11/07 16:20:03 Done.
909 } 971 }
910 } 972 }
911 _closeHandler(); 973 _closeHandler();
912 } 974 }
913 if (_status == CLOSED) return; 975 if (_status == CLOSED) return;
914 if (_filterStatus.progress) { 976 if (_filterStatus.progress) {
915 _filterPending = true; 977 _filterPending = true;
916 if (_filterStatus.writePlaintextNoLongerFull) _sendWriteEvent(); 978 if (_filterStatus.writePlaintextNoLongerFull) _sendWriteEvent();
917 if (_filterStatus.readEncryptedNoLongerFull) _readSocket(); 979 if (_filterStatus.readEncryptedNoLongerFull) _readSocket();
918 if (_filterStatus.writeEncryptedNoLongerEmpty) _writeSocket(); 980 if (_filterStatus.writeEncryptedNoLongerEmpty) _writeSocket();
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 abstract class _SecureFilter { 1261 abstract class _SecureFilter {
1200 external factory _SecureFilter(); 1262 external factory _SecureFilter();
1201 1263
1202 void connect(String hostName, 1264 void connect(String hostName,
1203 Uint8List addr, 1265 Uint8List addr,
1204 int port, 1266 int port,
1205 bool is_server, 1267 bool is_server,
1206 String certificateName, 1268 String certificateName,
1207 bool requestClientCertificate, 1269 bool requestClientCertificate,
1208 bool requireClientCertificate, 1270 bool requireClientCertificate,
1209 bool sendClientCertificate); 1271 bool sendClientCertificate,
1272 Uint8List protocols);
1210 void destroy(); 1273 void destroy();
1211 void handshake(); 1274 void handshake();
1212 void rehandshake(); 1275 void rehandshake();
1213 void renegotiate(bool useSessionCache, 1276 void renegotiate(bool useSessionCache,
1214 bool requestClientCertificate, 1277 bool requestClientCertificate,
1215 bool requireClientCertificate); 1278 bool requireClientCertificate);
1216 void init(); 1279 void init();
1217 X509Certificate get peerCertificate; 1280 X509Certificate get peerCertificate;
1218 int processBuffer(int bufferIndex); 1281 int processBuffer(int bufferIndex);
1219 void registerBadCertificateCallback(Function callback); 1282 void registerBadCertificateCallback(Function callback);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 /** 1330 /**
1268 * An exception that happens in the handshake phase of establishing 1331 * An exception that happens in the handshake phase of establishing
1269 * a secure network connection, when looking up or verifying a 1332 * a secure network connection, when looking up or verifying a
1270 * certificate. 1333 * certificate.
1271 */ 1334 */
1272 class CertificateException extends TlsException { 1335 class CertificateException extends TlsException {
1273 const CertificateException([String message = "", 1336 const CertificateException([String message = "",
1274 OSError osError = null]) 1337 OSError osError = null])
1275 : super._("CertificateException", message, osError); 1338 : super._("CertificateException", message, osError);
1276 } 1339 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698