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

Unified Diff: sdk/lib/io/secure_socket.dart

Issue 1319703002: Breaking Change: merge BoringSSL branch into master (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months 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
« no previous file with comments | « sdk/lib/io/secure_server_socket.dart ('k') | sdk/lib/io/security_context.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/secure_socket.dart
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 6b36ebaeac00abb0e7637ecbe58b8e19fc8130a4..468e1bd44652ac513db10a7ca61e31b2dc2e446c 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -18,16 +18,6 @@ abstract class SecureSocket implements Socket {
* [host] on port [port]. The returned Future will complete with a
* [SecureSocket] that is connected and ready for subscription.
*
- * If [sendClientCertificate] is set to true, the socket will send a client
- * certificate if one is requested by the server.
- *
- * If [certificateName] is the nickname of a certificate in the certificate
- * database, that certificate will be sent.
- *
- * If [certificateName] is null, which is the usual use case, an
- * appropriate certificate will be searched for in the database and
- * sent automatically, based on what the server says it will accept.
- *
* [onBadCertificate] is an optional handler for unverifiable certificates.
* The handler receives the [X509Certificate], and can inspect it and
* decide (or let the user decide) whether to accept
@@ -37,14 +27,13 @@ abstract class SecureSocket implements Socket {
static Future<SecureSocket> connect(
host,
int port,
- {bool sendClientCertificate: false,
- String certificateName,
+ {SecurityContext context,
bool onBadCertificate(X509Certificate certificate),
+ bool sendClientCertificate,
List<String> supportedProtocols}) {
return RawSecureSocket.connect(host,
port,
- sendClientCertificate: sendClientCertificate,
- certificateName: certificateName,
+ context: context,
onBadCertificate: onBadCertificate,
supportedProtocols: supportedProtocols)
.then((rawSocket) => new SecureSocket._(rawSocket));
@@ -79,8 +68,7 @@ abstract class SecureSocket implements Socket {
static Future<SecureSocket> secure(
Socket socket,
{host,
- bool sendClientCertificate: false,
- String certificateName,
+ SecurityContext context,
bool onBadCertificate(X509Certificate certificate)}) {
var completer = new Completer();
(socket as dynamic)._detachRaw()
@@ -89,7 +77,7 @@ abstract class SecureSocket implements Socket {
detachedRaw[0],
subscription: detachedRaw[1],
host: host,
- sendClientCertificate: sendClientCertificate,
+ context: context,
onBadCertificate: onBadCertificate);
})
.then((raw) {
@@ -121,7 +109,7 @@ abstract class SecureSocket implements Socket {
*/
static Future<SecureSocket> secureServer(
Socket socket,
- String certificateName,
+ SecurityContext context,
{List<int> bufferedData,
bool requestClientCertificate: false,
bool requireClientCertificate: false,
@@ -131,7 +119,7 @@ abstract class SecureSocket implements Socket {
.then((detachedRaw) {
return RawSecureSocket.secureServer(
detachedRaw[0],
- certificateName,
+ context,
subscription: detachedRaw[1],
bufferedData: bufferedData,
requestClientCertificate: requestClientCertificate,
@@ -168,52 +156,6 @@ abstract class SecureSocket implements Socket {
void renegotiate({bool useSessionCache: true,
bool requestClientCertificate: false,
bool requireClientCertificate: false});
-
- /**
- * Initializes the NSS library. If [initialize] is not called, the library
- * is automatically initialized as if [initialize] were called with no
- * arguments. If [initialize] is called more than once, or called after
- * automatic initialization has happened (when a secure connection is made),
- * then a TlsException is thrown.
- *
- * The optional argument [database] is the path to a certificate database
- * directory containing root certificates for verifying certificate paths on
- * client connections, and server certificates to provide on server
- * connections. The argument [password] should be used when creating
- * secure server sockets, to allow the private key of the server
- * certificate to be fetched. If [useBuiltinRoots] is true (the default),
- * then a built-in set of root certificates for trusted certificate
- * authorities is merged with the certificates in the database.
- * The list of built-in root certificates, and documentation about this
- * default database, is available at
- * http://www.mozilla.org/projects/security/certs/included/ .
- *
- * If the [database] argument is omitted, then only the
- * builtin root certificates are used. If [useBuiltinRoots] is also false,
- * then no certificates are available.
- *
- * Examples:
- * 1) Use only the builtin root certificates:
- * SecureSocket.initialize(); or
- *
- * 2) Use a specified database directory and the builtin roots:
- * SecureSocket.initialize(database: 'path/to/my/database',
- * password: 'my_password');
- *
- * 3) Use a specified database directory, without builtin roots:
- * SecureSocket.initialize(database: 'path/to/my/database',
- * password: 'my_password'.
- * useBuiltinRoots: false);
- *
- * The database should be an NSS certificate database directory
- * containing a cert9.db file, not a cert8.db file. This version of
- * the database can be created using the NSS certutil tool with "sql:" in
- * front of the absolute path of the database directory, or setting the
- * environment variable [[NSS_DEFAULT_DB_TYPE]] to "sql".
- */
- external static void initialize({String database,
- String password,
- bool useBuiltinRoots: true});
}
@@ -224,7 +166,7 @@ abstract class SecureSocket implements Socket {
* RawSecureServerSocket, also returns RawSecureSocket objects representing
* the server end of a secure connection.
* The certificate provided by the server is checked
- * using the certificate database provided in SecureSocket.initialize, and/or
+ * using the trusted certificates set in the SecurityContext object and/or
* the default built-in root certificates.
*/
abstract class RawSecureSocket implements RawSocket {
@@ -233,8 +175,9 @@ abstract class RawSecureSocket implements RawSocket {
* host on the given port. The returned Future is completed with the
* RawSecureSocket when it is connected and ready for subscription.
*
- * The certificate provided by the server is checked using the certificate
- * database provided in [SecureSocket.initialize], and/or the default built-in
+ * The certificate provided by the server is checked
+ * using the trusted certificates set in the SecurityContext object and/or
+ * the default built-in
* root certificates. If [sendClientCertificate] is
* set to true, the socket will send a client certificate if one is
* requested by the server. If [certificateName] is the nickname of
@@ -252,24 +195,20 @@ abstract class RawSecureSocket implements RawSocket {
static Future<RawSecureSocket> connect(
host,
int port,
- {bool sendClientCertificate: false,
- String certificateName,
+ {SecurityContext context,
bool onBadCertificate(X509Certificate certificate),
List<String> supportedProtocols}) {
_RawSecureSocket._verifyFields(
host,
port,
- certificateName,
false,
false,
false,
- sendClientCertificate,
onBadCertificate);
return RawSocket.connect(host, port)
.then((socket) {
return secure(socket,
- sendClientCertificate: sendClientCertificate,
- certificateName: certificateName,
+ context: context,
onBadCertificate: onBadCertificate,
supportedProtocols: supportedProtocols);
});
@@ -307,8 +246,7 @@ abstract class RawSecureSocket implements RawSocket {
RawSocket socket,
{StreamSubscription subscription,
host,
- bool sendClientCertificate: false,
- String certificateName,
+ SecurityContext context,
bool onBadCertificate(X509Certificate certificate),
List<String> supportedProtocols}) {
socket.readEventsEnabled = false;
@@ -316,11 +254,10 @@ abstract class RawSecureSocket implements RawSocket {
return _RawSecureSocket.connect(
host != null ? host : socket.address.host,
socket.port,
- certificateName,
is_server: false,
socket: socket,
subscription: subscription,
- sendClientCertificate: sendClientCertificate,
+ context: context,
onBadCertificate: onBadCertificate,
supportedProtocols: supportedProtocols);
}
@@ -350,7 +287,7 @@ abstract class RawSecureSocket implements RawSocket {
*/
static Future<RawSecureSocket> secureServer(
RawSocket socket,
- String certificateName,
+ SecurityContext context,
{StreamSubscription subscription,
List<int> bufferedData,
bool requestClientCertificate: false,
@@ -361,7 +298,7 @@ abstract class RawSecureSocket implements RawSocket {
return _RawSecureSocket.connect(
socket.address,
socket.remotePort,
- certificateName,
+ context: context,
is_server: true,
socket: socket,
subscription: subscription,
@@ -402,15 +339,13 @@ abstract class RawSecureSocket implements RawSocket {
* X509Certificate represents an SSL certificate, with accessors to
* get the fields of the certificate.
*/
-class X509Certificate {
- X509Certificate(this.subject,
- this.issuer,
- this.startValidity,
- this.endValidity);
- final String subject;
- final String issuer;
- final DateTime startValidity;
- final DateTime endValidity;
+abstract class X509Certificate {
+ external factory X509Certificate._();
+
+ String get subject;
+ String get issuer;
+ DateTime get startValidity;
+ DateTime get endValidity;
}
@@ -456,10 +391,9 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
int _bufferedDataIndex = 0;
final InternetAddress address;
final bool is_server;
- final String certificateName;
+ SecurityContext context;
final bool requestClientCertificate;
final bool requireClientCertificate;
- final bool sendClientCertificate;
final Function onBadCertificate;
var _status = HANDSHAKE;
@@ -484,8 +418,8 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
static Future<_RawSecureSocket> connect(
host,
int requestedPort,
- String certificateName,
{bool is_server,
+ SecurityContext context,
RawSocket socket,
StreamSubscription subscription,
List<int> bufferedData,
@@ -494,22 +428,21 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
bool sendClientCertificate: false,
bool onBadCertificate(X509Certificate certificate),
List<String> supportedProtocols}) {
- _verifyFields(host, requestedPort, certificateName, is_server,
+ _verifyFields(host, requestedPort, is_server,
requestClientCertificate, requireClientCertificate,
- sendClientCertificate, onBadCertificate);
+ onBadCertificate);
if (host is InternetAddress) host = host.host;
var address = socket.address;
if (host != null) address = address._cloneWithNewHost(host);
return new _RawSecureSocket(address,
requestedPort,
- certificateName,
is_server,
+ context,
socket,
subscription,
bufferedData,
requestClientCertificate,
requireClientCertificate,
- sendClientCertificate,
onBadCertificate,
supportedProtocols)
._handshakeComplete.future;
@@ -518,16 +451,18 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
_RawSecureSocket(
this.address,
int requestedPort,
- this.certificateName,
this.is_server,
+ this.context,
RawSocket this._socket,
this._socketSubscription,
this._bufferedData,
this.requestClientCertificate,
this.requireClientCertificate,
- this.sendClientCertificate,
this.onBadCertificate(X509Certificate certificate),
List<String> supportedProtocols) {
+ if (context == null) {
+ context = SecurityContext.defaultContext;
+ }
_controller = new StreamController<RawSocketEvent>(
sync: true,
onListen: _onSubscriptionStateChange,
@@ -570,144 +505,24 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
..onDone(_doneHandler);
}
try {
+ var encodedProtocols =
+ SecurityContext._protocolsToLengthEncoding(supportedProtocols);
_secureFilter.connect(address.host,
- (address as dynamic)._in_addr,
- port,
+ context,
is_server,
- certificateName,
requestClientCertificate ||
requireClientCertificate,
requireClientCertificate,
- sendClientCertificate,
- _protocolsToLengthEncoding(supportedProtocols));
+ // TODO(whesse): Remove sendClientCertificate
+ // argument, or add it to API.
+ false, // sendClientCertificate,
+ encodedProtocols);
_secureHandshake();
} catch (e, s) {
_reportError(e, s);
}
}
- /// Encodes a set of supported protocols for ALPN/NPN usage.
- ///
- /// The `protocols` list is expected to contain protocols in descending order
- /// of preference.
- ///
- /// See RFC 7301 (https://tools.ietf.org/html/rfc7301) for the encoding of
- /// `List<String> protocols`:
- /// opaque ProtocolName<1..2^8-1>;
- ///
- /// struct {
- /// ProtocolName protocol_name_list<2..2^16-1>
- /// } ProtocolNameList;
- ///
- /// The encoding of the opaque `ProtocolName<lower..upper>` vector is
- /// described in RFC 2246: 4.3 Vectors.
- ///
- /// Note: Even though this encoding scheme would allow a total
- /// `ProtocolNameList` length of 65535, this limit cannot be reached. Testing
- /// showed that more than ~ 65480 bytes will fail to negogiate a protocol.
- /// We will be conservative and support only messages up to (1<<15) -1 bytes.
- ///
- /// Our NSS implementation will support ALPN and NPN transparently. The
- /// default protocol will be the first in the encoded Uint8List.
- ///
- /// NOTE: The NSS library will treat the first protocol as the fallback
- /// protocol. The remaining ones are sorted in (decreasing) priority order.
- /// We therefore put the protocol least desired to the front, to make it the
- /// default.
- Uint8List _protocolsToLengthEncoding(List<String> protocols) {
- if (protocols == null || protocols.length == 0) {
- return new Uint8List(0);
- }
- int protocolsLength = protocols.length;
-
- // Calculate the number of bytes we will need if it is ASCII.
- int expectedLength = protocolsLength;
- for (int i = 0; i < protocolsLength; i++) {
- int length = protocols[i].length;
- if (length > 0 && length <= 255) {
- expectedLength += length;
- } else {
- throw new ArgumentError(
- 'Length of protocol must be between 1 and 255 (was: $length).');
- }
- }
-
- if (expectedLength >= (1 << 15)) {
- throw new ArgumentError(
- 'The maximum message length supported is 2^15-1.');
- }
-
- // Try encoding the `List<String> protocols` array using fast ASCII path.
- var bytes = new Uint8List(expectedLength);
- int bytesOffset = 0;
- for (int i = 0; i < protocolsLength; i++) {
- // The last protocol will be encoded as the first/default one in the list.
- // (i.e. rotate `protocols` by 1 to the right).
- int index = i;
- if (index == 0) index = protocols.length;
- String proto = protocols[index - 1];
-
- // Add length byte.
- bytes[bytesOffset++] = proto.length;
- int bits = 0;
-
- // Add protocol bytes.
- for (int j = 0; j < proto.length; j++) {
- var char = proto.codeUnitAt(j);
- bits |= char;
- bytes[bytesOffset++] = char & 0xff;
- }
-
- // Go slow case if we have encountered anything non-ascii.
- if (bits > 0x7f) {
- return _protocolsToLengthEncodingNonAsciiBailout(protocols);
- }
- }
- return bytes;
- }
-
- Uint8List _protocolsToLengthEncodingNonAsciiBailout(List<String> protocols) {
- void addProtocol(List<int> outBytes, String protocol) {
- var protocolBytes = UTF8.encode(protocol);
- var len = protocolBytes.length;
-
- if (len > 255) {
- throw new ArgumentError(
- 'Length of protocol must be between 1 and 255 (was: $len)');
- }
- // Add length byte.
- outBytes.add(len);
-
- // Add protocol bytes.
- outBytes.addAll(protocolBytes);
- }
-
- List<int> bytes = [];
- addProtocol(bytes, protocols.last);
- for (var i = 0; i < protocols.length -1; i++) {
- addProtocol(bytes, protocols[i]);
- }
-
- if (bytes.length >= (1 << 15)) {
- throw new ArgumentError(
- 'The maximum message length supported is 2^15-1.');
- }
-
- return new Uint8List.fromList(bytes);
- }
-
- void _addProtocolBytes(List<int> outBytes, String protocol) {
- var protocolBytes = UTF8.encode(protocol);
- var len = protocolBytes.length;
-
- if (len > 255) {
- throw new ArgumentError(
- 'Cannot support protocols with more than 255 characters');
- }
- outBytes.add(len);
- outBytes.addAll(protocolBytes);
- }
-
StreamSubscription listen(void onData(RawSocketEvent data),
{Function onError,
void onDone(),
@@ -721,11 +536,9 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
static void _verifyFields(host,
int requestedPort,
- String certificateName,
bool is_server,
bool requestClientCertificate,
bool requireClientCertificate,
- bool sendClientCertificate,
Function onBadCertificate) {
if (host is! String && host is! InternetAddress) {
throw new ArgumentError("host is not a String or an InternetAddress");
@@ -736,21 +549,12 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
if (requestedPort < 0 || requestedPort > 65535) {
throw new ArgumentError("requestedPort is not in the range 0..65535");
}
- if (certificateName != null && certificateName is! String) {
- throw new ArgumentError("certificateName is not null or a String");
- }
- if (certificateName == null && is_server) {
- throw new ArgumentError("certificateName is null on a server");
- }
if (requestClientCertificate is! bool) {
throw new ArgumentError("requestClientCertificate is not a bool");
}
if (requireClientCertificate is! bool) {
throw new ArgumentError("requireClientCertificate is not a bool");
}
- if (sendClientCertificate is! bool) {
- throw new ArgumentError("sendClientCertificate is not a bool");
- }
if (onBadCertificate != null && onBadCertificate is! Function) {
throw new ArgumentError("onBadCertificate is not null or a Function");
}
@@ -891,7 +695,7 @@ class _RawSecureSocket extends Stream<RawSocketEvent>
if (onBadCertificate == null) return false;
var result = onBadCertificate(certificate);
if (result is bool) return result;
- throw new ArgumentError(
+ throw new HandshakeException(
"onBadCertificate callback returned non-boolean $result");
}
@@ -1360,10 +1164,8 @@ abstract class _SecureFilter {
external factory _SecureFilter();
void connect(String hostName,
- Uint8List addr,
- int port,
+ SecurityContext context,
bool is_server,
- String certificateName,
bool requestClientCertificate,
bool requireClientCertificate,
bool sendClientCertificate,
« no previous file with comments | « sdk/lib/io/secure_server_socket.dart ('k') | sdk/lib/io/security_context.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698