Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A high-level class for communicating securely over a TCP socket, using | 8 * A high-level class for communicating securely over a TCP socket, using |
| 9 * TLS and SSL. The [SecureSocket] exposes both a [Stream] and an | 9 * TLS and SSL. The [SecureSocket] exposes both a [Stream] and an |
| 10 * [IOSink] interface, making it ideal for using together with | 10 * [IOSink] interface, making it ideal for using together with |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |