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