• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
6 #define QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "absl/container/flat_hash_map.h"
12 #include "absl/strings/string_view.h"
13 #include "absl/types/optional.h"
14 #include "quiche/quic/core/quic_connection_id.h"
15 #include "quiche/quic/core/quic_data_reader.h"
16 #include "quiche/quic/core/quic_data_writer.h"
17 #include "quiche/quic/core/quic_tag.h"
18 #include "quiche/quic/core/quic_types.h"
19 #include "quiche/quic/core/quic_versions.h"
20 #include "quiche/quic/platform/api/quic_socket_address.h"
21 
22 namespace quic {
23 
24 // TransportParameters contains parameters for QUIC's transport layer that are
25 // exchanged during the TLS handshake. This struct is a mirror of the struct in
26 // the "Transport Parameter Encoding" section of draft-ietf-quic-transport.
27 // This struct currently uses the values from draft 29.
28 struct QUIC_EXPORT_PRIVATE TransportParameters {
29   // The identifier used to differentiate transport parameters.
30   enum TransportParameterId : uint64_t;
31   // A map used to specify custom parameters.
32   using ParameterMap = absl::flat_hash_map<TransportParameterId, std::string>;
33   // Represents an individual QUIC transport parameter that only encodes a
34   // variable length integer. Can only be created inside the constructor for
35   // TransportParameters.
36   class QUIC_EXPORT_PRIVATE IntegerParameter {
37    public:
38     // Forbid constructing and copying apart from TransportParameters.
39     IntegerParameter() = delete;
40     IntegerParameter& operator=(const IntegerParameter&) = delete;
41     // Sets the value of this transport parameter.
42     void set_value(uint64_t value);
43     // Gets the value of this transport parameter.
44     uint64_t value() const;
45     // Validates whether the current value is valid.
46     bool IsValid() const;
47     // Writes to a crypto byte buffer, used during serialization. Does not write
48     // anything if the value is equal to the parameter's default value.
49     // Returns whether the write was successful.
50     bool Write(QuicDataWriter* writer) const;
51     // Reads from a crypto byte string, used during parsing.
52     // Returns whether the read was successful.
53     // On failure, this method will write a human-readable error message to
54     // |error_details|.
55     bool Read(QuicDataReader* reader, std::string* error_details);
56     // operator<< allows easily logging integer transport parameters.
57     friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
58         std::ostream& os, const IntegerParameter& param);
59 
60    private:
61     friend struct TransportParameters;
62     // Constructors for initial setup used by TransportParameters only.
63     // This constructor sets |default_value| and |min_value| to 0, and
64     // |max_value| to quiche::kVarInt62MaxValue.
65     explicit IntegerParameter(TransportParameterId param_id);
66     IntegerParameter(TransportParameterId param_id, uint64_t default_value,
67                      uint64_t min_value, uint64_t max_value);
68     IntegerParameter(const IntegerParameter& other) = default;
69     IntegerParameter(IntegerParameter&& other) = default;
70     // Human-readable string representation.
71     std::string ToString(bool for_use_in_list) const;
72 
73     // Number used to indicate this transport parameter.
74     TransportParameterId param_id_;
75     // Current value of the transport parameter.
76     uint64_t value_;
77     // Default value of this transport parameter, as per IETF specification.
78     const uint64_t default_value_;
79     // Minimum value of this transport parameter, as per IETF specification.
80     const uint64_t min_value_;
81     // Maximum value of this transport parameter, as per IETF specification.
82     const uint64_t max_value_;
83     // Ensures this parameter is not parsed twice in the same message.
84     bool has_been_read_;
85   };
86 
87   // Represents the preferred_address transport parameter that a server can
88   // send to clients.
89   struct QUIC_EXPORT_PRIVATE PreferredAddress {
90     PreferredAddress();
91     PreferredAddress(const PreferredAddress& other) = default;
92     PreferredAddress(PreferredAddress&& other) = default;
93     ~PreferredAddress();
94     bool operator==(const PreferredAddress& rhs) const;
95     bool operator!=(const PreferredAddress& rhs) const;
96 
97     QuicSocketAddress ipv4_socket_address;
98     QuicSocketAddress ipv6_socket_address;
99     QuicConnectionId connection_id;
100     std::vector<uint8_t> stateless_reset_token;
101 
102     // Allows easily logging.
103     std::string ToString() const;
104     friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
105         std::ostream& os, const TransportParameters& params);
106   };
107 
108   // LegacyVersionInformation represents the Google QUIC downgrade prevention
109   // mechanism ported to QUIC+TLS. It is exchanged using transport parameter ID
110   // 0x4752 and will eventually be deprecated in favor of
111   // draft-ietf-quic-version-negotiation.
112   struct QUIC_EXPORT_PRIVATE LegacyVersionInformation {
113     LegacyVersionInformation();
114     LegacyVersionInformation(const LegacyVersionInformation& other) = default;
115     LegacyVersionInformation& operator=(const LegacyVersionInformation& other) =
116         default;
117     LegacyVersionInformation& operator=(LegacyVersionInformation&& other) =
118         default;
119     LegacyVersionInformation(LegacyVersionInformation&& other) = default;
120     ~LegacyVersionInformation() = default;
121     bool operator==(const LegacyVersionInformation& rhs) const;
122     bool operator!=(const LegacyVersionInformation& rhs) const;
123     // When sent by the client, |version| is the initial version offered by the
124     // client (before any version negotiation packets) for this connection. When
125     // sent by the server, |version| is the version that is in use.
126     QuicVersionLabel version;
127 
128     // When sent by the server, |supported_versions| contains a list of all
129     // versions that the server would send in a version negotiation packet. When
130     // sent by the client, this is empty.
131     QuicVersionLabelVector supported_versions;
132 
133     // Allows easily logging.
134     std::string ToString() const;
135     friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
136         std::ostream& os,
137         const LegacyVersionInformation& legacy_version_information);
138   };
139 
140   // Version information used for version downgrade prevention and compatible
141   // version negotiation. See draft-ietf-quic-version-negotiation-05.
142   struct QUIC_EXPORT_PRIVATE VersionInformation {
143     VersionInformation();
144     VersionInformation(const VersionInformation& other) = default;
145     VersionInformation& operator=(const VersionInformation& other) = default;
146     VersionInformation& operator=(VersionInformation&& other) = default;
147     VersionInformation(VersionInformation&& other) = default;
148     ~VersionInformation() = default;
149     bool operator==(const VersionInformation& rhs) const;
150     bool operator!=(const VersionInformation& rhs) const;
151 
152     // Version that the sender has chosen to use on this connection.
153     QuicVersionLabel chosen_version;
154 
155     // When sent by the client, |other_versions| contains all the versions that
156     // this first flight is compatible with. When sent by the server,
157     // |other_versions| contains all of the versions supported by the server.
158     QuicVersionLabelVector other_versions;
159 
160     // Allows easily logging.
161     std::string ToString() const;
162     friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
163         std::ostream& os, const VersionInformation& version_information);
164   };
165 
166   TransportParameters();
167   TransportParameters(const TransportParameters& other);
168   ~TransportParameters();
169   bool operator==(const TransportParameters& rhs) const;
170   bool operator!=(const TransportParameters& rhs) const;
171 
172   // Represents the sender of the transport parameters. When |perspective| is
173   // Perspective::IS_CLIENT, this struct is being used in the client_hello
174   // handshake message; when it is Perspective::IS_SERVER, it is being used in
175   // the encrypted_extensions handshake message.
176   Perspective perspective;
177 
178   // Google QUIC downgrade prevention mechanism sent over QUIC+TLS.
179   absl::optional<LegacyVersionInformation> legacy_version_information;
180 
181   // IETF downgrade prevention and compatible version negotiation, see
182   // draft-ietf-quic-version-negotiation.
183   absl::optional<VersionInformation> version_information;
184 
185   // The value of the Destination Connection ID field from the first
186   // Initial packet sent by the client.
187   absl::optional<QuicConnectionId> original_destination_connection_id;
188 
189   // Maximum idle timeout expressed in milliseconds.
190   IntegerParameter max_idle_timeout_ms;
191 
192   // Stateless reset token used in verifying stateless resets.
193   std::vector<uint8_t> stateless_reset_token;
194 
195   // Limits the size of packets that the endpoint is willing to receive.
196   // This indicates that packets larger than this limit will be dropped.
197   IntegerParameter max_udp_payload_size;
198 
199   // Contains the initial value for the maximum amount of data that can
200   // be sent on the connection.
201   IntegerParameter initial_max_data;
202 
203   // Initial flow control limit for locally-initiated bidirectional streams.
204   IntegerParameter initial_max_stream_data_bidi_local;
205 
206   // Initial flow control limit for peer-initiated bidirectional streams.
207   IntegerParameter initial_max_stream_data_bidi_remote;
208 
209   // Initial flow control limit for unidirectional streams.
210   IntegerParameter initial_max_stream_data_uni;
211 
212   // Initial maximum number of bidirectional streams the peer may initiate.
213   IntegerParameter initial_max_streams_bidi;
214 
215   // Initial maximum number of unidirectional streams the peer may initiate.
216   IntegerParameter initial_max_streams_uni;
217 
218   // Exponent used to decode the ACK Delay field in ACK frames.
219   IntegerParameter ack_delay_exponent;
220 
221   // Maximum amount of time in milliseconds by which the endpoint will
222   // delay sending acknowledgments.
223   IntegerParameter max_ack_delay;
224 
225   // Minimum amount of time in microseconds by which the endpoint will
226   // delay sending acknowledgments. Used to enable sender control of ack delay.
227   IntegerParameter min_ack_delay_us;
228 
229   // Indicates lack of support for connection migration.
230   bool disable_active_migration;
231 
232   // Used to effect a change in server address at the end of the handshake.
233   std::unique_ptr<PreferredAddress> preferred_address;
234 
235   // Maximum number of connection IDs from the peer that an endpoint is willing
236   // to store.
237   IntegerParameter active_connection_id_limit;
238 
239   // The value that the endpoint included in the Source Connection ID field of
240   // the first Initial packet it sent.
241   absl::optional<QuicConnectionId> initial_source_connection_id;
242 
243   // The value that the server included in the Source Connection ID field of a
244   // Retry packet it sent.
245   absl::optional<QuicConnectionId> retry_source_connection_id;
246 
247   // Indicates support for the DATAGRAM frame and the maximum frame size that
248   // the sender accepts. See draft-ietf-quic-datagram.
249   IntegerParameter max_datagram_frame_size;
250 
251   // Google-specific transport parameter that carries an estimate of the
252   // initial round-trip time in microseconds.
253   IntegerParameter initial_round_trip_time_us;
254 
255   // Google internal handshake message.
256   absl::optional<std::string> google_handshake_message;
257 
258   // Google-specific connection options.
259   absl::optional<QuicTagVector> google_connection_options;
260 
261   // Validates whether transport parameters are valid according to
262   // the specification. If the transport parameters are not valid, this method
263   // will write a human-readable error message to |error_details|.
264   bool AreValid(std::string* error_details) const;
265 
266   // Custom parameters that may be specific to application protocol.
267   ParameterMap custom_parameters;
268 
269   // Allows easily logging transport parameters.
270   std::string ToString() const;
271   friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
272       std::ostream& os, const TransportParameters& params);
273 };
274 
275 // Serializes a TransportParameters struct into the format for sending it in a
276 // TLS extension. The serialized bytes are written to |*out|. Returns if the
277 // parameters are valid and serialization succeeded.
278 QUIC_EXPORT_PRIVATE bool SerializeTransportParameters(
279     const TransportParameters& in, std::vector<uint8_t>* out);
280 
281 // Parses bytes from the quic_transport_parameters TLS extension and writes the
282 // parsed parameters into |*out|. Input is read from |in| for |in_len| bytes.
283 // |perspective| indicates whether the input came from a client or a server.
284 // This method returns true if the input was successfully parsed.
285 // On failure, this method will write a human-readable error message to
286 // |error_details|.
287 QUIC_EXPORT_PRIVATE bool ParseTransportParameters(
288     ParsedQuicVersion version, Perspective perspective, const uint8_t* in,
289     size_t in_len, TransportParameters* out, std::string* error_details);
290 
291 // Serializes |in| and |application_data| in a deterministic format so that
292 // multiple calls to SerializeTransportParametersForTicket with the same inputs
293 // will generate the same output, and if the inputs differ, then the output will
294 // differ. The output of this function is used by the server in
295 // SSL_set_quic_early_data_context to determine whether early data should be
296 // accepted: Early data will only be accepted if the inputs to this function
297 // match what they were on the connection that issued an early data capable
298 // ticket.
299 QUIC_EXPORT_PRIVATE bool SerializeTransportParametersForTicket(
300     const TransportParameters& in, const std::vector<uint8_t>& application_data,
301     std::vector<uint8_t>* out);
302 
303 // Removes reserved values from custom_parameters and versions.
304 // The resulting value can be reliably compared with an original or other
305 // deserialized value.
306 QUIC_EXPORT_PRIVATE void DegreaseTransportParameters(
307     TransportParameters& parameters);
308 
309 }  // namespace quic
310 
311 #endif  // QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
312