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

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: Add more 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
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. An appropriate certificate will
17 * be searched for and chosen automatically, based on what the server
18 * says it will accept, unless clientCertificate is set to the nickname of
19 * a certificate in the certificate database.
Søren Gjesse 2012/12/07 13:00:23 How about rephrasing this additional comment to
Bill Hesse 2012/12/10 15:15:48 Done.
15 */ 20 */
16 factory SecureSocket(String host, int port) => new _SecureSocket(host, port); 21 factory SecureSocket(String host,
22 int port,
23 {bool sendClientCertificate: false,
24 String certificateName}) {
Søren Gjesse 2012/12/07 13:00:23 Please indent one char more here.
Bill Hesse 2012/12/10 15:15:48 Done.
25 return new _SecureSocket.client(host,
26 port,
27 sendClientCertificate,
28 certificateName);
29 }
17 30
18 /** 31 /**
19 * Install a handler for unverifiable certificates. The handler can inspect 32 * Install a handler for unverifiable certificates. The handler can inspect
20 * the certificate, and decide (or let the user decide) whether to accept 33 * the certificate, and decide (or let the user decide) whether to accept
21 * the connection or not. The callback should return true 34 * the connection or not. The callback should return true
22 * to continue the SecureSocket connection. 35 * to continue the SecureSocket connection.
23 */ 36 */
24 void set onBadCertificate(bool callback(X509Certificate certificate)); 37 void set onBadCertificate(bool callback(X509Certificate certificate));
25 38
39 /**
40 * Get the peerCertificate for a connected secure socket. For a server
41 * socket, this will return the client certificate, or null, if no
42 * client certificate was requested or supplied. For a client socket, this
Søren Gjesse 2012/12/07 13:00:23 Maybe remove "requested or".
Bill Hesse 2012/12/10 15:15:48 Done.
43 * will return the server's certificate.
44 */
45 X509Certificate get peerCertificate;
46
26 /** 47 /**
27 * Initializes the NSS library with the path to a certificate database 48 * Initializes the NSS library with the path to a certificate database
28 * containing root certificates for verifying certificate paths on 49 * containing root certificates for verifying certificate paths on
29 * client connections, and server certificates to provide on server 50 * client connections, and server certificates to provide on server
30 * connections. The password argument should be used when creating 51 * connections. The password argument should be used when creating
31 * secure server sockets, to allow the private key of the server 52 * secure server sockets, to allow the private key of the server
32 * certificate to be fetched. If useBuiltinRoots is true (the default), 53 * certificate to be fetched. If useBuiltinRoots is true (the default),
33 * then a built-in set of root certificates for trusted certificate 54 * then a built-in set of root certificates for trusted certificate
34 * authorities is merged with the certificates in the database. 55 * authorities is merged with the certificates in the database.
35 * 56 *
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 static final int CLOSED = 203; 103 static final int CLOSED = 203;
83 104
84 // Buffer identifiers. 105 // Buffer identifiers.
85 // These must agree with those in the native C++ implementation. 106 // These must agree with those in the native C++ implementation.
86 static final int READ_PLAINTEXT = 0; 107 static final int READ_PLAINTEXT = 0;
87 static final int WRITE_PLAINTEXT = 1; 108 static final int WRITE_PLAINTEXT = 1;
88 static final int READ_ENCRYPTED = 2; 109 static final int READ_ENCRYPTED = 2;
89 static final int WRITE_ENCRYPTED = 3; 110 static final int WRITE_ENCRYPTED = 3;
90 static final int NUM_BUFFERS = 4; 111 static final int NUM_BUFFERS = 4;
91 112
92 int _count = 0;
93 // Constructs a new secure client socket. 113 // Constructs a new secure client socket.
94 factory _SecureSocket(String host, int port) => 114 factory _SecureSocket.client(String host,
95 new _SecureSocket.internal(host, port, false); 115 int port,
116 bool sendClientCertificate,
117 String certificateName) =>
118 new _SecureSocket.internal(
119 host,
120 port,
121 false,
122 certificateName: certificateName,
123 sendClientCertificate: sendClientCertificate);
96 124
97 // Constructs a new secure server socket, with the named server certificate. 125 // Constructs a new secure server socket.
98 factory _SecureSocket.server(String host, 126 factory _SecureSocket.server(String host,
99 int port, 127 int port,
100 Socket socket, 128 Socket socket,
101 String certificateName) => 129 String certificateName,
102 new _SecureSocket.internal(host, port, true, socket, certificateName); 130 bool requestClientCertificate,
131 bool requireClientCertificate) =>
132 new _SecureSocket.internal(
133 host,
134 port,
135 true,
136 socket: socket,
137 certificateName: certificateName,
138 requestClientCertificate: requestClientCertificate,
139 requireClientCertificate: requireClientCertificate);
103 140
104 _SecureSocket.internal(String host, 141 _SecureSocket.internal(String host,
105 int port, 142 int port,
106 bool is_server, 143 bool is_server,
107 [Socket socket, 144 {Socket socket,
108 String certificateName]) 145 String certificateName,
146 bool requestClientCertificate: false,
147 bool requireClientCertificate: false,
148 bool sendClientCertificate: false})
109 : _host = host, 149 : _host = host,
110 _port = port, 150 _port = port,
151 _is_server = is_server,
111 _socket = socket, 152 _socket = socket,
112 _certificateName = certificateName, 153 _certificateName = certificateName,
113 _is_server = is_server, 154 _requestClientCertificate =
155 (requestClientCertificate == true) ||
156 (requireClientCertificate == true),
157 _requireClientCertificate = requireClientCertificate,
158 _sendClientCertificate = sendClientCertificate,
114 _secureFilter = new _SecureFilter() { 159 _secureFilter = new _SecureFilter() {
160 // Throw an ArgumentError if any field is invalid.
161 _verifyFields(requestClientCertificate);
115 if (_socket == null) { 162 if (_socket == null) {
116 _socket = new Socket(host, port); 163 _socket = new Socket(host, port);
117 } 164 }
118 _socket.onConnect = _secureConnectHandler; 165 _socket.onConnect = _secureConnectHandler;
119 _socket.onData = _secureDataHandler; 166 _socket.onData = _secureDataHandler;
120 _socket.onClosed = _secureCloseHandler; 167 _socket.onClosed = _secureCloseHandler;
121 _socket.onError = _secureErrorHandler; 168 _socket.onError = _secureErrorHandler;
122 _secureFilter.init(); 169 _secureFilter.init();
123 _secureFilter.registerHandshakeCompleteCallback(_secureHandshakeCompleteHand ler); 170 _secureFilter.registerHandshakeCompleteCallback(
171 _secureHandshakeCompleteHandler);
172 }
173
174 void _verifyFields(bool requestClientCertificate) {
175 if (_host is! String) throw new ArgumentError(
176 "SecureSocket constructor: host is not a String");
177 if (_port is! int || _port < 0 || _port > 65535) throw new ArgumentError(
178 "SecureSocket constructor: port is not an int between 0 and 65536");
179 assert(_is_server is bool);
180 assert(_socket == null || _socket is Socket);
181 if (_certificateName != null && _certificateName is! String) {
182 throw new ArgumentError(
183 "SecureSocket constructor: certificateName is not null or a String");
184 }
185 if (_certificateName == null && _is_server) {
186 throw new ArgumentError(
187 "SecureSocket constructor: certificateName is null on a server");
188 }
189 if (requestClientCertificate is! bool) throw new ArgumentError(
190 "SecureSocket constructor: requestClientCertificate is not a bool");
191 if (_requireClientCertificate is! bool) throw new ArgumentError(
192 "SecureSocket constructor: requireClientCertificate is not a bool");
193 if (_sendClientCertificate is! bool) throw new ArgumentError(
194 "SecureSocket constructor: sendClientCertificate is not a bool");
124 } 195 }
125 196
126 int get port => _socket.port; 197 int get port => _socket.port;
127 198
128 String get remoteHost => _socket.remoteHost; 199 String get remoteHost => _socket.remoteHost;
129 200
130 int get remotePort => _socket.remotePort; 201 int get remotePort => _socket.remotePort;
131 202
132 void set onClosed(void callback()) { 203 void set onClosed(void callback()) {
133 if (_inputStream != null && callback != null) { 204 if (_inputStream != null && callback != null) {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 bytes = buffer.free; 386 bytes = buffer.free;
316 } 387 }
317 if (bytes > 0) { 388 if (bytes > 0) {
318 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset); 389 buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset);
319 buffer.length += bytes; 390 buffer.length += bytes;
320 } 391 }
321 _writeEncryptedData(); // Tries to flush all pipeline stages. 392 _writeEncryptedData(); // Tries to flush all pipeline stages.
322 return bytes; 393 return bytes;
323 } 394 }
324 395
396 X509Certificate get peerCertificate => _secureFilter.peerCertificate;
397
325 void _secureConnectHandler() { 398 void _secureConnectHandler() {
326 _connectPending = true; 399 _connectPending = true;
327 _secureFilter.connect(_host, _port, _is_server, _certificateName); 400 _secureFilter.connect(_host,
401 _port,
402 _is_server,
403 _certificateName,
404 _requestClientCertificate,
405 _requireClientCertificate,
406 _sendClientCertificate);
328 _status = HANDSHAKE; 407 _status = HANDSHAKE;
329 _secureHandshake(); 408 _secureHandshake();
330 } 409 }
331 410
332 void _secureWriteHandler() { 411 void _secureWriteHandler() {
333 _writeEncryptedData(); 412 _writeEncryptedData();
334 if (_filterWriteEmpty && _closedWrite && !_socketClosedWrite) { 413 if (_filterWriteEmpty && _closedWrite && !_socketClosedWrite) {
335 close(true); 414 close(true);
336 } 415 }
337 if (_status == HANDSHAKE) { 416 if (_status == HANDSHAKE) {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 // This must be asynchronous, because we are in a read or readList call. 630 // This must be asynchronous, because we are in a read or readList call.
552 new Timer(0, (_) => _secureCloseHandler()); 631 new Timer(0, (_) => _secureCloseHandler());
553 } 632 }
554 } 633 }
555 } 634 }
556 635
557 bool get _socketClosed => _closedRead; 636 bool get _socketClosed => _closedRead;
558 637
559 // _SecureSocket cannot extend _Socket and use _Socket's factory constructor. 638 // _SecureSocket cannot extend _Socket and use _Socket's factory constructor.
560 Socket _socket; 639 Socket _socket;
561 String _host; 640 final String _host;
562 int _port; 641 final int _port;
563 bool _is_server; 642 final bool _is_server;
564 String _certificateName; 643 final String _certificateName;
644 final bool _requestClientCertificate;
645 final bool _requireClientCertificate;
646 final bool _sendClientCertificate;
565 647
566 var _status = NOT_CONNECTED; 648 var _status = NOT_CONNECTED;
567 bool _socketClosedRead = false; // The network socket is closed for reading. 649 bool _socketClosedRead = false; // The network socket is closed for reading.
568 bool _socketClosedWrite = false; // The network socket is closed for writing. 650 bool _socketClosedWrite = false; // The network socket is closed for writing.
569 bool _closedRead = false; // The secure socket has fired an onClosed event. 651 bool _closedRead = false; // The secure socket has fired an onClosed event.
570 bool _closedWrite = false; // The secure socket has been closed for writing. 652 bool _closedWrite = false; // The secure socket has been closed for writing.
571 bool _filterReadEmpty = true; // There is no buffered data to read. 653 bool _filterReadEmpty = true; // There is no buffered data to read.
572 bool _filterWriteEmpty = true; // There is no buffered data to be written. 654 bool _filterWriteEmpty = true; // There is no buffered data to be written.
573 _SocketInputStream _inputStream; 655 _SocketInputStream _inputStream;
574 _SocketOutputStream _outputStream; 656 _SocketOutputStream _outputStream;
(...skipping 29 matching lines...) Expand all
604 int length; 686 int length;
605 } 687 }
606 688
607 689
608 abstract class _SecureFilter { 690 abstract class _SecureFilter {
609 external factory _SecureFilter(); 691 external factory _SecureFilter();
610 692
611 void connect(String hostName, 693 void connect(String hostName,
612 int port, 694 int port,
613 bool is_server, 695 bool is_server,
614 String certificateName); 696 String certificateName,
697 bool requestClientCertificate,
698 bool requireClientCertificate,
699 bool sendClientCertificate);
615 void destroy(); 700 void destroy();
616 void handshake(); 701 void handshake();
617 void init(); 702 void init();
703 X509Certificate get peerCertificate;
618 int processBuffer(int bufferIndex); 704 int processBuffer(int bufferIndex);
619 void registerBadCertificateCallback(Function callback); 705 void registerBadCertificateCallback(Function callback);
620 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); 706 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);
621 707
622 List<_ExternalBuffer> get buffers; 708 List<_ExternalBuffer> get buffers;
623 } 709 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698