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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/io/secure_socket.dart
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 272123796102cb9a5bff980766e2b169456f1443..e2cb9016218e66a3849b57c52f6755107047f90c 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -11,9 +11,22 @@ abstract class SecureSocket implements Socket {
/**
* Constructs a new secure client socket and connect it to the given
* host on the given port. The returned socket is not yet connected
- * but ready for registration of callbacks.
+ * but ready for registration of callbacks. If sendClientCertificate is
+ * set to true, the socket will send a client certificate if one is
+ * requested by the server. An appropriate certificate will
+ * be searched for and chosen automatically, based on what the server
+ * says it will accept, unless clientCertificate is set to the nickname of
+ * 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.
*/
- factory SecureSocket(String host, int port) => new _SecureSocket(host, port);
+ factory SecureSocket(String host,
+ int port,
+ {bool sendClientCertificate: false,
+ 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.
+ return new _SecureSocket.client(host,
+ port,
+ sendClientCertificate,
+ certificateName);
+ }
/**
* Install a handler for unverifiable certificates. The handler can inspect
@@ -23,6 +36,14 @@ abstract class SecureSocket implements Socket {
*/
void set onBadCertificate(bool callback(X509Certificate certificate));
+ /**
+ * Get the peerCertificate for a connected secure socket. For a server
+ * socket, this will return the client certificate, or null, if no
+ * 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.
+ * will return the server's certificate.
+ */
+ X509Certificate get peerCertificate;
+
/**
* Initializes the NSS library with the path to a certificate database
* containing root certificates for verifying certificate paths on
@@ -89,29 +110,55 @@ class _SecureSocket implements SecureSocket {
static final int WRITE_ENCRYPTED = 3;
static final int NUM_BUFFERS = 4;
- int _count = 0;
// Constructs a new secure client socket.
- factory _SecureSocket(String host, int port) =>
- new _SecureSocket.internal(host, port, false);
-
- // Constructs a new secure server socket, with the named server certificate.
+ factory _SecureSocket.client(String host,
+ int port,
+ bool sendClientCertificate,
+ String certificateName) =>
+ new _SecureSocket.internal(
+ host,
+ port,
+ false,
+ certificateName: certificateName,
+ sendClientCertificate: sendClientCertificate);
+
+ // Constructs a new secure server socket.
factory _SecureSocket.server(String host,
- int port,
- Socket socket,
- String certificateName) =>
- new _SecureSocket.internal(host, port, true, socket, certificateName);
+ int port,
+ Socket socket,
+ String certificateName,
+ bool requestClientCertificate,
+ bool requireClientCertificate) =>
+ new _SecureSocket.internal(
+ host,
+ port,
+ true,
+ socket: socket,
+ certificateName: certificateName,
+ requestClientCertificate: requestClientCertificate,
+ requireClientCertificate: requireClientCertificate);
_SecureSocket.internal(String host,
- int port,
- bool is_server,
- [Socket socket,
- String certificateName])
+ int port,
+ bool is_server,
+ {Socket socket,
+ String certificateName,
+ bool requestClientCertificate: false,
+ bool requireClientCertificate: false,
+ bool sendClientCertificate: false})
: _host = host,
_port = port,
+ _is_server = is_server,
_socket = socket,
_certificateName = certificateName,
- _is_server = is_server,
+ _requestClientCertificate =
+ (requestClientCertificate == true) ||
+ (requireClientCertificate == true),
+ _requireClientCertificate = requireClientCertificate,
+ _sendClientCertificate = sendClientCertificate,
_secureFilter = new _SecureFilter() {
+ // Throw an ArgumentError if any field is invalid.
+ _verifyFields(requestClientCertificate);
if (_socket == null) {
_socket = new Socket(host, port);
}
@@ -120,7 +167,31 @@ class _SecureSocket implements SecureSocket {
_socket.onClosed = _secureCloseHandler;
_socket.onError = _secureErrorHandler;
_secureFilter.init();
- _secureFilter.registerHandshakeCompleteCallback(_secureHandshakeCompleteHandler);
+ _secureFilter.registerHandshakeCompleteCallback(
+ _secureHandshakeCompleteHandler);
+ }
+
+ void _verifyFields(bool requestClientCertificate) {
+ if (_host is! String) throw new ArgumentError(
+ "SecureSocket constructor: host is not a String");
+ if (_port is! int || _port < 0 || _port > 65535) throw new ArgumentError(
+ "SecureSocket constructor: port is not an int between 0 and 65536");
+ assert(_is_server is bool);
+ assert(_socket == null || _socket is Socket);
+ if (_certificateName != null && _certificateName is! String) {
+ throw new ArgumentError(
+ "SecureSocket constructor: certificateName is not null or a String");
+ }
+ if (_certificateName == null && _is_server) {
+ throw new ArgumentError(
+ "SecureSocket constructor: certificateName is null on a server");
+ }
+ if (requestClientCertificate is! bool) throw new ArgumentError(
+ "SecureSocket constructor: requestClientCertificate is not a bool");
+ if (_requireClientCertificate is! bool) throw new ArgumentError(
+ "SecureSocket constructor: requireClientCertificate is not a bool");
+ if (_sendClientCertificate is! bool) throw new ArgumentError(
+ "SecureSocket constructor: sendClientCertificate is not a bool");
}
int get port => _socket.port;
@@ -322,9 +393,17 @@ class _SecureSocket implements SecureSocket {
return bytes;
}
+ X509Certificate get peerCertificate => _secureFilter.peerCertificate;
+
void _secureConnectHandler() {
_connectPending = true;
- _secureFilter.connect(_host, _port, _is_server, _certificateName);
+ _secureFilter.connect(_host,
+ _port,
+ _is_server,
+ _certificateName,
+ _requestClientCertificate,
+ _requireClientCertificate,
+ _sendClientCertificate);
_status = HANDSHAKE;
_secureHandshake();
}
@@ -558,10 +637,13 @@ class _SecureSocket implements SecureSocket {
// _SecureSocket cannot extend _Socket and use _Socket's factory constructor.
Socket _socket;
- String _host;
- int _port;
- bool _is_server;
- String _certificateName;
+ final String _host;
+ final int _port;
+ final bool _is_server;
+ final String _certificateName;
+ final bool _requestClientCertificate;
+ final bool _requireClientCertificate;
+ final bool _sendClientCertificate;
var _status = NOT_CONNECTED;
bool _socketClosedRead = false; // The network socket is closed for reading.
@@ -611,10 +693,14 @@ abstract class _SecureFilter {
void connect(String hostName,
int port,
bool is_server,
- String certificateName);
+ String certificateName,
+ bool requestClientCertificate,
+ bool requireClientCertificate,
+ bool sendClientCertificate);
void destroy();
void handshake();
void init();
+ X509Certificate get peerCertificate;
int processBuffer(int bufferIndex);
void registerBadCertificateCallback(Function callback);
void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);

Powered by Google App Engine
This is Rietveld 408576698