/src/boringssl/ssl/s3_both.cc
Line | Count | Source |
1 | | // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | // you may not use this file except in compliance with the License. |
6 | | // You may obtain a copy of the License at |
7 | | // |
8 | | // https://www.apache.org/licenses/LICENSE-2.0 |
9 | | // |
10 | | // Unless required by applicable law or agreed to in writing, software |
11 | | // distributed under the License is distributed on an "AS IS" BASIS, |
12 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | // See the License for the specific language governing permissions and |
14 | | // limitations under the License. |
15 | | |
16 | | #include <openssl/ssl.h> |
17 | | |
18 | | #include <assert.h> |
19 | | #include <limits.h> |
20 | | #include <string.h> |
21 | | |
22 | | #include <tuple> |
23 | | |
24 | | #include <openssl/buf.h> |
25 | | #include <openssl/bytestring.h> |
26 | | #include <openssl/err.h> |
27 | | #include <openssl/evp.h> |
28 | | #include <openssl/md5.h> |
29 | | #include <openssl/mem.h> |
30 | | #include <openssl/nid.h> |
31 | | #include <openssl/rand.h> |
32 | | #include <openssl/sha2.h> |
33 | | |
34 | | #include "../crypto/internal.h" |
35 | | #include "internal.h" |
36 | | |
37 | | |
38 | | BSSL_NAMESPACE_BEGIN |
39 | | |
40 | | static bool add_record_to_flight(SSL *ssl, uint8_t type, |
41 | 259k | Span<const uint8_t> in) { |
42 | | // The caller should have flushed |pending_hs_data| first. |
43 | 259k | assert(!ssl->s3->pending_hs_data); |
44 | | // We'll never add a flight while in the process of writing it out. |
45 | 259k | assert(ssl->s3->pending_flight_offset == 0); |
46 | | |
47 | 259k | if (ssl->s3->pending_flight == nullptr) { |
48 | 124k | ssl->s3->pending_flight.reset(BUF_MEM_new()); |
49 | 124k | if (ssl->s3->pending_flight == nullptr) { |
50 | 0 | return false; |
51 | 0 | } |
52 | 124k | } |
53 | | |
54 | 259k | size_t max_out = in.size() + SSL_max_seal_overhead(ssl); |
55 | 259k | size_t new_cap = ssl->s3->pending_flight->length + max_out; |
56 | 259k | if (max_out < in.size() || new_cap < max_out) { |
57 | 0 | OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); |
58 | 0 | return false; |
59 | 0 | } |
60 | | |
61 | 259k | size_t len; |
62 | 259k | if (!BUF_MEM_reserve(ssl->s3->pending_flight.get(), new_cap) || |
63 | 259k | !tls_seal_record(ssl, |
64 | 259k | (uint8_t *)ssl->s3->pending_flight->data + |
65 | 259k | ssl->s3->pending_flight->length, |
66 | 259k | &len, max_out, type, in.data(), in.size())) { |
67 | 0 | return false; |
68 | 0 | } |
69 | | |
70 | 259k | ssl->s3->pending_flight->length += len; |
71 | 259k | return true; |
72 | 259k | } |
73 | | |
74 | 270k | bool tls_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) { |
75 | | // Pick a modest size hint to save most of the |realloc| calls. |
76 | 270k | if (!CBB_init(cbb, 64) || // |
77 | 270k | !CBB_add_u8(cbb, type) || // |
78 | 270k | !CBB_add_u24_length_prefixed(cbb, body)) { |
79 | 0 | OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); |
80 | 0 | CBB_cleanup(cbb); |
81 | 0 | return false; |
82 | 0 | } |
83 | | |
84 | 270k | return true; |
85 | 270k | } |
86 | | |
87 | 270k | bool tls_finish_message(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg) { |
88 | 270k | return CBBFinishArray(cbb, out_msg); |
89 | 270k | } |
90 | | |
91 | 270k | bool tls_add_message(SSL *ssl, Array<uint8_t> msg) { |
92 | | // Pack handshake data into the minimal number of records. This avoids |
93 | | // unnecessary encryption overhead, notably in TLS 1.3 where we send several |
94 | | // encrypted messages in a row. For now, we do not do this for the null |
95 | | // cipher. The benefit is smaller and there is a risk of breaking buggy |
96 | | // implementations. |
97 | | // |
98 | | // TODO(crbug.com/374991962): See if we can do this uniformly. |
99 | 270k | Span<const uint8_t> rest = msg; |
100 | 270k | if (!SSL_is_quic(ssl) && ssl->s3->aead_write_ctx->is_null_cipher()) { |
101 | 80.9k | while (!rest.empty()) { |
102 | 40.4k | Span<const uint8_t> chunk = |
103 | 40.4k | rest.subspan(0, /* up to */ ssl->max_send_fragment); |
104 | 40.4k | rest = rest.subspan(chunk.size()); |
105 | | |
106 | 40.4k | if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, chunk)) { |
107 | 0 | return false; |
108 | 0 | } |
109 | 40.4k | } |
110 | 229k | } else { |
111 | 459k | while (!rest.empty()) { |
112 | | // Flush if |pending_hs_data| is full. |
113 | 229k | if (ssl->s3->pending_hs_data && |
114 | 67.5k | ssl->s3->pending_hs_data->length >= ssl->max_send_fragment && |
115 | 0 | !tls_flush_pending_hs_data(ssl)) { |
116 | 0 | return false; |
117 | 0 | } |
118 | | |
119 | 229k | size_t pending_len = |
120 | 229k | ssl->s3->pending_hs_data ? ssl->s3->pending_hs_data->length : 0; |
121 | 229k | Span<const uint8_t> chunk = |
122 | 229k | rest.subspan(0, /* up to */ ssl->max_send_fragment - pending_len); |
123 | 229k | assert(!chunk.empty()); |
124 | 229k | rest = rest.subspan(chunk.size()); |
125 | | |
126 | 229k | if (!ssl->s3->pending_hs_data) { |
127 | 162k | ssl->s3->pending_hs_data.reset(BUF_MEM_new()); |
128 | 162k | } |
129 | 229k | if (!ssl->s3->pending_hs_data || |
130 | 229k | !BUF_MEM_append(ssl->s3->pending_hs_data.get(), chunk.data(), |
131 | 229k | chunk.size())) { |
132 | 0 | return false; |
133 | 0 | } |
134 | 229k | } |
135 | 229k | } |
136 | | |
137 | 270k | ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg); |
138 | | // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript on |
139 | | // hs. |
140 | 270k | if (ssl->s3->hs != nullptr && // |
141 | 270k | !ssl->s3->hs->transcript.Update(msg)) { |
142 | 0 | return false; |
143 | 0 | } |
144 | 270k | return true; |
145 | 270k | } |
146 | | |
147 | 250k | bool tls_flush_pending_hs_data(SSL *ssl) { |
148 | 250k | if (!ssl->s3->pending_hs_data || ssl->s3->pending_hs_data->length == 0) { |
149 | 88.5k | return true; |
150 | 88.5k | } |
151 | | |
152 | 162k | UniquePtr<BUF_MEM> pending_hs_data = std::move(ssl->s3->pending_hs_data); |
153 | 162k | auto data = Span(reinterpret_cast<const uint8_t *>(pending_hs_data->data), |
154 | 162k | pending_hs_data->length); |
155 | 162k | if (SSL_is_quic(ssl)) { |
156 | 0 | if ((ssl->s3->hs == nullptr || !ssl->s3->hs->hints_requested) && |
157 | 0 | !ssl->quic_method->add_handshake_data(ssl, ssl->s3->quic_write_level, |
158 | 0 | data.data(), data.size())) { |
159 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR); |
160 | 0 | return false; |
161 | 0 | } |
162 | 0 | return true; |
163 | 0 | } |
164 | | |
165 | 162k | return add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, data); |
166 | 162k | } |
167 | | |
168 | 57.1k | bool tls_add_change_cipher_spec(SSL *ssl) { |
169 | 57.1k | if (SSL_is_quic(ssl)) { |
170 | 0 | return true; |
171 | 0 | } |
172 | | |
173 | 57.1k | static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS}; |
174 | 57.1k | if (!tls_flush_pending_hs_data(ssl) || |
175 | 57.1k | !add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, |
176 | 57.1k | kChangeCipherSpec)) { |
177 | 0 | return false; |
178 | 0 | } |
179 | | |
180 | 57.1k | ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC, |
181 | 57.1k | kChangeCipherSpec); |
182 | 57.1k | return true; |
183 | 57.1k | } |
184 | | |
185 | 124k | int tls_flush(SSL *ssl) { |
186 | 124k | if (!tls_flush_pending_hs_data(ssl)) { |
187 | 0 | return -1; |
188 | 0 | } |
189 | | |
190 | 124k | if (SSL_is_quic(ssl)) { |
191 | 0 | if (ssl->s3->write_shutdown != ssl_shutdown_none) { |
192 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); |
193 | 0 | return -1; |
194 | 0 | } |
195 | | |
196 | 0 | if (!ssl->quic_method->flush_flight(ssl)) { |
197 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR); |
198 | 0 | return -1; |
199 | 0 | } |
200 | 0 | } |
201 | | |
202 | 124k | if (ssl->s3->pending_flight == nullptr) { |
203 | 0 | return 1; |
204 | 0 | } |
205 | | |
206 | 124k | if (ssl->s3->write_shutdown != ssl_shutdown_none) { |
207 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); |
208 | 0 | return -1; |
209 | 0 | } |
210 | | |
211 | 124k | static_assert(INT_MAX <= 0xffffffff, "int is larger than 32 bits"); |
212 | 124k | if (ssl->s3->pending_flight->length > INT_MAX) { |
213 | 0 | OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); |
214 | 0 | return -1; |
215 | 0 | } |
216 | | |
217 | | // If there is pending data in the write buffer, it must be flushed out before |
218 | | // any new data in pending_flight. |
219 | 124k | if (!ssl->s3->write_buffer.empty()) { |
220 | 0 | int ret = ssl_write_buffer_flush(ssl); |
221 | 0 | if (ret <= 0) { |
222 | 0 | ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; |
223 | 0 | return ret; |
224 | 0 | } |
225 | 0 | } |
226 | | |
227 | 124k | if (ssl->wbio == nullptr) { |
228 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); |
229 | 0 | return -1; |
230 | 0 | } |
231 | | |
232 | | // Write the pending flight. |
233 | 248k | while (ssl->s3->pending_flight_offset < ssl->s3->pending_flight->length) { |
234 | 124k | int ret = BIO_write( |
235 | 124k | ssl->wbio.get(), |
236 | 124k | ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, |
237 | 124k | ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset); |
238 | 124k | if (ret <= 0) { |
239 | 0 | ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; |
240 | 0 | return ret; |
241 | 0 | } |
242 | | |
243 | 124k | ssl->s3->pending_flight_offset += ret; |
244 | 124k | } |
245 | | |
246 | 124k | if (BIO_flush(ssl->wbio.get()) <= 0) { |
247 | 0 | ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; |
248 | 0 | return -1; |
249 | 0 | } |
250 | | |
251 | 124k | ssl->s3->pending_flight.reset(); |
252 | 124k | ssl->s3->pending_flight_offset = 0; |
253 | 124k | return 1; |
254 | 124k | } |
255 | | |
256 | | static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed, |
257 | 1.16k | Span<const uint8_t> in) { |
258 | 1.16k | *out_consumed = 0; |
259 | 1.16k | assert(in.size() >= SSL3_RT_HEADER_LENGTH); |
260 | | // Determine the length of the V2ClientHello. |
261 | 1.16k | size_t msg_length = ((in[0] & 0x7f) << 8) | in[1]; |
262 | 1.16k | if (msg_length > (1024 * 4)) { |
263 | 6 | OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); |
264 | 6 | return ssl_open_record_error; |
265 | 6 | } |
266 | 1.15k | if (msg_length < SSL3_RT_HEADER_LENGTH - 2) { |
267 | | // Reject lengths that are too short early. We have already read |
268 | | // |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an |
269 | | // (invalid) V2ClientHello which would be shorter than that. |
270 | 3 | OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH); |
271 | 3 | return ssl_open_record_error; |
272 | 3 | } |
273 | | |
274 | | // Ask for the remainder of the V2ClientHello. |
275 | 1.15k | if (in.size() < 2 + msg_length) { |
276 | 601 | *out_consumed = 2 + msg_length; |
277 | 601 | return ssl_open_record_partial; |
278 | 601 | } |
279 | | |
280 | 551 | CBS v2_client_hello = CBS(in.subspan(2, msg_length)); |
281 | | // The V2ClientHello without the length is incorporated into the handshake |
282 | | // hash. This is only ever called at the start of the handshake, so hs is |
283 | | // guaranteed to be non-NULL. |
284 | 551 | if (!ssl->s3->hs->transcript.Update(v2_client_hello)) { |
285 | 0 | return ssl_open_record_error; |
286 | 0 | } |
287 | | |
288 | 551 | ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */, |
289 | 551 | v2_client_hello); |
290 | | |
291 | 551 | uint8_t msg_type; |
292 | 551 | uint16_t version, cipher_spec_length, session_id_length, challenge_length; |
293 | 551 | CBS cipher_specs, session_id, challenge; |
294 | 551 | if (!CBS_get_u8(&v2_client_hello, &msg_type) || |
295 | 551 | !CBS_get_u16(&v2_client_hello, &version) || |
296 | 551 | !CBS_get_u16(&v2_client_hello, &cipher_spec_length) || |
297 | 547 | !CBS_get_u16(&v2_client_hello, &session_id_length) || |
298 | 543 | !CBS_get_u16(&v2_client_hello, &challenge_length) || |
299 | 539 | !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) || |
300 | 527 | !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) || |
301 | 519 | !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) || |
302 | 511 | CBS_len(&v2_client_hello) != 0) { |
303 | 61 | OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); |
304 | 61 | return ssl_open_record_error; |
305 | 61 | } |
306 | | |
307 | | // msg_type has already been checked. |
308 | 551 | assert(msg_type == SSL2_MT_CLIENT_HELLO); |
309 | | |
310 | | // The client_random is the V2ClientHello challenge. Truncate or left-pad with |
311 | | // zeros as needed. |
312 | 490 | size_t rand_len = CBS_len(&challenge); |
313 | 490 | if (rand_len > SSL3_RANDOM_SIZE) { |
314 | 3 | rand_len = SSL3_RANDOM_SIZE; |
315 | 3 | } |
316 | 490 | uint8_t random[SSL3_RANDOM_SIZE]; |
317 | 490 | OPENSSL_memset(random, 0, SSL3_RANDOM_SIZE); |
318 | 490 | OPENSSL_memcpy(random + (SSL3_RANDOM_SIZE - rand_len), CBS_data(&challenge), |
319 | 490 | rand_len); |
320 | | |
321 | | // Write out an equivalent TLS ClientHello directly to the handshake buffer. |
322 | 490 | size_t max_v3_client_hello = SSL3_HM_HEADER_LENGTH + 2 /* version */ + |
323 | 490 | SSL3_RANDOM_SIZE + 1 /* session ID length */ + |
324 | 490 | 2 /* cipher list length */ + |
325 | 490 | CBS_len(&cipher_specs) / 3 * 2 + |
326 | 490 | 1 /* compression length */ + 1 /* compression */; |
327 | 490 | ScopedCBB client_hello; |
328 | 490 | CBB hello_body, cipher_suites; |
329 | 490 | if (!ssl->s3->hs_buf) { |
330 | 490 | ssl->s3->hs_buf.reset(BUF_MEM_new()); |
331 | 490 | } |
332 | 490 | if (!ssl->s3->hs_buf || |
333 | 490 | !BUF_MEM_reserve(ssl->s3->hs_buf.get(), max_v3_client_hello) || |
334 | 490 | !CBB_init_fixed(client_hello.get(), (uint8_t *)ssl->s3->hs_buf->data, |
335 | 490 | ssl->s3->hs_buf->max) || |
336 | 490 | !CBB_add_u8(client_hello.get(), SSL3_MT_CLIENT_HELLO) || |
337 | 490 | !CBB_add_u24_length_prefixed(client_hello.get(), &hello_body) || |
338 | 490 | !CBB_add_u16(&hello_body, version) || |
339 | 490 | !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) || |
340 | | // No session id. |
341 | 490 | !CBB_add_u8(&hello_body, 0) || |
342 | 490 | !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) { |
343 | 0 | return ssl_open_record_error; |
344 | 0 | } |
345 | | |
346 | | // Copy the cipher suites. |
347 | 8.04k | while (CBS_len(&cipher_specs) > 0) { |
348 | 7.58k | uint32_t cipher_spec; |
349 | 7.58k | if (!CBS_get_u24(&cipher_specs, &cipher_spec)) { |
350 | 24 | OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); |
351 | 24 | return ssl_open_record_error; |
352 | 24 | } |
353 | | |
354 | | // Skip SSLv2 ciphers. |
355 | 7.55k | if ((cipher_spec & 0xff0000) != 0) { |
356 | 2.70k | continue; |
357 | 2.70k | } |
358 | 4.85k | if (!CBB_add_u16(&cipher_suites, cipher_spec)) { |
359 | 0 | OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); |
360 | 0 | return ssl_open_record_error; |
361 | 0 | } |
362 | 4.85k | } |
363 | | |
364 | | // Add the null compression scheme and finish. |
365 | 466 | if (!CBB_add_u8(&hello_body, 1) || // |
366 | 466 | !CBB_add_u8(&hello_body, 0) || // |
367 | 466 | !CBB_finish(client_hello.get(), nullptr, &ssl->s3->hs_buf->length)) { |
368 | 0 | OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); |
369 | 0 | return ssl_open_record_error; |
370 | 0 | } |
371 | | |
372 | 466 | *out_consumed = 2 + msg_length; |
373 | 466 | ssl->s3->is_v2_hello = true; |
374 | 466 | return ssl_open_record_success; |
375 | 466 | } |
376 | | |
377 | | static bool parse_message(const SSL *ssl, SSLMessage *out, |
378 | 3.72M | size_t *out_bytes_needed) { |
379 | 3.72M | if (!ssl->s3->hs_buf) { |
380 | 481k | *out_bytes_needed = 4; |
381 | 481k | return false; |
382 | 481k | } |
383 | | |
384 | 3.24M | CBS cbs; |
385 | 3.24M | uint32_t len; |
386 | 3.24M | CBS_init(&cbs, reinterpret_cast<const uint8_t *>(ssl->s3->hs_buf->data), |
387 | 3.24M | ssl->s3->hs_buf->length); |
388 | 3.24M | if (!CBS_get_u8(&cbs, &out->type) || // |
389 | 1.74M | !CBS_get_u24(&cbs, &len)) { |
390 | 1.74M | *out_bytes_needed = 4; |
391 | 1.74M | return false; |
392 | 1.74M | } |
393 | | |
394 | 1.50M | if (!CBS_get_bytes(&cbs, &out->body, len)) { |
395 | 416k | *out_bytes_needed = 4 + len; |
396 | 416k | return false; |
397 | 416k | } |
398 | | |
399 | 1.08M | CBS_init(&out->raw, reinterpret_cast<const uint8_t *>(ssl->s3->hs_buf->data), |
400 | 1.08M | 4 + len); |
401 | 1.08M | out->is_v2_hello = ssl->s3->is_v2_hello; |
402 | 1.08M | return true; |
403 | 1.50M | } |
404 | | |
405 | 1.68M | bool tls_get_message(const SSL *ssl, SSLMessage *out) { |
406 | 1.68M | size_t unused; |
407 | 1.68M | if (!parse_message(ssl, out, &unused)) { |
408 | 727k | return false; |
409 | 727k | } |
410 | 959k | if (!ssl->s3->has_message) { |
411 | 452k | if (!out->is_v2_hello) { |
412 | 451k | ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw); |
413 | 451k | } |
414 | 452k | ssl->s3->has_message = true; |
415 | 452k | } |
416 | 959k | return true; |
417 | 1.68M | } |
418 | | |
419 | 1.91M | bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert) { |
420 | | // If there is a complete message, the caller must have consumed it first. |
421 | 1.91M | SSLMessage msg; |
422 | 1.91M | size_t bytes_needed; |
423 | 1.91M | if (parse_message(ssl, &msg, &bytes_needed)) { |
424 | 6 | OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); |
425 | 6 | *out_alert = SSL_AD_INTERNAL_ERROR; |
426 | 6 | return false; |
427 | 6 | } |
428 | | |
429 | | // Enforce the limit so the peer cannot force us to buffer 16MB. |
430 | 1.91M | if (bytes_needed > 4 + ssl_max_handshake_message_len(ssl)) { |
431 | 337 | OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); |
432 | 337 | *out_alert = SSL_AD_ILLEGAL_PARAMETER; |
433 | 337 | return false; |
434 | 337 | } |
435 | | |
436 | 1.91M | return true; |
437 | 1.91M | } |
438 | | |
439 | 243k | bool tls_has_unprocessed_handshake_data(const SSL *ssl) { |
440 | 243k | size_t msg_len = 0; |
441 | 243k | if (ssl->s3->has_message) { |
442 | 126k | SSLMessage msg; |
443 | 126k | size_t unused; |
444 | 126k | if (parse_message(ssl, &msg, &unused)) { |
445 | 126k | msg_len = CBS_len(&msg.raw); |
446 | 126k | } |
447 | 126k | } |
448 | | |
449 | 243k | return ssl->s3->hs_buf && ssl->s3->hs_buf->length > msg_len; |
450 | 243k | } |
451 | | |
452 | 567k | bool tls_append_handshake_data(SSL *ssl, Span<const uint8_t> data) { |
453 | | // Re-create the handshake buffer if needed. |
454 | 567k | if (!ssl->s3->hs_buf) { |
455 | 81.1k | ssl->s3->hs_buf.reset(BUF_MEM_new()); |
456 | 81.1k | } |
457 | 567k | return ssl->s3->hs_buf && |
458 | 567k | BUF_MEM_append(ssl->s3->hs_buf.get(), data.data(), data.size()); |
459 | 567k | } |
460 | | |
461 | | ssl_open_record_t tls_open_handshake(SSL *ssl, size_t *out_consumed, |
462 | 1.54M | uint8_t *out_alert, Span<uint8_t> in) { |
463 | 1.54M | *out_consumed = 0; |
464 | | // Bypass the record layer for the first message to handle V2ClientHello. |
465 | 1.54M | if (ssl->server && !ssl->s3->v2_hello_done) { |
466 | | // Ask for the first 5 bytes, the size of the TLS record header. This is |
467 | | // sufficient to detect a V2ClientHello and ensures that we never read |
468 | | // beyond the first record. |
469 | 20.4k | if (in.size() < SSL3_RT_HEADER_LENGTH) { |
470 | 9.99k | *out_consumed = SSL3_RT_HEADER_LENGTH; |
471 | 9.99k | return ssl_open_record_partial; |
472 | 9.99k | } |
473 | | |
474 | | // Some dedicated error codes for protocol mixups should the application |
475 | | // wish to interpret them differently. (These do not overlap with |
476 | | // ClientHello or V2ClientHello.) |
477 | 10.4k | auto str = bssl::BytesAsStringView(in); |
478 | 10.4k | if (str.substr(0, 4) == "GET " || // |
479 | 10.4k | str.substr(0, 5) == "POST " || // |
480 | 10.4k | str.substr(0, 5) == "HEAD " || // |
481 | 10.4k | str.substr(0, 4) == "PUT ") { |
482 | 8 | OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST); |
483 | 8 | *out_alert = 0; |
484 | 8 | return ssl_open_record_error; |
485 | 8 | } |
486 | 10.4k | if (str.substr(0, 5) == "CONNE") { |
487 | 2 | OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST); |
488 | 2 | *out_alert = 0; |
489 | 2 | return ssl_open_record_error; |
490 | 2 | } |
491 | | |
492 | | // Check for a V2ClientHello. |
493 | 10.4k | if ((in[0] & 0x80) != 0 && in[2] == SSL2_MT_CLIENT_HELLO && |
494 | 1.18k | in[3] == SSL3_VERSION_MAJOR) { |
495 | 1.16k | auto ret = read_v2_client_hello(ssl, out_consumed, in); |
496 | 1.16k | if (ret == ssl_open_record_error) { |
497 | 94 | *out_alert = 0; |
498 | 1.06k | } else if (ret == ssl_open_record_success) { |
499 | 466 | ssl->s3->v2_hello_done = true; |
500 | 466 | } |
501 | 1.16k | return ret; |
502 | 1.16k | } |
503 | | |
504 | 9.30k | ssl->s3->v2_hello_done = true; |
505 | 9.30k | } |
506 | | |
507 | 1.53M | uint8_t type; |
508 | 1.53M | Span<uint8_t> body; |
509 | 1.53M | auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); |
510 | 1.53M | if (ret != ssl_open_record_success) { |
511 | 1.03M | return ret; |
512 | 1.03M | } |
513 | | |
514 | 502k | if (type != SSL3_RT_HANDSHAKE) { |
515 | 136 | OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); |
516 | 136 | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; |
517 | 136 | return ssl_open_record_error; |
518 | 136 | } |
519 | | |
520 | | // Append the entire handshake record to the buffer. |
521 | 502k | if (!tls_append_handshake_data(ssl, body)) { |
522 | 0 | *out_alert = SSL_AD_INTERNAL_ERROR; |
523 | 0 | return ssl_open_record_error; |
524 | 0 | } |
525 | | |
526 | 502k | return ssl_open_record_success; |
527 | 502k | } |
528 | | |
529 | 443k | void tls_next_message(SSL *ssl) { |
530 | 443k | SSLMessage msg; |
531 | 443k | if (!tls_get_message(ssl, &msg) || // |
532 | 443k | !ssl->s3->hs_buf || // |
533 | 443k | ssl->s3->hs_buf->length < CBS_len(&msg.raw)) { |
534 | 0 | assert(0); |
535 | 0 | return; |
536 | 0 | } |
537 | | |
538 | 443k | OPENSSL_memmove(ssl->s3->hs_buf->data, |
539 | 443k | ssl->s3->hs_buf->data + CBS_len(&msg.raw), |
540 | 443k | ssl->s3->hs_buf->length - CBS_len(&msg.raw)); |
541 | 443k | ssl->s3->hs_buf->length -= CBS_len(&msg.raw); |
542 | 443k | ssl->s3->is_v2_hello = false; |
543 | 443k | ssl->s3->has_message = false; |
544 | | |
545 | | // Post-handshake messages are rare, so release the buffer after every |
546 | | // message. During the handshake, |on_handshake_complete| will release it. |
547 | 443k | if (!SSL_in_init(ssl) && ssl->s3->hs_buf->length == 0) { |
548 | 10.6k | ssl->s3->hs_buf.reset(); |
549 | 10.6k | } |
550 | 443k | } |
551 | | |
552 | | namespace { |
553 | | |
554 | | class CipherScorer { |
555 | | public: |
556 | | using Score = int; |
557 | | static constexpr Score kMinScore = 0; |
558 | | |
559 | 9.39k | virtual ~CipherScorer() = default; |
560 | | |
561 | | virtual Score Evaluate(const SSL_CIPHER *cipher) const = 0; |
562 | | }; |
563 | | |
564 | | // AesHwCipherScorer scores cipher suites based on whether AES is supported in |
565 | | // hardware. |
566 | | class AesHwCipherScorer : public CipherScorer { |
567 | | public: |
568 | 4.69k | explicit AesHwCipherScorer(bool has_aes_hw) : aes_is_fine_(has_aes_hw) {} |
569 | | |
570 | | virtual ~AesHwCipherScorer() override = default; |
571 | | |
572 | 9.96k | Score Evaluate(const SSL_CIPHER *a) const override { |
573 | 9.96k | return |
574 | | // Something is always preferable to nothing. |
575 | 9.96k | 1 + |
576 | | // Either AES is fine, or else ChaCha20 is preferred. |
577 | 9.96k | ((aes_is_fine_ || a->algorithm_enc == SSL_CHACHA20POLY1305) ? 1 : 0); |
578 | 9.96k | } |
579 | | |
580 | | private: |
581 | | const bool aes_is_fine_; |
582 | | }; |
583 | | |
584 | | // CNsaCipherScorer prefers AES-256-GCM over AES-128-GCM over anything else. |
585 | | class CNsaCipherScorer : public CipherScorer { |
586 | | public: |
587 | | virtual ~CNsaCipherScorer() override = default; |
588 | | |
589 | 0 | Score Evaluate(const SSL_CIPHER *a) const override { |
590 | 0 | if (a->protocol_id == SSL_CIPHER_AES_256_GCM_SHA384) { |
591 | 0 | return 3; |
592 | 0 | } else if (a->protocol_id == SSL_CIPHER_AES_128_GCM_SHA256) { |
593 | 0 | return 2; |
594 | 0 | } |
595 | 0 | return 1; |
596 | 0 | } |
597 | | }; |
598 | | |
599 | | } // namespace |
600 | | |
601 | | bool ssl_tls13_cipher_meets_policy(uint16_t cipher_id, |
602 | 220k | enum ssl_compliance_policy_t policy) { |
603 | 220k | switch (policy) { |
604 | 220k | case ssl_compliance_policy_none: |
605 | 220k | case ssl_compliance_policy_cnsa_202407: |
606 | 220k | return true; |
607 | | |
608 | 0 | case ssl_compliance_policy_fips_202205: |
609 | 0 | switch (cipher_id) { |
610 | 0 | case SSL_CIPHER_AES_128_GCM_SHA256: |
611 | 0 | case SSL_CIPHER_AES_256_GCM_SHA384: |
612 | 0 | return true; |
613 | 0 | case SSL_CIPHER_CHACHA20_POLY1305_SHA256: |
614 | 0 | return false; |
615 | 0 | default: |
616 | 0 | assert(false); |
617 | 0 | return false; |
618 | 0 | } |
619 | | |
620 | 0 | case ssl_compliance_policy_wpa3_192_202304: |
621 | 0 | switch (cipher_id) { |
622 | 0 | case SSL_CIPHER_AES_256_GCM_SHA384: |
623 | 0 | return true; |
624 | 0 | case SSL_CIPHER_AES_128_GCM_SHA256: |
625 | 0 | case SSL_CIPHER_CHACHA20_POLY1305_SHA256: |
626 | 0 | return false; |
627 | 0 | default: |
628 | 0 | assert(false); |
629 | 0 | return false; |
630 | 0 | } |
631 | 220k | } |
632 | | |
633 | 220k | assert(false); |
634 | 0 | return false; |
635 | 0 | } |
636 | | |
637 | | const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, bool has_aes_hw, |
638 | | uint16_t version, |
639 | 4.69k | enum ssl_compliance_policy_t policy) { |
640 | 4.69k | if (CBS_len(&cipher_suites) % 2 != 0) { |
641 | 0 | return nullptr; |
642 | 0 | } |
643 | | |
644 | 4.69k | const SSL_CIPHER *best = nullptr; |
645 | 4.69k | AesHwCipherScorer aes_hw_scorer(has_aes_hw); |
646 | 4.69k | CNsaCipherScorer cnsa_scorer; |
647 | 4.69k | CipherScorer *const scorer = |
648 | 4.69k | (policy == ssl_compliance_policy_cnsa_202407) |
649 | 4.69k | ? static_cast<CipherScorer *>(&cnsa_scorer) |
650 | 4.69k | : static_cast<CipherScorer *>(&aes_hw_scorer); |
651 | 4.69k | CipherScorer::Score best_score = CipherScorer::kMinScore; |
652 | | |
653 | 102k | while (CBS_len(&cipher_suites) > 0) { |
654 | 97.8k | uint16_t cipher_suite; |
655 | 97.8k | if (!CBS_get_u16(&cipher_suites, &cipher_suite)) { |
656 | 0 | return nullptr; |
657 | 0 | } |
658 | | |
659 | | // Limit to TLS 1.3 ciphers we know about. |
660 | 97.8k | const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite); |
661 | 97.8k | if (candidate == nullptr || |
662 | 55.0k | SSL_CIPHER_get_min_version(candidate) > version || |
663 | 87.9k | SSL_CIPHER_get_max_version(candidate) < version) { |
664 | 87.9k | continue; |
665 | 87.9k | } |
666 | | |
667 | 9.96k | if (!ssl_tls13_cipher_meets_policy(SSL_CIPHER_get_protocol_id(candidate), |
668 | 9.96k | policy)) { |
669 | 0 | continue; |
670 | 0 | } |
671 | | |
672 | 9.96k | const CipherScorer::Score candidate_score = scorer->Evaluate(candidate); |
673 | | // |candidate_score| must be larger to displace the current choice. That way |
674 | | // the client's order controls between ciphers with an equal score. |
675 | 9.96k | if (candidate_score > best_score) { |
676 | 4.66k | best = candidate; |
677 | 4.66k | best_score = candidate_score; |
678 | 4.66k | } |
679 | 9.96k | } |
680 | | |
681 | 4.69k | return best; |
682 | 4.69k | } |
683 | | |
684 | | BSSL_NAMESPACE_END |