OLD | NEW |
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 * TlsSocket provides a secure (SSL or TLS) client connection to a server. | 6 * TlsSocket 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 TlsSocket implements Socket { | 10 abstract class TlsSocket implements Socket { |
11 /** | 11 /** |
12 * Constructs a new secure 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 TlsSocket(String host, int port) => new _TlsSocket(host, port); | 16 factory TlsSocket(String host, int port) => new _TlsSocket(host, port); |
17 | 17 |
18 /** | 18 /** |
19 * Initializes the TLS library with the path to a certificate database | 19 * Initializes the TLS library with the path to a certificate database |
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. | 22 * connections. The password argument should be used when creating |
| 23 * secure server sockets, to allow the private key of the server |
| 24 * certificate to be fetched. |
| 25 * |
| 26 * The database should be an NSS certificate database directory |
| 27 * 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 |
| 29 * front of the absolute path of the database directory, or setting the |
| 30 * environment variable NSS_DEFAULT_DB_TYPE to "sql". |
23 */ | 31 */ |
24 external static void setCertificateDatabase(String pkcertDirectory); | 32 external static void setCertificateDatabase(String certificateDatabase, |
| 33 [String password]); |
25 } | 34 } |
26 | 35 |
27 | 36 |
28 class _TlsSocket implements TlsSocket { | 37 class _TlsSocket implements TlsSocket { |
29 // Status states | 38 // Status states |
30 static final int NOT_CONNECTED = 200; | 39 static final int NOT_CONNECTED = 200; |
31 static final int HANDSHAKE = 201; | 40 static final int HANDSHAKE = 201; |
32 static final int CONNECTED = 202; | 41 static final int CONNECTED = 202; |
33 static final int CLOSED = 203; | 42 static final int CLOSED = 203; |
34 | 43 |
35 // Buffer identifiers. | 44 // Buffer identifiers. |
36 // These must agree with those in the native C++ implementation. | 45 // These must agree with those in the native C++ implementation. |
37 static final int READ_PLAINTEXT = 0; | 46 static final int READ_PLAINTEXT = 0; |
38 static final int WRITE_PLAINTEXT = 1; | 47 static final int WRITE_PLAINTEXT = 1; |
39 static final int READ_ENCRYPTED = 2; | 48 static final int READ_ENCRYPTED = 2; |
40 static final int WRITE_ENCRYPTED = 3; | 49 static final int WRITE_ENCRYPTED = 3; |
41 static final int NUM_BUFFERS = 4; | 50 static final int NUM_BUFFERS = 4; |
42 | 51 |
43 int _count = 0; | 52 int _count = 0; |
44 // Constructs a new secure client socket. | 53 // Constructs a new secure client socket. |
45 _TlsSocket(String host, int port) | 54 factory _TlsSocket(String host, int port) => |
| 55 new _TlsSocket.internal(host, port, false); |
| 56 |
| 57 // Constructs a new secure server socket, with the named server certificate. |
| 58 factory _TlsSocket.server(String host, |
| 59 int port, |
| 60 Socket socket, |
| 61 String certificateName) => |
| 62 new _TlsSocket.internal(host, port, true, socket, certificateName); |
| 63 |
| 64 _TlsSocket.internal(String host, |
| 65 int port, |
| 66 bool is_server, |
| 67 [Socket socket, |
| 68 String certificateName]) |
46 : _host = host, | 69 : _host = host, |
47 _port = port, | 70 _port = port, |
48 _socket = new Socket(host, port), | 71 _socket = socket, |
| 72 _certificateName = certificateName, |
| 73 _is_server = is_server, |
49 _tlsFilter = new _TlsFilter() { | 74 _tlsFilter = new _TlsFilter() { |
| 75 if (_socket == null) { |
| 76 _socket = new Socket(host, port); |
| 77 } |
50 _socket.onConnect = _tlsConnectHandler; | 78 _socket.onConnect = _tlsConnectHandler; |
51 _socket.onData = _tlsDataHandler; | 79 _socket.onData = _tlsDataHandler; |
52 _socket.onClosed = _tlsCloseHandler; | 80 _socket.onClosed = _tlsCloseHandler; |
53 _tlsFilter.init(); | 81 _tlsFilter.init(); |
54 _tlsFilter.registerHandshakeCompleteCallback(_tlsHandshakeCompleteHandler); | 82 _tlsFilter.registerHandshakeCompleteCallback(_tlsHandshakeCompleteHandler); |
55 } | 83 } |
56 | 84 |
57 InputStream get inputStream { | 85 InputStream get inputStream { |
58 // TODO(6701): Implement stream interfaces on TlsSocket. | 86 // TODO(6701): Implement stream interfaces on TlsSocket. |
59 throw new UnimplementedError("TlsSocket.inputStream not implemented yet"); | 87 throw new UnimplementedError("TlsSocket.inputStream not implemented yet"); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 if (bytes > 0) { | 179 if (bytes > 0) { |
152 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset); | 180 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset); |
153 buffer.length += bytes; | 181 buffer.length += bytes; |
154 } | 182 } |
155 _writeEncryptedData(); // Tries to flush all pipeline stages. | 183 _writeEncryptedData(); // Tries to flush all pipeline stages. |
156 return bytes; | 184 return bytes; |
157 } | 185 } |
158 | 186 |
159 void _tlsConnectHandler() { | 187 void _tlsConnectHandler() { |
160 _connectPending = true; | 188 _connectPending = true; |
161 _tlsFilter.connect(_host, _port); | 189 _tlsFilter.connect(_host, _port, _is_server, _certificateName); |
162 _status = HANDSHAKE; | 190 _status = HANDSHAKE; |
163 _tlsHandshake(); | 191 _tlsHandshake(); |
164 } | 192 } |
165 | 193 |
166 void _tlsWriteHandler() { | 194 void _tlsWriteHandler() { |
167 if (_status == HANDSHAKE) { | 195 if (_status == HANDSHAKE) { |
168 _tlsHandshake(); | 196 _tlsHandshake(); |
169 } else if (_status == CONNECTED) { | 197 } else if (_status == CONNECTED) { |
170 if (_socketWriteHandler != null) { | 198 if (_socketWriteHandler != null) { |
171 _socketWriteHandler(); | 199 _socketWriteHandler(); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 } | 345 } |
318 if (_filterEmpty && _fireCloseEventPending) { | 346 if (_filterEmpty && _fireCloseEventPending) { |
319 _fireCloseEvent(); | 347 _fireCloseEvent(); |
320 } | 348 } |
321 } | 349 } |
322 | 350 |
323 // _TlsSocket cannot extend _Socket and use _Socket's factory constructor. | 351 // _TlsSocket cannot extend _Socket and use _Socket's factory constructor. |
324 Socket _socket; | 352 Socket _socket; |
325 String _host; | 353 String _host; |
326 int _port; | 354 int _port; |
| 355 bool _is_server; |
| 356 String _certificateName; |
327 | 357 |
328 var _status = NOT_CONNECTED; | 358 var _status = NOT_CONNECTED; |
329 bool _socketClosed = false; | 359 bool _socketClosed = false; |
330 bool _filterEmpty = false; | 360 bool _filterEmpty = false; |
331 bool _connectPending = false; | 361 bool _connectPending = false; |
332 bool _fireCloseEventPending = false; | 362 bool _fireCloseEventPending = false; |
333 Function _socketConnectHandler; | 363 Function _socketConnectHandler; |
334 Function _socketWriteHandler; | 364 Function _socketWriteHandler; |
335 Function _socketDataHandler; | 365 Function _socketDataHandler; |
336 Function _socketCloseHandler; | 366 Function _socketCloseHandler; |
(...skipping 20 matching lines...) Expand all Loading... |
357 | 387 |
358 List data; // This will be a ExternalByteArray, backed by C allocated data. | 388 List data; // This will be a ExternalByteArray, backed by C allocated data. |
359 int start; | 389 int start; |
360 int length; | 390 int length; |
361 } | 391 } |
362 | 392 |
363 | 393 |
364 abstract class _TlsFilter { | 394 abstract class _TlsFilter { |
365 external factory _TlsFilter(); | 395 external factory _TlsFilter(); |
366 | 396 |
367 void connect(String hostName, int port); | 397 void connect(String hostName, |
| 398 int port, |
| 399 bool is_server, |
| 400 String certificateName); |
368 void destroy(); | 401 void destroy(); |
369 void handshake(); | 402 void handshake(); |
370 void init(); | 403 void init(); |
371 int processBuffer(int bufferIndex); | 404 int processBuffer(int bufferIndex); |
372 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); | 405 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); |
| 406 |
| 407 List<_TlsExternalBuffer> get buffers; |
373 } | 408 } |
OLD | NEW |