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

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

Issue 11467004: Enable client certificates in SecureSocket and SecureServerSocket (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 years 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
« no previous file with comments | « sdk/lib/io/secure_server_socket.dart ('k') | tests/standalone/io/pkcert/cert9.db » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * SecureSocket provides a secure (SSL or TLS) client connection to a server. 6 * SecureSocket provides a secure (SSL or TLS) client connection to a server.
7 * The certificate provided by the server is checked 7 * The certificate provided by the server is checked
8 * using the certificate database provided in setCertificateDatabase. 8 * using the certificate database provided in setCertificateDatabase.
9 */ 9 */
10 abstract class SecureSocket implements Socket { 10 abstract class SecureSocket implements Socket {
11 /** 11 /**
12 * Constructs a new secure client socket and connect it to the given 12 * Constructs a new secure client socket and connect it to the given
13 * host on the given port. The returned socket is not yet connected 13 * host on the given port. The returned socket is not yet connected
14 * but ready for registration of callbacks. 14 * but ready for registration of callbacks. If sendClientCertificate is
15 * set to true, the socket will send a client certificate if one is
16 * requested by the server. If clientCertificate is the nickname of
17 * a certificate in the certificate database, that certificate will be sent.
18 * If clientCertificate is null, which is the usual use case, an
19 * appropriate certificate will be searched for in the database and
20 * sent automatically, based on what the server says it will accept.
15 */ 21 */
16 factory SecureSocket(String host, int port) => new _SecureSocket(host, port); 22 factory SecureSocket(String host,
23 int port,
24 {bool sendClientCertificate: false,
25 String certificateName}) {
26 return new _SecureSocket(host,
27 port,
28 certificateName,
29 is_server: false,
30 sendClientCertificate: sendClientCertificate);
31 }
17 32
18 /** 33 /**
19 * Install a handler for unverifiable certificates. The handler can inspect 34 * Install a handler for unverifiable certificates. The handler can inspect
20 * the certificate, and decide (or let the user decide) whether to accept 35 * the certificate, and decide (or let the user decide) whether to accept
21 * the connection or not. The callback should return true 36 * the connection or not. The callback should return true
22 * to continue the SecureSocket connection. 37 * to continue the SecureSocket connection.
23 */ 38 */
24 void set onBadCertificate(bool callback(X509Certificate certificate)); 39 void set onBadCertificate(bool callback(X509Certificate certificate));
25 40
41 /**
42 * Get the peerCertificate for a connected secure socket. For a server
43 * socket, this will return the client certificate, or null, if no
44 * client certificate was received. For a client socket, this
45 * will return the server's certificate.
46 */
47 X509Certificate get peerCertificate;
48
26 /** 49 /**
27 * Initializes the NSS library with the path to a certificate database 50 * Initializes the NSS library with the path to a certificate database
28 * containing root certificates for verifying certificate paths on 51 * containing root certificates for verifying certificate paths on
29 * client connections, and server certificates to provide on server 52 * client connections, and server certificates to provide on server
30 * connections. The password argument should be used when creating 53 * connections. The password argument should be used when creating
31 * secure server sockets, to allow the private key of the server 54 * secure server sockets, to allow the private key of the server
32 * certificate to be fetched. If useBuiltinRoots is true (the default), 55 * certificate to be fetched. If useBuiltinRoots is true (the default),
33 * then a built-in set of root certificates for trusted certificate 56 * then a built-in set of root certificates for trusted certificate
34 * authorities is merged with the certificates in the database. 57 * authorities is merged with the certificates in the database.
35 * 58 *
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 static final int CLOSED = 203; 105 static final int CLOSED = 203;
83 106
84 // Buffer identifiers. 107 // Buffer identifiers.
85 // These must agree with those in the native C++ implementation. 108 // These must agree with those in the native C++ implementation.
86 static final int READ_PLAINTEXT = 0; 109 static final int READ_PLAINTEXT = 0;
87 static final int WRITE_PLAINTEXT = 1; 110 static final int WRITE_PLAINTEXT = 1;
88 static final int READ_ENCRYPTED = 2; 111 static final int READ_ENCRYPTED = 2;
89 static final int WRITE_ENCRYPTED = 3; 112 static final int WRITE_ENCRYPTED = 3;
90 static final int NUM_BUFFERS = 4; 113 static final int NUM_BUFFERS = 4;
91 114
92 int _count = 0; 115 _SecureSocket(String this.host,
93 // Constructs a new secure client socket. 116 int requestedPort,
94 factory _SecureSocket(String host, int port) => 117 String this.certificateName,
95 new _SecureSocket.internal(host, port, false); 118 {bool this.is_server,
96 119 Socket this.socket,
97 // Constructs a new secure server socket, with the named server certificate. 120 bool this.requestClientCertificate: false,
98 factory _SecureSocket.server(String host, 121 bool this.requireClientCertificate: false,
99 int port, 122 bool this.sendClientCertificate: false})
100 Socket socket, 123 : secureFilter = new _SecureFilter() {
101 String certificateName) => 124 // Throw an ArgumentError if any field is invalid.
102 new _SecureSocket.internal(host, port, true, socket, certificateName); 125 _verifyFields();
103 126 if (socket == null) {
104 _SecureSocket.internal(String host, 127 socket = new Socket(host, requestedPort);
105 int port,
106 bool is_server,
107 [Socket socket,
108 String certificateName])
109 : _host = host,
110 _port = port,
111 _socket = socket,
112 _certificateName = certificateName,
113 _is_server = is_server,
114 _secureFilter = new _SecureFilter() {
115 if (_socket == null) {
116 _socket = new Socket(host, port);
117 } 128 }
118 _socket.onConnect = _secureConnectHandler; 129 socket.onConnect = _secureConnectHandler;
119 _socket.onData = _secureDataHandler; 130 socket.onData = _secureDataHandler;
120 _socket.onClosed = _secureCloseHandler; 131 socket.onClosed = _secureCloseHandler;
121 _socket.onError = _secureErrorHandler; 132 socket.onError = _secureErrorHandler;
122 _secureFilter.init(); 133 secureFilter.init();
123 _secureFilter.registerHandshakeCompleteCallback(_secureHandshakeCompleteHand ler); 134 secureFilter.registerHandshakeCompleteCallback(
135 _secureHandshakeCompleteHandler);
124 } 136 }
125 137
126 int get port => _socket.port; 138 void _verifyFields() {
139 if (host is! String) throw new ArgumentError(
140 "SecureSocket constructor: host is not a String");
141 assert(is_server is bool);
142 assert(socket == null || socket is Socket);
143 if (certificateName != null && certificateName is! String) {
144 throw new ArgumentError(
145 "SecureSocket constructor: certificateName is not null or a String");
146 }
147 if (certificateName == null && is_server) {
148 throw new ArgumentError(
149 "SecureSocket constructor: certificateName is null on a server");
150 }
151 if (requestClientCertificate is! bool) {
152 throw new ArgumentError(
153 "SecureSocket constructor: requestClientCertificate is not a bool");
154 }
155 if (requireClientCertificate is! bool) {
156 throw new ArgumentError(
157 "SecureSocket constructor: requireClientCertificate is not a bool");
158 }
159 if (sendClientCertificate is! bool) {
160 throw new ArgumentError(
161 "SecureSocket constructor: sendClientCertificate is not a bool");
162 }
163 }
127 164
128 String get remoteHost => _socket.remoteHost; 165 int get port => socket.port;
129 166
130 int get remotePort => _socket.remotePort; 167 String get remoteHost => socket.remoteHost;
168
169 int get remotePort => socket.remotePort;
131 170
132 void set onClosed(void callback()) { 171 void set onClosed(void callback()) {
133 if (_inputStream != null && callback != null) { 172 if (_inputStream != null && callback != null) {
134 throw new StreamException( 173 throw new StreamException(
135 "Cannot set close handler when input stream is used"); 174 "Cannot set close handler when input stream is used");
136 } 175 }
137 _onClosed = callback; 176 _onClosed = callback;
138 } 177 }
139 178
140 void set _onClosed(void callback()) { 179 void set _onClosed(void callback()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 if (_outputStream != null && callback != null) { 212 if (_outputStream != null && callback != null) {
174 throw new StreamException( 213 throw new StreamException(
175 "Cannot set write handler when output stream is used"); 214 "Cannot set write handler when output stream is used");
176 } 215 }
177 _onWrite = callback; 216 _onWrite = callback;
178 } 217 }
179 218
180 void set _onWrite(void callback()) { 219 void set _onWrite(void callback()) {
181 _socketWriteHandler = callback; 220 _socketWriteHandler = callback;
182 // Reset the one-shot onWrite handler. 221 // Reset the one-shot onWrite handler.
183 _socket.onWrite = _secureWriteHandler; 222 socket.onWrite = _secureWriteHandler;
184 } 223 }
185 224
186 void set onBadCertificate(bool callback(X509Certificate certificate)) { 225 void set onBadCertificate(bool callback(X509Certificate certificate)) {
187 if (callback is! Function && callback != null) { 226 if (callback is! Function && callback != null) {
188 throw new SocketIOException( 227 throw new SocketIOException(
189 "Callback provided to onBadCertificate is not a function or null"); 228 "Callback provided to onBadCertificate is not a function or null");
190 } 229 }
191 _secureFilter.registerBadCertificateCallback(callback); 230 secureFilter.registerBadCertificateCallback(callback);
192 } 231 }
193 232
194 InputStream get inputStream { 233 InputStream get inputStream {
195 if (_inputStream == null) { 234 if (_inputStream == null) {
196 if (_socketDataHandler != null || _socketCloseHandler != null) { 235 if (_socketDataHandler != null || _socketCloseHandler != null) {
197 throw new StreamException( 236 throw new StreamException(
198 "Cannot get input stream when socket handlers are used"); 237 "Cannot get input stream when socket handlers are used");
199 } 238 }
200 _inputStream = new _SocketInputStream(this); 239 _inputStream = new _SocketInputStream(this);
201 } 240 }
(...skipping 14 matching lines...) Expand all
216 int available() { 255 int available() {
217 throw new UnimplementedError("SecureSocket.available not implemented yet"); 256 throw new UnimplementedError("SecureSocket.available not implemented yet");
218 } 257 }
219 258
220 void close([bool halfClose = false]) { 259 void close([bool halfClose = false]) {
221 if (_status == CLOSED) return; 260 if (_status == CLOSED) return;
222 if (halfClose) { 261 if (halfClose) {
223 _closedWrite = true; 262 _closedWrite = true;
224 _writeEncryptedData(); 263 _writeEncryptedData();
225 if (_filterWriteEmpty) { 264 if (_filterWriteEmpty) {
226 _socket.close(true); 265 socket.close(true);
227 _socketClosedWrite = true; 266 _socketClosedWrite = true;
228 if (_closedRead) { 267 if (_closedRead) {
229 close(false); 268 close(false);
230 } 269 }
231 } 270 }
232 } else { 271 } else {
233 _closedWrite = true; 272 _closedWrite = true;
234 _closedRead = true; 273 _closedRead = true;
235 _socket.close(false); 274 socket.close(false);
236 _socketClosedWrite = true; 275 _socketClosedWrite = true;
237 _socketClosedRead = true; 276 _socketClosedRead = true;
238 _secureFilter.destroy(); 277 secureFilter.destroy();
239 _secureFilter = null; 278 secureFilter = null;
240 if (scheduledDataEvent != null) { 279 if (scheduledDataEvent != null) {
241 scheduledDataEvent.cancel(); 280 scheduledDataEvent.cancel();
242 } 281 }
243 _status = CLOSED; 282 _status = CLOSED;
244 } 283 }
245 } 284 }
246 285
247 void _closeWrite() => close(true); 286 void _closeWrite() => close(true);
248 287
249 List<int> read([int len]) { 288 List<int> read([int len]) {
250 if (_closedRead) { 289 if (_closedRead) {
251 throw new SocketIOException("Reading from a closed socket"); 290 throw new SocketIOException("Reading from a closed socket");
252 } 291 }
253 if (_status != CONNECTED) { 292 if (_status != CONNECTED) {
254 return new List<int>(0); 293 return new List<int>(0);
255 } 294 }
256 var buffer = _secureFilter.buffers[READ_PLAINTEXT]; 295 var buffer = secureFilter.buffers[READ_PLAINTEXT];
257 _readEncryptedData(); 296 _readEncryptedData();
258 int toRead = buffer.length; 297 int toRead = buffer.length;
259 if (len != null) { 298 if (len != null) {
260 if (len is! int || len < 0) { 299 if (len is! int || len < 0) {
261 throw new ArgumentError( 300 throw new ArgumentError(
262 "Invalid len parameter in SecureSocket.read (len: $len)"); 301 "Invalid len parameter in SecureSocket.read (len: $len)");
263 } 302 }
264 if (len < toRead) { 303 if (len < toRead) {
265 toRead = len; 304 toRead = len;
266 } 305 }
(...skipping 10 matching lines...) Expand all
277 } 316 }
278 if (offset < 0 || bytes < 0 || offset + bytes > data.length) { 317 if (offset < 0 || bytes < 0 || offset + bytes > data.length) {
279 throw new ArgumentError( 318 throw new ArgumentError(
280 "Invalid offset or bytes in SecureSocket.readList"); 319 "Invalid offset or bytes in SecureSocket.readList");
281 } 320 }
282 if (_status != CONNECTED && _status != CLOSED) { 321 if (_status != CONNECTED && _status != CLOSED) {
283 return 0; 322 return 0;
284 } 323 }
285 324
286 int bytesRead = 0; 325 int bytesRead = 0;
287 var buffer = _secureFilter.buffers[READ_PLAINTEXT]; 326 var buffer = secureFilter.buffers[READ_PLAINTEXT];
288 // TODO(whesse): Currently this fails if the if is turned into a while loop. 327 // TODO(whesse): Currently this fails if the if is turned into a while loop.
289 // Fix it so that it can loop and read more than one buffer's worth of data. 328 // Fix it so that it can loop and read more than one buffer's worth of data.
290 if (bytes > bytesRead) { 329 if (bytes > bytesRead) {
291 _readEncryptedData(); 330 _readEncryptedData();
292 if (buffer.length > 0) { 331 if (buffer.length > 0) {
293 int toRead = min(bytes - bytesRead, buffer.length); 332 int toRead = min(bytes - bytesRead, buffer.length);
294 data.setRange(offset, toRead, buffer.data, buffer.start); 333 data.setRange(offset, toRead, buffer.data, buffer.start);
295 buffer.advanceStart(toRead); 334 buffer.advanceStart(toRead);
296 bytesRead += toRead; 335 bytesRead += toRead;
297 offset += toRead; 336 offset += toRead;
298 } 337 }
299 } 338 }
300 339
301 _setHandlersAfterRead(); 340 _setHandlersAfterRead();
302 return bytesRead; 341 return bytesRead;
303 } 342 }
304 343
305 // Write the data to the socket, and flush it as much as possible 344 // Write the data to the socket, and flush it as much as possible
306 // until it would block. If the write would block, _writeEncryptedData sets 345 // until it would block. If the write would block, _writeEncryptedData sets
307 // up handlers to flush the pipeline when possible. 346 // up handlers to flush the pipeline when possible.
308 int writeList(List<int> data, int offset, int bytes) { 347 int writeList(List<int> data, int offset, int bytes) {
309 if (_closedWrite) { 348 if (_closedWrite) {
310 throw new SocketIOException("Writing to a closed socket"); 349 throw new SocketIOException("Writing to a closed socket");
311 } 350 }
312 if (_status != CONNECTED) return 0; 351 if (_status != CONNECTED) return 0;
313 var buffer = _secureFilter.buffers[WRITE_PLAINTEXT]; 352 var buffer = secureFilter.buffers[WRITE_PLAINTEXT];
314 if (bytes > buffer.free) { 353 if (bytes > buffer.free) {
315 bytes = buffer.free; 354 bytes = buffer.free;
316 } 355 }
317 if (bytes > 0) { 356 if (bytes > 0) {
318 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset); 357 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset);
319 buffer.length += bytes; 358 buffer.length += bytes;
320 } 359 }
321 _writeEncryptedData(); // Tries to flush all pipeline stages. 360 _writeEncryptedData(); // Tries to flush all pipeline stages.
322 return bytes; 361 return bytes;
323 } 362 }
324 363
364 X509Certificate get peerCertificate => secureFilter.peerCertificate;
365
325 void _secureConnectHandler() { 366 void _secureConnectHandler() {
326 _connectPending = true; 367 _connectPending = true;
327 _secureFilter.connect(_host, _port, _is_server, _certificateName); 368 secureFilter.connect(host,
369 port,
370 is_server,
371 certificateName,
372 requestClientCertificate || requireClientCertificate,
373 requireClientCertificate,
374 sendClientCertificate);
328 _status = HANDSHAKE; 375 _status = HANDSHAKE;
329 _secureHandshake(); 376 _secureHandshake();
330 } 377 }
331 378
332 void _secureWriteHandler() { 379 void _secureWriteHandler() {
333 _writeEncryptedData(); 380 _writeEncryptedData();
334 if (_filterWriteEmpty && _closedWrite && !_socketClosedWrite) { 381 if (_filterWriteEmpty && _closedWrite && !_socketClosedWrite) {
335 close(true); 382 close(true);
336 } 383 }
337 if (_status == HANDSHAKE) { 384 if (_status == HANDSHAKE) {
338 _secureHandshake(); 385 _secureHandshake();
339 } else if (_status == CONNECTED && 386 } else if (_status == CONNECTED &&
340 _socketWriteHandler != null && 387 _socketWriteHandler != null &&
341 _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) { 388 secureFilter.buffers[WRITE_PLAINTEXT].free > 0) {
342 // We must be able to set onWrite from the onWrite callback. 389 // We must be able to set onWrite from the onWrite callback.
343 var handler = _socketWriteHandler; 390 var handler = _socketWriteHandler;
344 // Reset the one-shot handler. 391 // Reset the one-shot handler.
345 _socketWriteHandler = null; 392 _socketWriteHandler = null;
346 handler(); 393 handler();
347 } 394 }
348 } 395 }
349 396
350 void _secureDataHandler() { 397 void _secureDataHandler() {
351 if (_status == HANDSHAKE) { 398 if (_status == HANDSHAKE) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 _socketCloseHandler(); 460 _socketCloseHandler();
414 } 461 }
415 if (_socketClosedWrite) { 462 if (_socketClosedWrite) {
416 close(false); 463 close(false);
417 } 464 }
418 } 465 }
419 } 466 }
420 467
421 void _secureHandshake() { 468 void _secureHandshake() {
422 _readEncryptedData(); 469 _readEncryptedData();
423 _secureFilter.handshake(); 470 secureFilter.handshake();
424 _writeEncryptedData(); 471 _writeEncryptedData();
425 if (_secureFilter.buffers[WRITE_ENCRYPTED].length > 0) { 472 if (secureFilter.buffers[WRITE_ENCRYPTED].length > 0) {
426 _socket.onWrite = _secureWriteHandler; 473 socket.onWrite = _secureWriteHandler;
427 } 474 }
428 } 475 }
429 476
430 void _secureHandshakeCompleteHandler() { 477 void _secureHandshakeCompleteHandler() {
431 _status = CONNECTED; 478 _status = CONNECTED;
432 if (_connectPending && _socketConnectHandler != null) { 479 if (_connectPending && _socketConnectHandler != null) {
433 _connectPending = false; 480 _connectPending = false;
434 _socketConnectHandler(); 481 _socketConnectHandler();
435 } 482 }
436 if (_socketWriteHandler != null) { 483 if (_socketWriteHandler != null) {
437 _socket.onWrite = _secureWriteHandler; 484 socket.onWrite = _secureWriteHandler;
438 } 485 }
439 } 486 }
440 487
441 // True if the underlying socket is closed, the filter has been emptied of 488 // True if the underlying socket is closed, the filter has been emptied of
442 // all data, and the close event has been fired. 489 // all data, and the close event has been fired.
443 get _closed => _socketClosed; 490 get _closed => _socketClosed;
444 491
445 void _readEncryptedData() { 492 void _readEncryptedData() {
446 // Read from the socket, and push it through the filter as far as 493 // Read from the socket, and push it through the filter as far as
447 // possible. 494 // possible.
448 var encrypted = _secureFilter.buffers[READ_ENCRYPTED]; 495 var encrypted = secureFilter.buffers[READ_ENCRYPTED];
449 var plaintext = _secureFilter.buffers[READ_PLAINTEXT]; 496 var plaintext = secureFilter.buffers[READ_PLAINTEXT];
450 bool progress = true; 497 bool progress = true;
451 while (progress) { 498 while (progress) {
452 progress = false; 499 progress = false;
453 // Do not try to read plaintext from the filter while handshaking. 500 // Do not try to read plaintext from the filter while handshaking.
454 if ((_status == CONNECTED) && plaintext.free > 0) { 501 if ((_status == CONNECTED) && plaintext.free > 0) {
455 int bytes = _secureFilter.processBuffer(READ_PLAINTEXT); 502 int bytes = secureFilter.processBuffer(READ_PLAINTEXT);
456 if (bytes > 0) { 503 if (bytes > 0) {
457 plaintext.length += bytes; 504 plaintext.length += bytes;
458 progress = true; 505 progress = true;
459 } 506 }
460 } 507 }
461 if (encrypted.length > 0) { 508 if (encrypted.length > 0) {
462 int bytes = _secureFilter.processBuffer(READ_ENCRYPTED); 509 int bytes = secureFilter.processBuffer(READ_ENCRYPTED);
463 if (bytes > 0) { 510 if (bytes > 0) {
464 encrypted.advanceStart(bytes); 511 encrypted.advanceStart(bytes);
465 progress = true; 512 progress = true;
466 } 513 }
467 } 514 }
468 if (!_socketClosedRead) { 515 if (!_socketClosedRead) {
469 int bytes = _socket.readList(encrypted.data, 516 int bytes = socket.readList(encrypted.data,
470 encrypted.start + encrypted.length, 517 encrypted.start + encrypted.length,
471 encrypted.free); 518 encrypted.free);
472 if (bytes > 0) { 519 if (bytes > 0) {
473 encrypted.length += bytes; 520 encrypted.length += bytes;
474 progress = true; 521 progress = true;
475 } 522 }
476 } 523 }
477 } 524 }
478 // If there is any data in any stages of the filter, there should 525 // If there is any data in any stages of the filter, there should
479 // be data in the plaintext buffer after this process. 526 // be data in the plaintext buffer after this process.
480 // TODO(whesse): Verify that this is true, and there can be no 527 // TODO(whesse): Verify that this is true, and there can be no
481 // partial encrypted block stuck in the secureFilter. 528 // partial encrypted block stuck in the secureFilter.
482 _filterReadEmpty = (plaintext.length == 0); 529 _filterReadEmpty = (plaintext.length == 0);
483 } 530 }
484 531
485 void _writeEncryptedData() { 532 void _writeEncryptedData() {
486 if (_socketClosedWrite) return; 533 if (_socketClosedWrite) return;
487 var encrypted = _secureFilter.buffers[WRITE_ENCRYPTED]; 534 var encrypted = secureFilter.buffers[WRITE_ENCRYPTED];
488 var plaintext = _secureFilter.buffers[WRITE_PLAINTEXT]; 535 var plaintext = secureFilter.buffers[WRITE_PLAINTEXT];
489 while (true) { 536 while (true) {
490 if (encrypted.length > 0) { 537 if (encrypted.length > 0) {
491 // Write from the filter to the socket. 538 // Write from the filter to the socket.
492 int bytes = _socket.writeList(encrypted.data, 539 int bytes = socket.writeList(encrypted.data,
493 encrypted.start, 540 encrypted.start,
494 encrypted.length); 541 encrypted.length);
495 if (bytes == 0) { 542 if (bytes == 0) {
496 // The socket has blocked while we have data to write. 543 // The socket has blocked while we have data to write.
497 // We must be notified when it becomes unblocked. 544 // We must be notified when it becomes unblocked.
498 _socket.onWrite = _secureWriteHandler; 545 socket.onWrite = _secureWriteHandler;
499 _filterWriteEmpty = false; 546 _filterWriteEmpty = false;
500 break; 547 break;
501 } 548 }
502 encrypted.advanceStart(bytes); 549 encrypted.advanceStart(bytes);
503 } else { 550 } else {
504 var plaintext = _secureFilter.buffers[WRITE_PLAINTEXT]; 551 var plaintext = secureFilter.buffers[WRITE_PLAINTEXT];
505 if (plaintext.length > 0) { 552 if (plaintext.length > 0) {
506 int plaintext_bytes = _secureFilter.processBuffer(WRITE_PLAINTEXT); 553 int plaintext_bytes = secureFilter.processBuffer(WRITE_PLAINTEXT);
507 plaintext.advanceStart(plaintext_bytes); 554 plaintext.advanceStart(plaintext_bytes);
508 } 555 }
509 int bytes = _secureFilter.processBuffer(WRITE_ENCRYPTED); 556 int bytes = secureFilter.processBuffer(WRITE_ENCRYPTED);
510 if (bytes <= 0) { 557 if (bytes <= 0) {
511 // We know the WRITE_ENCRYPTED buffer is empty, and the 558 // We know the WRITE_ENCRYPTED buffer is empty, and the
512 // filter wrote zero bytes to it, so the filter must be empty. 559 // filter wrote zero bytes to it, so the filter must be empty.
513 // Also, the WRITE_PLAINTEXT buffer must have been empty, or 560 // Also, the WRITE_PLAINTEXT buffer must have been empty, or
514 // it would have written to the filter. 561 // it would have written to the filter.
515 // TODO(whesse): Verify that the filter works this way. 562 // TODO(whesse): Verify that the filter works this way.
516 _filterWriteEmpty = true; 563 _filterWriteEmpty = true;
517 break; 564 break;
518 } 565 }
519 encrypted.length += bytes; 566 encrypted.length += bytes;
(...skipping 30 matching lines...) Expand all
550 // This can't be an else clause: the value of _filterReadEmpty changes. 597 // This can't be an else clause: the value of _filterReadEmpty changes.
551 // This must be asynchronous, because we are in a read or readList call. 598 // This must be asynchronous, because we are in a read or readList call.
552 new Timer(0, (_) => _secureCloseHandler()); 599 new Timer(0, (_) => _secureCloseHandler());
553 } 600 }
554 } 601 }
555 } 602 }
556 603
557 bool get _socketClosed => _closedRead; 604 bool get _socketClosed => _closedRead;
558 605
559 // _SecureSocket cannot extend _Socket and use _Socket's factory constructor. 606 // _SecureSocket cannot extend _Socket and use _Socket's factory constructor.
560 Socket _socket; 607 Socket socket;
561 String _host; 608 final String host;
562 int _port; 609 final bool is_server;
563 bool _is_server; 610 final String certificateName;
564 String _certificateName; 611 final bool requestClientCertificate;
612 final bool requireClientCertificate;
613 final bool sendClientCertificate;
565 614
566 var _status = NOT_CONNECTED; 615 var _status = NOT_CONNECTED;
567 bool _socketClosedRead = false; // The network socket is closed for reading. 616 bool _socketClosedRead = false; // The network socket is closed for reading.
568 bool _socketClosedWrite = false; // The network socket is closed for writing. 617 bool _socketClosedWrite = false; // The network socket is closed for writing.
569 bool _closedRead = false; // The secure socket has fired an onClosed event. 618 bool _closedRead = false; // The secure socket has fired an onClosed event.
570 bool _closedWrite = false; // The secure socket has been closed for writing. 619 bool _closedWrite = false; // The secure socket has been closed for writing.
571 bool _filterReadEmpty = true; // There is no buffered data to read. 620 bool _filterReadEmpty = true; // There is no buffered data to read.
572 bool _filterWriteEmpty = true; // There is no buffered data to be written. 621 bool _filterWriteEmpty = true; // There is no buffered data to be written.
573 _SocketInputStream _inputStream; 622 _SocketInputStream _inputStream;
574 _SocketOutputStream _outputStream; 623 _SocketOutputStream _outputStream;
575 bool _connectPending = false; 624 bool _connectPending = false;
576 Function _socketConnectHandler; 625 Function _socketConnectHandler;
577 Function _socketWriteHandler; 626 Function _socketWriteHandler;
578 Function _socketDataHandler; 627 Function _socketDataHandler;
579 Function _socketErrorHandler; 628 Function _socketErrorHandler;
580 Function _socketCloseHandler; 629 Function _socketCloseHandler;
581 Timer scheduledDataEvent; 630 Timer scheduledDataEvent;
582 631
583 _SecureFilter _secureFilter; 632 _SecureFilter secureFilter;
584 } 633 }
585 634
586 635
587 class _ExternalBuffer { 636 class _ExternalBuffer {
588 static final int SIZE = 8 * 1024; 637 static final int SIZE = 8 * 1024;
589 _ExternalBuffer() : start = 0, length = 0; 638 _ExternalBuffer() : start = 0, length = 0;
590 639
591 // TODO(whesse): Consider making this a circular buffer. Only if it helps. 640 // TODO(whesse): Consider making this a circular buffer. Only if it helps.
592 void advanceStart(int numBytes) { 641 void advanceStart(int numBytes) {
593 start += numBytes; 642 start += numBytes;
(...skipping 10 matching lines...) Expand all
604 int length; 653 int length;
605 } 654 }
606 655
607 656
608 abstract class _SecureFilter { 657 abstract class _SecureFilter {
609 external factory _SecureFilter(); 658 external factory _SecureFilter();
610 659
611 void connect(String hostName, 660 void connect(String hostName,
612 int port, 661 int port,
613 bool is_server, 662 bool is_server,
614 String certificateName); 663 String certificateName,
664 bool requestClientCertificate,
665 bool requireClientCertificate,
666 bool sendClientCertificate);
615 void destroy(); 667 void destroy();
616 void handshake(); 668 void handshake();
617 void init(); 669 void init();
670 X509Certificate get peerCertificate;
618 int processBuffer(int bufferIndex); 671 int processBuffer(int bufferIndex);
619 void registerBadCertificateCallback(Function callback); 672 void registerBadCertificateCallback(Function callback);
620 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); 673 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);
621 674
622 List<_ExternalBuffer> get buffers; 675 List<_ExternalBuffer> get buffers;
623 } 676 }
OLDNEW
« no previous file with comments | « sdk/lib/io/secure_server_socket.dart ('k') | tests/standalone/io/pkcert/cert9.db » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698