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

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

Issue 11308271: Add built-in root certificates to dart:io SecureSocket. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix dart2js errors on new dart:io stuff. 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
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.
15 */ 15 */
16 factory SecureSocket(String host, int port) => new _SecureSocket(host, port); 16 factory SecureSocket(String host, int port) => new _SecureSocket(host, port);
17 17
18 /** 18 /**
19 * Initializes the NSS library with the path to a certificate database 19 * Initializes the NSS library with the path to a certificate database
Mads Ager (google) 2012/12/03 09:15:09 We should revisit this comment more. We should pro
20 * containing root certificates for verifying certificate paths on 20 * containing root certificates for verifying certificate paths on
21 * client connections, and server certificates to provide on server 21 * client connections, and server certificates to provide on server
22 * connections. The password argument should be used when creating 22 * connections. The password argument should be used when creating
23 * secure server sockets, to allow the private key of the server 23 * secure server sockets, to allow the private key of the server
24 * certificate to be fetched. 24 * certificate to be fetched. If useBuiltinRoots is true (the default),
25 * then a built-in set of root certificates for trusted certificate
26 * authorities is merged with the certificates in the database.
25 * 27 *
26 * The database should be an NSS certificate database directory 28 * The database should be an NSS certificate database directory
27 * containing a cert9.db file, not a cert8.db file. This version of 29 * containing a cert9.db file, not a cert8.db file. This version of
28 * the database can be created using the NSS certutil tool with "sql:" in 30 * the database can be created using the NSS certutil tool with "sql:" in
29 * front of the absolute path of the database directory, or setting the 31 * front of the absolute path of the database directory, or setting the
30 * environment variable NSS_DEFAULT_DB_TYPE to "sql". 32 * environment variable NSS_DEFAULT_DB_TYPE to "sql".
31 */ 33 */
32 external static void setCertificateDatabase(String certificateDatabase, 34 external static void initialize({String database,
33 [String password]); 35 String password,
36 bool useBuiltinRoots: true});
34 } 37 }
35 38
36 39
37 class _SecureSocket implements SecureSocket { 40 class _SecureSocket implements SecureSocket {
38 // Status states 41 // Status states
39 static final int NOT_CONNECTED = 200; 42 static final int NOT_CONNECTED = 200;
40 static final int HANDSHAKE = 201; 43 static final int HANDSHAKE = 201;
41 static final int CONNECTED = 202; 44 static final int CONNECTED = 202;
42 static final int CLOSED = 203; 45 static final int CLOSED = 203;
43 46
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 scheduledDataEvent.cancel(); 192 scheduledDataEvent.cancel();
190 } 193 }
191 _status = CLOSED; 194 _status = CLOSED;
192 } 195 }
193 } 196 }
194 197
195 void _closeWrite() => close(true); 198 void _closeWrite() => close(true);
196 199
197 List<int> read([int len]) { 200 List<int> read([int len]) {
198 if (_closedRead) { 201 if (_closedRead) {
199 throw new SocketException("Reading from a closed socket"); 202 throw new SocketIOException("Reading from a closed socket");
200 } 203 }
201 if (_status != CONNECTED) { 204 if (_status != CONNECTED) {
202 return new List<int>(0); 205 return new List<int>(0);
203 } 206 }
204 var buffer = _secureFilter.buffers[READ_PLAINTEXT]; 207 var buffer = _secureFilter.buffers[READ_PLAINTEXT];
205 _readEncryptedData(); 208 _readEncryptedData();
206 int toRead = buffer.length; 209 int toRead = buffer.length;
207 if (len != null) { 210 if (len != null) {
208 if (len is! int || len < 0) { 211 if (len is! int || len < 0) {
209 throw new ArgumentError( 212 throw new ArgumentError(
210 "Invalid len parameter in SecureSocket.read (len: $len)"); 213 "Invalid len parameter in SecureSocket.read (len: $len)");
211 } 214 }
212 if (len < toRead) { 215 if (len < toRead) {
213 toRead = len; 216 toRead = len;
214 } 217 }
215 } 218 }
216 List<int> result = buffer.data.getRange(buffer.start, toRead); 219 List<int> result = buffer.data.getRange(buffer.start, toRead);
217 buffer.advanceStart(toRead); 220 buffer.advanceStart(toRead);
218 _setHandlersAfterRead(); 221 _setHandlersAfterRead();
219 return result; 222 return result;
220 } 223 }
221 224
222 int readList(List<int> data, int offset, int bytes) { 225 int readList(List<int> data, int offset, int bytes) {
223 if (_closedRead) { 226 if (_closedRead) {
224 throw new SocketException("Reading from a closed socket"); 227 throw new SocketIOException("Reading from a closed socket");
225 } 228 }
226 if (offset < 0 || bytes < 0 || offset + bytes > data.length) { 229 if (offset < 0 || bytes < 0 || offset + bytes > data.length) {
227 throw new ArgumentError( 230 throw new ArgumentError(
228 "Invalid offset or bytes in SecureSocket.readList"); 231 "Invalid offset or bytes in SecureSocket.readList");
229 } 232 }
230 if (_status != CONNECTED && _status != CLOSED) { 233 if (_status != CONNECTED && _status != CLOSED) {
231 return 0; 234 return 0;
232 } 235 }
233 236
234 int bytesRead = 0; 237 int bytesRead = 0;
(...skipping 13 matching lines...) Expand all
248 251
249 _setHandlersAfterRead(); 252 _setHandlersAfterRead();
250 return bytesRead; 253 return bytesRead;
251 } 254 }
252 255
253 // Write the data to the socket, and flush it as much as possible 256 // Write the data to the socket, and flush it as much as possible
254 // until it would block. If the write would block, _writeEncryptedData sets 257 // until it would block. If the write would block, _writeEncryptedData sets
255 // up handlers to flush the pipeline when possible. 258 // up handlers to flush the pipeline when possible.
256 int writeList(List<int> data, int offset, int bytes) { 259 int writeList(List<int> data, int offset, int bytes) {
257 if (_closedWrite) { 260 if (_closedWrite) {
258 throw new SocketException("Writing to a closed socket"); 261 throw new SocketIOException("Writing to a closed socket");
259 } 262 }
260 if (_status != CONNECTED) return 0; 263 if (_status != CONNECTED) return 0;
261 var buffer = _secureFilter.buffers[WRITE_PLAINTEXT]; 264 var buffer = _secureFilter.buffers[WRITE_PLAINTEXT];
262 if (bytes > buffer.free) { 265 if (bytes > buffer.free) {
263 bytes = buffer.free; 266 bytes = buffer.free;
264 } 267 }
265 if (bytes > 0) { 268 if (bytes > 0) {
266 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset); 269 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset);
267 buffer.length += bytes; 270 buffer.length += bytes;
268 } 271 }
(...skipping 22 matching lines...) Expand all
291 // We must be able to set onWrite from the onWrite callback. 294 // We must be able to set onWrite from the onWrite callback.
292 var handler = _socketWriteHandler; 295 var handler = _socketWriteHandler;
293 // Reset the one-shot handler. 296 // Reset the one-shot handler.
294 _socketWriteHandler = null; 297 _socketWriteHandler = null;
295 handler(); 298 handler();
296 } 299 }
297 } 300 }
298 301
299 void _secureDataHandler() { 302 void _secureDataHandler() {
300 if (_status == HANDSHAKE) { 303 if (_status == HANDSHAKE) {
301 _secureHandshake(); 304 try {
305 _secureHandshake();
306 } catch (e) { _reportError(e, "SecureSocket error"); }
302 } else { 307 } else {
303 _writeEncryptedData(); // TODO(whesse): Removing this causes a failure. 308 try {
304 _readEncryptedData(); 309 _writeEncryptedData(); // TODO(whesse): Removing this causes a failure.
310 _readEncryptedData();
311 } catch (e) { _reportError(e, "SecureSocket error"); }
305 if (!_filterReadEmpty) { 312 if (!_filterReadEmpty) {
306 // Call the onData event. 313 // Call the onData event.
307 if (scheduledDataEvent != null) { 314 if (scheduledDataEvent != null) {
308 scheduledDataEvent.cancel(); 315 scheduledDataEvent.cancel();
309 scheduledDataEvent = null; 316 scheduledDataEvent = null;
310 } 317 }
311 if (_socketDataHandler != null) { 318 if (_socketDataHandler != null) {
312 _socketDataHandler(); 319 _socketDataHandler();
313 } 320 }
314 } 321 }
315 } 322 }
316 } 323 }
317 324
318 void _secureErrorHandler(e) { 325 void _secureErrorHandler(e) {
319 _reportError(e, 'Error on underlying Socket'); 326 _reportError(e, 'Error on underlying Socket');
320 } 327 }
321 328
322 void _reportError(error, String message) { 329 void _reportError(error, String message) {
323 // TODO(whesse): Call _reportError from all internal functions that throw. 330 // TODO(whesse): Call _reportError from all internal functions that throw.
324 var e; 331 var e;
325 if (error is SocketIOException) { 332 if (error is SocketIOException) {
326 e = new SocketIOException('$message (${error.message})', error.osError); 333 e = new SocketIOException('$message (${error.message})', error.osError);
327 } else if (error is OSError) { 334 } else if (error is OSError) {
328 e = new SocketIOException(message, error); 335 e = new SocketIOException(message, error);
329 } else { 336 } else {
330 e = new SocketIOException('$message (${error.toString()})', null); 337 e = new SocketIOException('$message (${error.toString()})', null);
331 } 338 }
339 close(false);
332 bool reported = false; 340 bool reported = false;
333 if (_socketErrorHandler != null) { 341 if (_socketErrorHandler != null) {
334 reported = true; 342 reported = true;
335 _socketErrorHandler(e); 343 _socketErrorHandler(e);
336 } 344 }
337 if (_inputStream != null) { 345 if (_inputStream != null) {
338 reported = reported || _inputStream._onSocketError(e); 346 reported = reported || _inputStream._onSocketError(e);
339 } 347 }
340 if (_outputStream != null) { 348 if (_outputStream != null) {
341 reported = reported || _outputStream._onSocketError(e); 349 reported = reported || _outputStream._onSocketError(e);
342 } 350 }
343
344 if (!reported) throw e; 351 if (!reported) throw e;
345 } 352 }
346 353
347 void _secureCloseHandler() { 354 void _secureCloseHandler() {
348 _socketClosedRead = true; 355 _socketClosedRead = true;
349 if (_filterReadEmpty) { 356 if (_filterReadEmpty) {
350 _closedRead = true; 357 _closedRead = true;
351 _fireCloseEvent(); 358 _fireCloseEvent();
352 if (_socketClosedWrite) { 359 if (_socketClosedWrite) {
353 _secureFilter.destroy(); 360 _secureFilter.destroy();
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 bool is_server, 568 bool is_server,
562 String certificateName); 569 String certificateName);
563 void destroy(); 570 void destroy();
564 void handshake(); 571 void handshake();
565 void init(); 572 void init();
566 int processBuffer(int bufferIndex); 573 int processBuffer(int bufferIndex);
567 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); 574 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);
568 575
569 List<_ExternalBuffer> get buffers; 576 List<_ExternalBuffer> get buffers;
570 } 577 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698