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