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 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 bufferedData, | 484 bufferedData, |
485 requestClientCertificate, | 485 requestClientCertificate, |
486 requireClientCertificate, | 486 requireClientCertificate, |
487 sendClientCertificate, | 487 sendClientCertificate, |
488 onBadCertificate) | 488 onBadCertificate) |
489 ._handshakeComplete.future; | 489 ._handshakeComplete.future; |
490 }); | 490 }); |
491 } | 491 } |
492 | 492 |
493 _RawSecureSocket( | 493 _RawSecureSocket( |
494 InternetAddress this.address, | 494 this.address, |
495 int requestedPort, | 495 int requestedPort, |
496 String this.certificateName, | 496 this.certificateName, |
497 bool this.is_server, | 497 this.is_server, |
498 RawSocket socket, | 498 RawSocket socket, |
499 StreamSubscription this._socketSubscription, | 499 this._socketSubscription, |
500 List<int> this._bufferedData, | 500 this._bufferedData, |
501 bool this.requestClientCertificate, | 501 this.requestClientCertificate, |
502 bool this.requireClientCertificate, | 502 this.requireClientCertificate, |
503 bool this.sendClientCertificate, | 503 this.sendClientCertificate, |
504 bool this.onBadCertificate(X509Certificate certificate)) { | 504 this.onBadCertificate(X509Certificate certificate)) { |
505 _controller = new StreamController<RawSocketEvent>( | 505 _controller = new StreamController<RawSocketEvent>( |
506 sync: true, | 506 sync: true, |
507 onListen: _onSubscriptionStateChange, | 507 onListen: _onSubscriptionStateChange, |
508 onPause: _onPauseStateChange, | 508 onPause: _onPauseStateChange, |
509 onResume: _onPauseStateChange, | 509 onResume: _onPauseStateChange, |
510 onCancel: _onSubscriptionStateChange); | 510 onCancel: _onSubscriptionStateChange); |
511 _stream = _controller.stream; | 511 _stream = _controller.stream; |
512 // Throw an ArgumentError if any field is invalid. After this, all | 512 // Throw an ArgumentError if any field is invalid. After this, all |
513 // errors will be reported through the future or the stream. | 513 // errors will be reported through the future or the stream. |
514 _secureFilter.init(); | 514 _secureFilter.init(); |
(...skipping 13 matching lines...) Expand all Loading... |
528 _socket = rawSocket; | 528 _socket = rawSocket; |
529 _socket.readEventsEnabled = true; | 529 _socket.readEventsEnabled = true; |
530 _socket.writeEventsEnabled = false; | 530 _socket.writeEventsEnabled = false; |
531 if (_socketSubscription == null) { | 531 if (_socketSubscription == null) { |
532 // If a current subscription is provided use this otherwise | 532 // If a current subscription is provided use this otherwise |
533 // create a new one. | 533 // create a new one. |
534 _socketSubscription = _socket.listen(_eventDispatcher, | 534 _socketSubscription = _socket.listen(_eventDispatcher, |
535 onError: _reportError, | 535 onError: _reportError, |
536 onDone: _doneHandler); | 536 onDone: _doneHandler); |
537 } else { | 537 } else { |
538 _socketSubscription.onData(_eventDispatcher); | 538 _socketSubscription |
539 _socketSubscription.onError(_reportError); | 539 ..onData(_eventDispatcher) |
540 _socketSubscription.onDone(_doneHandler); | 540 ..onError(_reportError) |
| 541 ..onDone(_doneHandler); |
541 } | 542 } |
542 _secureFilter.connect(address.host, | 543 _secureFilter.connect(address.host, |
543 (address as dynamic)._in_addr, | 544 (address as dynamic)._in_addr, |
544 port, | 545 port, |
545 is_server, | 546 is_server, |
546 certificateName, | 547 certificateName, |
547 requestClientCertificate || | 548 requestClientCertificate || |
548 requireClientCertificate, | 549 requireClientCertificate, |
549 requireClientCertificate, | 550 requireClientCertificate, |
550 sendClientCertificate); | 551 sendClientCertificate); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 } | 602 } |
602 } | 603 } |
603 | 604 |
604 int get port => _socket.port; | 605 int get port => _socket.port; |
605 | 606 |
606 InternetAddress get remoteAddress => _socket.remoteAddress; | 607 InternetAddress get remoteAddress => _socket.remoteAddress; |
607 | 608 |
608 int get remotePort => _socket.remotePort; | 609 int get remotePort => _socket.remotePort; |
609 | 610 |
610 int available() { | 611 int available() { |
611 if (_status != CONNECTED) return 0; | 612 return _status != CONNECTED ? 0 |
612 return _secureFilter.buffers[READ_PLAINTEXT].length; | 613 : _secureFilter.buffers[READ_PLAINTEXT].length; |
613 } | 614 } |
614 | 615 |
615 Future<RawSecureSocket> close() { | 616 Future<RawSecureSocket> close() { |
616 shutdown(SocketDirection.BOTH); | 617 shutdown(SocketDirection.BOTH); |
617 return _closeCompleter.future; | 618 return _closeCompleter.future; |
618 } | 619 } |
619 | 620 |
620 void _completeCloseCompleter([dummy]) { | 621 void _completeCloseCompleter([dummy]) { |
621 if (!_closeCompleter.isCompleted) _closeCompleter.complete(this); | 622 if (!_closeCompleter.isCompleted) _closeCompleter.complete(this); |
622 } | 623 } |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 } | 1062 } |
1062 } | 1063 } |
1063 | 1064 |
1064 | 1065 |
1065 /** | 1066 /** |
1066 * A circular buffer backed by an external byte array. Accessed from | 1067 * A circular buffer backed by an external byte array. Accessed from |
1067 * both C++ and Dart code in an unsynchronized way, with one reading | 1068 * both C++ and Dart code in an unsynchronized way, with one reading |
1068 * and one writing. All updates to start and end are done by Dart code. | 1069 * and one writing. All updates to start and end are done by Dart code. |
1069 */ | 1070 */ |
1070 class _ExternalBuffer { | 1071 class _ExternalBuffer { |
| 1072 List data; // This will be a ExternalByteArray, backed by C allocated data. |
| 1073 int start; |
| 1074 int end; |
| 1075 final size; |
| 1076 |
1071 _ExternalBuffer(this.size) { | 1077 _ExternalBuffer(this.size) { |
1072 start = size~/2; | 1078 start = end = size ~/ 2; |
1073 end = size~/2; | |
1074 } | 1079 } |
1075 | 1080 |
1076 void advanceStart(int bytes) { | 1081 void advanceStart(int bytes) { |
1077 assert(start > end || start + bytes <= end); | 1082 assert(start > end || start + bytes <= end); |
1078 start += bytes; | 1083 start += bytes; |
1079 if (start >= size) { | 1084 if (start >= size) { |
1080 start -= size; | 1085 start -= size; |
1081 assert(start <= end); | 1086 assert(start <= end); |
1082 assert(start < size); | 1087 assert(start < size); |
1083 } | 1088 } |
1084 } | 1089 } |
1085 | 1090 |
1086 void advanceEnd(int bytes) { | 1091 void advanceEnd(int bytes) { |
1087 assert(start <= end || start > end + bytes); | 1092 assert(start <= end || start > end + bytes); |
1088 end += bytes; | 1093 end += bytes; |
1089 if (end >= size) { | 1094 if (end >= size) { |
1090 end -= size; | 1095 end -= size; |
1091 assert(end < start); | 1096 assert(end < start); |
1092 assert(end < size); | 1097 assert(end < size); |
1093 } | 1098 } |
1094 } | 1099 } |
1095 | 1100 |
1096 bool get isEmpty => end == start; | 1101 bool get isEmpty => end == start; |
1097 | 1102 |
1098 int get length { | 1103 int get length => |
1099 if (start > end) return size + end - start; | 1104 start > end ? size + end - start : end - start; |
1100 return end - start; | |
1101 } | |
1102 | 1105 |
1103 int get linearLength { | 1106 int get linearLength => |
1104 if (start > end) return size - start; | 1107 start > end ? size - start : end - start; |
1105 return end - start; | |
1106 } | |
1107 | 1108 |
1108 int get free { | 1109 int get free => |
1109 if (start > end) return start - end - 1; | 1110 start > end ? start - end - 1 : size + start - end - 1; |
1110 return size + start - end - 1; | |
1111 } | |
1112 | 1111 |
1113 int get linearFree { | 1112 int get linearFree { |
1114 if (start > end) return start - end - 1; | 1113 if (start > end) return start - end - 1; |
1115 if (start == 0) return size - end - 1; | 1114 if (start == 0) return size - end - 1; |
1116 return size - end; | 1115 return size - end; |
1117 } | 1116 } |
1118 | 1117 |
1119 List<int> read(int bytes) { | 1118 List<int> read(int bytes) { |
1120 if (bytes == null) { | 1119 if (bytes == null) { |
1121 bytes = length; | 1120 bytes = length; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 var toWrite = linearLength; | 1177 var toWrite = linearLength; |
1179 if (toWrite == 0) return false; | 1178 if (toWrite == 0) return false; |
1180 int bytes = socket.write(data, start, toWrite); | 1179 int bytes = socket.write(data, start, toWrite); |
1181 advanceStart(bytes); | 1180 advanceStart(bytes); |
1182 if (bytes < toWrite) { | 1181 if (bytes < toWrite) { |
1183 // The socket has blocked while we have data to write. | 1182 // The socket has blocked while we have data to write. |
1184 return true; | 1183 return true; |
1185 } | 1184 } |
1186 } | 1185 } |
1187 } | 1186 } |
1188 | |
1189 List data; // This will be a ExternalByteArray, backed by C allocated data. | |
1190 int start; | |
1191 int end; | |
1192 final size; | |
1193 } | 1187 } |
1194 | 1188 |
1195 | 1189 |
1196 abstract class _SecureFilter { | 1190 abstract class _SecureFilter { |
1197 external factory _SecureFilter(); | 1191 external factory _SecureFilter(); |
1198 | 1192 |
1199 void connect(String hostName, | 1193 void connect(String hostName, |
1200 Uint8List addr, | 1194 Uint8List addr, |
1201 int port, | 1195 int port, |
1202 bool is_server, | 1196 bool is_server, |
(...skipping 22 matching lines...) Expand all Loading... |
1225 */ | 1219 */ |
1226 class TlsException implements IOException { | 1220 class TlsException implements IOException { |
1227 final String type; | 1221 final String type; |
1228 final String message; | 1222 final String message; |
1229 final OSError osError; | 1223 final OSError osError; |
1230 | 1224 |
1231 const TlsException([String message = "", | 1225 const TlsException([String message = "", |
1232 OSError osError = null]) | 1226 OSError osError = null]) |
1233 : this._("TlsException", message, osError); | 1227 : this._("TlsException", message, osError); |
1234 | 1228 |
1235 const TlsException._(String this.type, | 1229 const TlsException._(this.type, this.message, this.osError); |
1236 String this.message, | |
1237 OSError this.osError); | |
1238 | 1230 |
1239 String toString() { | 1231 String toString() { |
1240 StringBuffer sb = new StringBuffer(); | 1232 StringBuffer sb = new StringBuffer(); |
1241 sb.write(type); | 1233 sb.write(type); |
1242 if (!message.isEmpty) { | 1234 if (!message.isEmpty) { |
1243 sb.write(": $message"); | 1235 sb.write(": $message"); |
1244 if (osError != null) { | 1236 if (osError != null) { |
1245 sb.write(" ($osError)"); | 1237 sb.write(" ($osError)"); |
1246 } | 1238 } |
1247 } else if (osError != null) { | 1239 } else if (osError != null) { |
(...skipping 18 matching lines...) Expand all Loading... |
1266 /** | 1258 /** |
1267 * An exception that happens in the handshake phase of establishing | 1259 * An exception that happens in the handshake phase of establishing |
1268 * a secure network connection, when looking up or verifying a | 1260 * a secure network connection, when looking up or verifying a |
1269 * certificate. | 1261 * certificate. |
1270 */ | 1262 */ |
1271 class CertificateException extends TlsException { | 1263 class CertificateException extends TlsException { |
1272 const CertificateException([String message = "", | 1264 const CertificateException([String message = "", |
1273 OSError osError = null]) | 1265 OSError osError = null]) |
1274 : super._("CertificateException", message, osError); | 1266 : super._("CertificateException", message, osError); |
1275 } | 1267 } |
OLD | NEW |