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

Side by Side Diff: sdk/lib/io/security_context.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, 3 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 unified diff | Download patch
« no previous file with comments | « sdk/lib/io/secure_socket.dart ('k') | tests/lib/mirrors/invocation_fuzz_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
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.
4
5 part of dart.io;
6
7 /**
8 * The object containing the certificates to trust when making
9 * a secure client connection, and the certificate chain and
10 * private key to serve from a secure server.
11 *
12 * The [SecureSocket] and [SecureServer] classes take a SecurityContext
13 * as an argument to their connect and bind methods.
14 *
15 * Certificates and keys can be added to a SecurityContext from PEM files
16 * on the disk. A PEM file contains one or more base-64 encoded DER-serialized
17 * ASN1 objects, surrounded with delimiter strings like
18 * "-----BEGIN CERTIFICATE -----" and "-----END CERTIFICATE-----".
19 * Distinguished encoding rules (DER) is a canonical binary serialization
20 * of ASN1 objects into an octet string.
21 */
22 abstract class SecurityContext {
23 external factory SecurityContext();
24 external static SecurityContext get defaultContext;
25
26 /**
27 * Sets the private key for a server certificate or client certificate.
28 * A secure connection using this SecurityContext will use this key with
29 * the server or client certificate to sign and decrypt messages.
30 * [keyFile] is a PEM file containing an encrypted
31 * private key, encrypted with [password]. An unencrypted file can be
32 * used, but this is not usual.
33 */
34 void usePrivateKey(String keyFile, {String password});
35
36 /**
37 * Sets the set of trusted X509 certificates used by [SecureSocket]
38 * client connections, when connecting to a secure server.
39 *
40 * There are two ways to set a set of trusted certificates, with a single
41 * PEM file, or with a directory containing individual PEM files for
42 * certificates.
43 *
44 * [file] is an optional PEM file containing X509 certificates, usually
45 * root certificates from certificate authorities.
46 *
47 * [directory] is an optional directory containing PEM files. The directory
48 * must also have filesystem links added, which link extra filenames based
49 * on the hash of a certificate's distinguished name (DN) to the file
50 * containing that certificate. OpenSSL contains a tool called c_rehash
51 * to create these links in a directory.
52 */
53 void setTrustedCertificates({String file, String directory});
54
55 /**
56 * Sets the chain of X509 certificates served by [SecureServer]
57 * when making secure connections, including the server certificate.
58 * [file] is an PEM file containing X509 certificates, starting with
59 * the root authority and intermediate authorities forming the signed
60 * chain to the server certificate, and ending with the server certificate.
61 * The private key for the server certificate is set by [usePrivateKey].
62 */
63 void useCertificateChain(String file);
64
65 /**
66 * Sets the list of authority names that a [SecureServer] will advertise
67 * as accepted, when requesting a client certificate from a connecting
68 * client. [file] is a PEM file containing the accepted signing authority
69 * certificates - the authority names are extracted from the certificates.
70 */
71 void setClientAuthorities(String file);
72
73 /**
74 * Sets the list of application-level protocols supported by a client
75 * connection or server connection. The ALPN (application level protocol
76 * negotiation) extension to TLS allows a client to send a list of
77 * protocols in the TLS client hello message, and the server to pick
78 * one and send the selected one back in its server hello message.
79 *
80 * Separate lists of protocols can be sent for client connections and
81 * for server connections, using the same SecurityContext. The [isServer]
82 * boolean argument specifies whether to set the list for server connections
83 * or client connections.
84 */
85 void setAlpnProtocols(List<String> protocols, bool isServer);
86
87 /// Encodes a set of supported protocols for ALPN/NPN usage.
88 ///
89 /// The `protocols` list is expected to contain protocols in descending order
90 /// of preference.
91 ///
92 /// See RFC 7301 (https://tools.ietf.org/html/rfc7301) for the encoding of
93 /// `List<String> protocols`:
94 /// opaque ProtocolName<1..2^8-1>;
95 ///
96 /// struct {
97 /// ProtocolName protocol_name_list<2..2^16-1>
98 /// } ProtocolNameList;
99 ///
100 /// The encoding of the opaque `ProtocolName<lower..upper>` vector is
101 /// described in RFC 2246: 4.3 Vectors.
102 ///
103 /// Note: Even though this encoding scheme would allow a total
104 /// `ProtocolNameList` length of 65535, this limit cannot be reached. Testing
105 /// showed that more than ~ 2^14 bytes will fail to negotiate a protocol.
106 /// We will be conservative and support only messages up to (1<<13)-1 bytes.
107 static Uint8List _protocolsToLengthEncoding(List<String> protocols) {
108 if (protocols == null || protocols.length == 0) {
109 return new Uint8List(0);
110 }
111 int protocolsLength = protocols.length;
112
113 // Calculate the number of bytes we will need if it is ASCII.
114 int expectedLength = protocolsLength;
115 for (int i = 0; i < protocolsLength; i++) {
116 int length = protocols[i].length;
117 if (length > 0 && length <= 255) {
118 expectedLength += length;
119 } else {
120 throw new ArgumentError(
121 'Length of protocol must be between 1 and 255 (was: $length).');
122 }
123 }
124
125 if (expectedLength >= (1 << 13)) {
126 throw new ArgumentError(
127 'The maximum message length supported is 2^13-1.');
128 }
129
130 // Try encoding the `List<String> protocols` array using fast ASCII path.
131 var bytes = new Uint8List(expectedLength);
132 int bytesOffset = 0;
133 for (int i = 0; i < protocolsLength; i++) {
134 String proto = protocols[i];
135
136 // Add length byte.
137 bytes[bytesOffset++] = proto.length;
138 int bits = 0;
139
140 // Add protocol bytes.
141 for (int j = 0; j < proto.length; j++) {
142 var char = proto.codeUnitAt(j);
143 bits |= char;
144 bytes[bytesOffset++] = char & 0xff;
145 }
146
147 // Go slow case if we have encountered anything non-ascii.
148 if (bits > 0x7f) {
149 return _protocolsToLengthEncodingNonAsciiBailout(protocols);
150 }
151 }
152 return bytes;
153 }
154
155 static Uint8List _protocolsToLengthEncodingNonAsciiBailout(
156 List<String> protocols) {
157 void addProtocol(List<int> outBytes, String protocol) {
158 var protocolBytes = UTF8.encode(protocol);
159 var len = protocolBytes.length;
160
161 if (len > 255) {
162 throw new ArgumentError(
163 'Length of protocol must be between 1 and 255 (was: $len)');
164 }
165 // Add length byte.
166 outBytes.add(len);
167
168 // Add protocol bytes.
169 outBytes.addAll(protocolBytes);
170 }
171
172 List<int> bytes = [];
173 for (var i = 0; i < protocols.length; i++) {
174 addProtocol(bytes, protocols[i]);
175 }
176
177 if (bytes.length >= (1 << 13)) {
178 throw new ArgumentError(
179 'The maximum message length supported is 2^13-1.');
180 }
181
182 return new Uint8List.fromList(bytes);
183 }
184 }
OLDNEW
« no previous file with comments | « sdk/lib/io/secure_socket.dart ('k') | tests/lib/mirrors/invocation_fuzz_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698