s3_both.cc
Go to the documentation of this file.
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to. The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  * notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  * must display the following acknowledgement:
32  * "This product includes cryptographic software written by
33  * Eric Young (eay@cryptsoft.com)"
34  * The word 'cryptographic' can be left out if the rouines from the library
35  * being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  * the apps directory (application code) you must include an acknowledgement:
38  * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed. i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57 /* ====================================================================
58  * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
59  *
60  * Redistribution and use in source and binary forms, with or without
61  * modification, are permitted provided that the following conditions
62  * are met:
63  *
64  * 1. Redistributions of source code must retain the above copyright
65  * notice, this list of conditions and the following disclaimer.
66  *
67  * 2. Redistributions in binary form must reproduce the above copyright
68  * notice, this list of conditions and the following disclaimer in
69  * the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3. All advertising materials mentioning features or use of this
73  * software must display the following acknowledgment:
74  * "This product includes software developed by the OpenSSL Project
75  * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76  *
77  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78  * endorse or promote products derived from this software without
79  * prior written permission. For written permission, please contact
80  * openssl-core@openssl.org.
81  *
82  * 5. Products derived from this software may not be called "OpenSSL"
83  * nor may "OpenSSL" appear in their names without prior written
84  * permission of the OpenSSL Project.
85  *
86  * 6. Redistributions of any form whatsoever must retain the following
87  * acknowledgment:
88  * "This product includes software developed by the OpenSSL Project
89  * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90  *
91  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102  * OF THE POSSIBILITY OF SUCH DAMAGE.
103  * ====================================================================
104  *
105  * This product includes cryptographic software written by Eric Young
106  * (eay@cryptsoft.com). This product includes software written by Tim
107  * Hudson (tjh@cryptsoft.com). */
108 /* ====================================================================
109  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
110  * ECC cipher suite support in OpenSSL originally developed by
111  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
112 
113 #include <openssl/ssl.h>
114 
115 #include <assert.h>
116 #include <limits.h>
117 #include <string.h>
118 
119 #include <tuple>
120 
121 #include <openssl/buf.h>
122 #include <openssl/bytestring.h>
123 #include <openssl/err.h>
124 #include <openssl/evp.h>
125 #include <openssl/mem.h>
126 #include <openssl/md5.h>
127 #include <openssl/nid.h>
128 #include <openssl/rand.h>
129 #include <openssl/sha.h>
130 
131 #include "../crypto/internal.h"
132 #include "internal.h"
133 
134 
136 
139  // The caller should have flushed |pending_hs_data| first.
140  assert(!ssl->s3->pending_hs_data);
141  // We'll never add a flight while in the process of writing it out.
142  assert(ssl->s3->pending_flight_offset == 0);
143 
144  if (ssl->s3->pending_flight == nullptr) {
145  ssl->s3->pending_flight.reset(BUF_MEM_new());
146  if (ssl->s3->pending_flight == nullptr) {
147  return false;
148  }
149  }
150 
151  size_t max_out = in.size() + SSL_max_seal_overhead(ssl);
152  size_t new_cap = ssl->s3->pending_flight->length + max_out;
153  if (max_out < in.size() || new_cap < max_out) {
155  return false;
156  }
157 
158  size_t len;
159  if (!BUF_MEM_reserve(ssl->s3->pending_flight.get(), new_cap) ||
160  !tls_seal_record(ssl,
161  (uint8_t *)ssl->s3->pending_flight->data +
162  ssl->s3->pending_flight->length,
163  &len, max_out, type, in.data(), in.size())) {
164  return false;
165  }
166 
167  ssl->s3->pending_flight->length += len;
168  return true;
169 }
170 
171 bool tls_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
172  // Pick a modest size hint to save most of the |realloc| calls.
173  if (!CBB_init(cbb, 64) ||
174  !CBB_add_u8(cbb, type) ||
175  !CBB_add_u24_length_prefixed(cbb, body)) {
177  CBB_cleanup(cbb);
178  return false;
179  }
180 
181  return true;
182 }
183 
184 bool tls_finish_message(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg) {
185  return CBBFinishArray(cbb, out_msg);
186 }
187 
189  // Pack handshake data into the minimal number of records. This avoids
190  // unnecessary encryption overhead, notably in TLS 1.3 where we send several
191  // encrypted messages in a row. For now, we do not do this for the null
192  // cipher. The benefit is smaller and there is a risk of breaking buggy
193  // implementations.
194  //
195  // TODO(davidben): See if we can do this uniformly.
196  Span<const uint8_t> rest = msg;
197  if (ssl->quic_method == nullptr &&
198  ssl->s3->aead_write_ctx->is_null_cipher()) {
199  while (!rest.empty()) {
200  Span<const uint8_t> chunk = rest.subspan(0, ssl->max_send_fragment);
201  rest = rest.subspan(chunk.size());
202 
203  if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, chunk)) {
204  return false;
205  }
206  }
207  } else {
208  while (!rest.empty()) {
209  // Flush if |pending_hs_data| is full.
210  if (ssl->s3->pending_hs_data &&
211  ssl->s3->pending_hs_data->length >= ssl->max_send_fragment &&
213  return false;
214  }
215 
216  size_t pending_len =
217  ssl->s3->pending_hs_data ? ssl->s3->pending_hs_data->length : 0;
218  Span<const uint8_t> chunk =
219  rest.subspan(0, ssl->max_send_fragment - pending_len);
220  assert(!chunk.empty());
221  rest = rest.subspan(chunk.size());
222 
223  if (!ssl->s3->pending_hs_data) {
224  ssl->s3->pending_hs_data.reset(BUF_MEM_new());
225  }
226  if (!ssl->s3->pending_hs_data ||
227  !BUF_MEM_append(ssl->s3->pending_hs_data.get(), chunk.data(),
228  chunk.size())) {
229  return false;
230  }
231  }
232  }
233 
234  ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg);
235  // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript on
236  // hs.
237  if (ssl->s3->hs != NULL &&
238  !ssl->s3->hs->transcript.Update(msg)) {
239  return false;
240  }
241  return true;
242 }
243 
245  if (!ssl->s3->pending_hs_data || ssl->s3->pending_hs_data->length == 0) {
246  return true;
247  }
248 
249  UniquePtr<BUF_MEM> pending_hs_data = std::move(ssl->s3->pending_hs_data);
250  auto data =
251  MakeConstSpan(reinterpret_cast<const uint8_t *>(pending_hs_data->data),
252  pending_hs_data->length);
253  if (ssl->quic_method) {
254  if ((ssl->s3->hs == nullptr || !ssl->s3->hs->hints_requested) &&
255  !ssl->quic_method->add_handshake_data(ssl, ssl->s3->write_level,
256  data.data(), data.size())) {
258  return false;
259  }
260  return true;
261  }
262 
264 }
265 
267  static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
268 
269  if (!tls_flush_pending_hs_data(ssl)) {
270  return false;
271  }
272 
273  if (!ssl->quic_method &&
275  kChangeCipherSpec)) {
276  return false;
277  }
278 
280  kChangeCipherSpec);
281  return true;
282 }
283 
285  if (!tls_flush_pending_hs_data(ssl)) {
286  return -1;
287  }
288 
289  if (ssl->quic_method) {
290  if (ssl->s3->write_shutdown != ssl_shutdown_none) {
292  return -1;
293  }
294 
295  if (!ssl->quic_method->flush_flight(ssl)) {
297  return -1;
298  }
299  }
300 
301  if (ssl->s3->pending_flight == nullptr) {
302  return 1;
303  }
304 
305  if (ssl->s3->write_shutdown != ssl_shutdown_none) {
307  return -1;
308  }
309 
310  static_assert(INT_MAX <= 0xffffffff, "int is larger than 32 bits");
311  if (ssl->s3->pending_flight->length > INT_MAX) {
313  return -1;
314  }
315 
316  // If there is pending data in the write buffer, it must be flushed out before
317  // any new data in pending_flight.
318  if (!ssl->s3->write_buffer.empty()) {
319  int ret = ssl_write_buffer_flush(ssl);
320  if (ret <= 0) {
321  ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
322  return ret;
323  }
324  }
325 
326  if (ssl->wbio == nullptr) {
328  return -1;
329  }
330 
331  // Write the pending flight.
332  while (ssl->s3->pending_flight_offset < ssl->s3->pending_flight->length) {
333  int ret = BIO_write(
334  ssl->wbio.get(),
335  ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset,
336  ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset);
337  if (ret <= 0) {
338  ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
339  return ret;
340  }
341 
342  ssl->s3->pending_flight_offset += ret;
343  }
344 
345  if (BIO_flush(ssl->wbio.get()) <= 0) {
346  ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
347  return -1;
348  }
349 
350  ssl->s3->pending_flight.reset();
351  ssl->s3->pending_flight_offset = 0;
352  return 1;
353 }
354 
355 static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed,
357  *out_consumed = 0;
358  assert(in.size() >= SSL3_RT_HEADER_LENGTH);
359  // Determine the length of the V2ClientHello.
360  size_t msg_length = ((in[0] & 0x7f) << 8) | in[1];
361  if (msg_length > (1024 * 4)) {
363  return ssl_open_record_error;
364  }
365  if (msg_length < SSL3_RT_HEADER_LENGTH - 2) {
366  // Reject lengths that are too short early. We have already read
367  // |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an
368  // (invalid) V2ClientHello which would be shorter than that.
370  return ssl_open_record_error;
371  }
372 
373  // Ask for the remainder of the V2ClientHello.
374  if (in.size() < 2 + msg_length) {
375  *out_consumed = 2 + msg_length;
377  }
378 
379  CBS v2_client_hello = CBS(ssl->s3->read_buffer.span().subspan(2, msg_length));
380  // The V2ClientHello without the length is incorporated into the handshake
381  // hash. This is only ever called at the start of the handshake, so hs is
382  // guaranteed to be non-NULL.
383  if (!ssl->s3->hs->transcript.Update(v2_client_hello)) {
384  return ssl_open_record_error;
385  }
386 
387  ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */,
388  v2_client_hello);
389 
390  uint8_t msg_type;
391  uint16_t version, cipher_spec_length, session_id_length, challenge_length;
392  CBS cipher_specs, session_id, challenge;
393  if (!CBS_get_u8(&v2_client_hello, &msg_type) ||
394  !CBS_get_u16(&v2_client_hello, &version) ||
395  !CBS_get_u16(&v2_client_hello, &cipher_spec_length) ||
396  !CBS_get_u16(&v2_client_hello, &session_id_length) ||
397  !CBS_get_u16(&v2_client_hello, &challenge_length) ||
398  !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) ||
399  !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) ||
400  !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) ||
401  CBS_len(&v2_client_hello) != 0) {
403  return ssl_open_record_error;
404  }
405 
406  // msg_type has already been checked.
407  assert(msg_type == SSL2_MT_CLIENT_HELLO);
408 
409  // The client_random is the V2ClientHello challenge. Truncate or left-pad with
410  // zeros as needed.
411  size_t rand_len = CBS_len(&challenge);
412  if (rand_len > SSL3_RANDOM_SIZE) {
413  rand_len = SSL3_RANDOM_SIZE;
414  }
415  uint8_t random[SSL3_RANDOM_SIZE];
416  OPENSSL_memset(random, 0, SSL3_RANDOM_SIZE);
417  OPENSSL_memcpy(random + (SSL3_RANDOM_SIZE - rand_len), CBS_data(&challenge),
418  rand_len);
419 
420  // Write out an equivalent TLS ClientHello directly to the handshake buffer.
421  size_t max_v3_client_hello = SSL3_HM_HEADER_LENGTH + 2 /* version */ +
422  SSL3_RANDOM_SIZE + 1 /* session ID length */ +
423  2 /* cipher list length */ +
424  CBS_len(&cipher_specs) / 3 * 2 +
425  1 /* compression length */ + 1 /* compression */;
426  ScopedCBB client_hello;
427  CBB hello_body, cipher_suites;
428  if (!ssl->s3->hs_buf) {
429  ssl->s3->hs_buf.reset(BUF_MEM_new());
430  }
431  if (!ssl->s3->hs_buf ||
432  !BUF_MEM_reserve(ssl->s3->hs_buf.get(), max_v3_client_hello) ||
433  !CBB_init_fixed(client_hello.get(), (uint8_t *)ssl->s3->hs_buf->data,
434  ssl->s3->hs_buf->max) ||
435  !CBB_add_u8(client_hello.get(), SSL3_MT_CLIENT_HELLO) ||
436  !CBB_add_u24_length_prefixed(client_hello.get(), &hello_body) ||
437  !CBB_add_u16(&hello_body, version) ||
438  !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) ||
439  // No session id.
440  !CBB_add_u8(&hello_body, 0) ||
441  !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) {
443  return ssl_open_record_error;
444  }
445 
446  // Copy the cipher suites.
447  while (CBS_len(&cipher_specs) > 0) {
448  uint32_t cipher_spec;
449  if (!CBS_get_u24(&cipher_specs, &cipher_spec)) {
451  return ssl_open_record_error;
452  }
453 
454  // Skip SSLv2 ciphers.
455  if ((cipher_spec & 0xff0000) != 0) {
456  continue;
457  }
458  if (!CBB_add_u16(&cipher_suites, cipher_spec)) {
460  return ssl_open_record_error;
461  }
462  }
463 
464  // Add the null compression scheme and finish.
465  if (!CBB_add_u8(&hello_body, 1) ||
466  !CBB_add_u8(&hello_body, 0) ||
467  !CBB_finish(client_hello.get(), NULL, &ssl->s3->hs_buf->length)) {
469  return ssl_open_record_error;
470  }
471 
472  *out_consumed = 2 + msg_length;
473  ssl->s3->is_v2_hello = true;
475 }
476 
477 static bool parse_message(const SSL *ssl, SSLMessage *out,
478  size_t *out_bytes_needed) {
479  if (!ssl->s3->hs_buf) {
480  *out_bytes_needed = 4;
481  return false;
482  }
483 
484  CBS cbs;
485  uint32_t len;
486  CBS_init(&cbs, reinterpret_cast<const uint8_t *>(ssl->s3->hs_buf->data),
487  ssl->s3->hs_buf->length);
488  if (!CBS_get_u8(&cbs, &out->type) ||
489  !CBS_get_u24(&cbs, &len)) {
490  *out_bytes_needed = 4;
491  return false;
492  }
493 
494  if (!CBS_get_bytes(&cbs, &out->body, len)) {
495  *out_bytes_needed = 4 + len;
496  return false;
497  }
498 
499  CBS_init(&out->raw, reinterpret_cast<const uint8_t *>(ssl->s3->hs_buf->data),
500  4 + len);
501  out->is_v2_hello = ssl->s3->is_v2_hello;
502  return true;
503 }
504 
505 bool tls_get_message(const SSL *ssl, SSLMessage *out) {
506  size_t unused;
507  if (!parse_message(ssl, out, &unused)) {
508  return false;
509  }
510  if (!ssl->s3->has_message) {
511  if (!out->is_v2_hello) {
512  ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw);
513  }
514  ssl->s3->has_message = true;
515  }
516  return true;
517 }
518 
519 bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert) {
520  // If there is a complete message, the caller must have consumed it first.
521  SSLMessage msg;
522  size_t bytes_needed;
523  if (parse_message(ssl, &msg, &bytes_needed)) {
525  *out_alert = SSL_AD_INTERNAL_ERROR;
526  return false;
527  }
528 
529  // Enforce the limit so the peer cannot force us to buffer 16MB.
530  if (bytes_needed > 4 + ssl_max_handshake_message_len(ssl)) {
532  *out_alert = SSL_AD_ILLEGAL_PARAMETER;
533  return false;
534  }
535 
536  return true;
537 }
538 
540  size_t msg_len = 0;
541  if (ssl->s3->has_message) {
542  SSLMessage msg;
543  size_t unused;
544  if (parse_message(ssl, &msg, &unused)) {
545  msg_len = CBS_len(&msg.raw);
546  }
547  }
548 
549  return ssl->s3->hs_buf && ssl->s3->hs_buf->length > msg_len;
550 }
551 
553  // Re-create the handshake buffer if needed.
554  if (!ssl->s3->hs_buf) {
555  ssl->s3->hs_buf.reset(BUF_MEM_new());
556  }
557  return ssl->s3->hs_buf &&
558  BUF_MEM_append(ssl->s3->hs_buf.get(), data.data(), data.size());
559 }
560 
561 ssl_open_record_t tls_open_handshake(SSL *ssl, size_t *out_consumed,
562  uint8_t *out_alert, Span<uint8_t> in) {
563  *out_consumed = 0;
564  // Bypass the record layer for the first message to handle V2ClientHello.
565  if (ssl->server && !ssl->s3->v2_hello_done) {
566  // Ask for the first 5 bytes, the size of the TLS record header. This is
567  // sufficient to detect a V2ClientHello and ensures that we never read
568  // beyond the first record.
569  if (in.size() < SSL3_RT_HEADER_LENGTH) {
570  *out_consumed = SSL3_RT_HEADER_LENGTH;
572  }
573 
574  // Some dedicated error codes for protocol mixups should the application
575  // wish to interpret them differently. (These do not overlap with
576  // ClientHello or V2ClientHello.)
577  const char *str = reinterpret_cast<const char*>(in.data());
578  if (strncmp("GET ", str, 4) == 0 ||
579  strncmp("POST ", str, 5) == 0 ||
580  strncmp("HEAD ", str, 5) == 0 ||
581  strncmp("PUT ", str, 4) == 0) {
583  *out_alert = 0;
584  return ssl_open_record_error;
585  }
586  if (strncmp("CONNE", str, 5) == 0) {
588  *out_alert = 0;
589  return ssl_open_record_error;
590  }
591 
592  // Check for a V2ClientHello.
593  if ((in[0] & 0x80) != 0 && in[2] == SSL2_MT_CLIENT_HELLO &&
594  in[3] == SSL3_VERSION_MAJOR) {
595  auto ret = read_v2_client_hello(ssl, out_consumed, in);
596  if (ret == ssl_open_record_error) {
597  *out_alert = 0;
598  } else if (ret == ssl_open_record_success) {
599  ssl->s3->v2_hello_done = true;
600  }
601  return ret;
602  }
603 
604  ssl->s3->v2_hello_done = true;
605  }
606 
607  uint8_t type;
608  Span<uint8_t> body;
609  auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in);
610  if (ret != ssl_open_record_success) {
611  return ret;
612  }
613 
614  // WatchGuard's TLS 1.3 interference bug is very distinctive: they drop the
615  // ServerHello and send the remaining encrypted application data records
616  // as-is. This manifests as an application data record when we expect
617  // handshake. Report a dedicated error code for this case.
618  if (!ssl->server && type == SSL3_RT_APPLICATION_DATA &&
619  ssl->s3->aead_read_ctx->is_null_cipher()) {
621  *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
622  return ssl_open_record_error;
623  }
624 
625  if (type != SSL3_RT_HANDSHAKE) {
627  *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
628  return ssl_open_record_error;
629  }
630 
631  // Append the entire handshake record to the buffer.
632  if (!tls_append_handshake_data(ssl, body)) {
633  *out_alert = SSL_AD_INTERNAL_ERROR;
634  return ssl_open_record_error;
635  }
636 
638 }
639 
640 void tls_next_message(SSL *ssl) {
641  SSLMessage msg;
642  if (!tls_get_message(ssl, &msg) ||
643  !ssl->s3->hs_buf ||
644  ssl->s3->hs_buf->length < CBS_len(&msg.raw)) {
645  assert(0);
646  return;
647  }
648 
649  OPENSSL_memmove(ssl->s3->hs_buf->data,
650  ssl->s3->hs_buf->data + CBS_len(&msg.raw),
651  ssl->s3->hs_buf->length - CBS_len(&msg.raw));
652  ssl->s3->hs_buf->length -= CBS_len(&msg.raw);
653  ssl->s3->is_v2_hello = false;
654  ssl->s3->has_message = false;
655 
656  // Post-handshake messages are rare, so release the buffer after every
657  // message. During the handshake, |on_handshake_complete| will release it.
658  if (!SSL_in_init(ssl) && ssl->s3->hs_buf->length == 0) {
659  ssl->s3->hs_buf.reset();
660  }
661 }
662 
663 // CipherScorer produces a "score" for each possible cipher suite offered by
664 // the client.
666  public:
670 
671  typedef std::tuple<bool, bool, bool> Score;
672 
673  // MinScore returns a |Score| that will compare less than the score of all
674  // cipher suites.
675  Score MinScore() const {
676  return Score(false, false, false);
677  }
678 
679  Score Evaluate(const SSL_CIPHER *a) const {
680  return Score(
681  // Something is always preferable to nothing.
682  true,
683  // Either 128-bit is fine, or 256-bit is preferred.
684  security_128_is_fine_ || a->algorithm_enc != SSL_AES128GCM,
685  // Either AES is fine, or else ChaCha20 is preferred.
686  aes_is_fine_ || a->algorithm_enc == SSL_CHACHA20POLY1305);
687  }
688 
689  private:
690  const bool aes_is_fine_;
692 };
693 
695  uint16_t group_id) {
696  if (CBS_len(&cipher_suites) % 2 != 0) {
697  return nullptr;
698  }
699 
700  const SSL_CIPHER *best = nullptr;
701  CipherScorer scorer(group_id);
702  CipherScorer::Score best_score = scorer.MinScore();
703 
704  while (CBS_len(&cipher_suites) > 0) {
705  uint16_t cipher_suite;
706  if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
707  return nullptr;
708  }
709 
710  // Limit to TLS 1.3 ciphers we know about.
711  const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
712  if (candidate == nullptr ||
713  SSL_CIPHER_get_min_version(candidate) > version ||
714  SSL_CIPHER_get_max_version(candidate) < version) {
715  continue;
716  }
717 
718  const CipherScorer::Score candidate_score = scorer.Evaluate(candidate);
719  // |candidate_score| must be larger to displace the current choice. That way
720  // the client's order controls between ciphers with an equal score.
721  if (candidate_score > best_score) {
722  best = candidate;
723  best_score = candidate_score;
724  }
725  }
726 
727  return best;
728 }
729 
SSL3_VERSION_MAJOR
#define SSL3_VERSION_MAJOR
Definition: ssl.h:647
xds_interop_client.str
str
Definition: xds_interop_client.py:487
ssl_st::server
bool server
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3777
Span::subspan
Span subspan(size_t pos=0, size_t len=npos) const
Definition: boringssl-with-bazel/src/include/openssl/span.h:162
ssl_cipher_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:520
SSL_AD_UNEXPECTED_MESSAGE
#define SSL_AD_UNEXPECTED_MESSAGE
Definition: ssl.h:3795
CBB_init
#define CBB_init
Definition: boringssl_prefix_symbols.h:1047
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
ssl_open_record_partial
@ ssl_open_record_partial
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:936
CBS_get_u16
#define CBS_get_u16
Definition: boringssl_prefix_symbols.h:1073
Span::size
size_t size() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:133
cbs_st
Definition: bytestring.h:39
tls_open_handshake
ssl_open_record_t tls_open_handshake(SSL *ssl, size_t *out_consumed, uint8_t *out_alert, Span< uint8_t > in)
Definition: s3_both.cc:561
CBB_cleanup
#define CBB_cleanup
Definition: boringssl_prefix_symbols.h:1039
SSL_CHACHA20POLY1305
#define SSL_CHACHA20POLY1305
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:561
BUF_MEM_append
#define BUF_MEM_append
Definition: boringssl_prefix_symbols.h:1007
evp.h
CBS_data
#define CBS_data
Definition: boringssl_prefix_symbols.h:1057
tls_open_record
enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, Span< uint8_t > *out, size_t *out_consumed, uint8_t *out_alert, Span< uint8_t > in)
Definition: tls_record.cc:206
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
parse_message
static bool parse_message(const SSL *ssl, SSLMessage *out, size_t *out_bytes_needed)
Definition: s3_both.cc:477
CipherScorer::CipherScorer
CipherScorer(uint16_t group_id)
Definition: s3_both.cc:667
SSL_R_BIO_NOT_SET
#define SSL_R_BIO_NOT_SET
Definition: ssl.h:5387
CipherScorer::security_128_is_fine_
const bool security_128_is_fine_
Definition: s3_both.cc:691
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
internal.h
string.h
CBB_add_u16_length_prefixed
#define CBB_add_u16_length_prefixed
Definition: boringssl_prefix_symbols.h:1028
CBB_add_u8
#define CBB_add_u8
Definition: boringssl_prefix_symbols.h:1036
ssl_quic_method_st::flush_flight
int(* flush_flight)(SSL *ssl)
Definition: ssl.h:3350
CipherScorer::aes_is_fine_
const bool aes_is_fine_
Definition: s3_both.cc:690
SSL_R_QUIC_INTERNAL_ERROR
#define SSL_R_QUIC_INTERNAL_ERROR
Definition: ssl.h:5565
SSL_AD_INTERNAL_ERROR
#define SSL_AD_INTERNAL_ERROR
Definition: ssl.h:3815
SSL_max_seal_overhead
#define SSL_max_seal_overhead
Definition: boringssl_prefix_symbols.h:412
CBS_len
#define CBS_len
Definition: boringssl_prefix_symbols.h:1089
BIO_write
#define BIO_write
Definition: boringssl_prefix_symbols.h:870
version
Definition: version.py:1
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
cipher_suites
static const char * cipher_suites
Definition: ssl_utils.cc:78
cbs
const CBS * cbs
Definition: third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h:107
SSL_AD_ILLEGAL_PARAMETER
#define SSL_AD_ILLEGAL_PARAMETER
Definition: ssl.h:3807
SSL3_RANDOM_SIZE
#define SSL3_RANDOM_SIZE
Definition: ssl3.h:204
tls_init_message
bool tls_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type)
Definition: s3_both.cc:171
CBS_init
#define CBS_init
Definition: boringssl_prefix_symbols.h:1085
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
tls_get_message
bool tls_get_message(const SSL *ssl, SSLMessage *out)
Definition: s3_both.cc:505
ssl_shutdown_none
@ ssl_shutdown_none
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2604
SSL3_MT_CLIENT_HELLO
#define SSL3_MT_CLIENT_HELLO
Definition: ssl3.h:299
OPENSSL_memset
static void * OPENSSL_memset(void *dst, int c, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:835
ssl_st::quic_method
const SSL_QUIC_METHOD * quic_method
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3769
tls_has_unprocessed_handshake_data
bool tls_has_unprocessed_handshake_data(const SSL *ssl)
Definition: s3_both.cc:539
ssl_quic_method_st::add_handshake_data
int(* add_handshake_data)(SSL *ssl, enum ssl_encryption_level_t level, const uint8_t *data, size_t len)
Definition: ssl.h:3345
ssl_max_handshake_message_len
size_t ssl_max_handshake_message_len(const SSL *ssl)
Definition: handshake.cc:230
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
ssl_do_msg_callback
void ssl_do_msg_callback(const SSL *ssl, int is_write, int content_type, Span< const uint8_t > in)
Definition: ssl_lib.cc:329
CipherScorer::Score
std::tuple< bool, bool, bool > Score
Definition: s3_both.cc:671
bytestring.h
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
CBB_add_u16
#define CBB_add_u16
Definition: boringssl_prefix_symbols.h:1027
BUF_MEM_reserve
#define BUF_MEM_reserve
Definition: boringssl_prefix_symbols.h:1012
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
Array< uint8_t >
Span::empty
bool empty() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:134
tls_add_message
bool tls_add_message(SSL *ssl, Array< uint8_t > msg)
Definition: s3_both.cc:188
ssl_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3698
buf.h
CBB_finish
#define CBB_finish
Definition: boringssl_prefix_symbols.h:1043
CBS
struct cbs_st CBS
Definition: base.h:388
read_v2_client_hello
static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed, Span< const uint8_t > in)
Definition: s3_both.cc:355
sha.h
CipherScorer
Definition: s3_both.cc:665
conf.version
string version
Definition: doc/python/sphinx/conf.py:36
SSL_R_UNEXPECTED_RECORD
#define SSL_R_UNEXPECTED_RECORD
Definition: ssl.h:5492
SSL3_HM_HEADER_LENGTH
#define SSL3_HM_HEADER_LENGTH
Definition: ssl3.h:208
ssl_st::wbio
bssl::UniquePtr< BIO > wbio
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3723
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
BSSL_NAMESPACE_END
#define BSSL_NAMESPACE_END
Definition: base.h:480
CBS_get_u8
#define CBS_get_u8
Definition: boringssl_prefix_symbols.h:1082
err.h
ERR_R_INTERNAL_ERROR
#define ERR_R_INTERNAL_ERROR
Definition: err.h:374
SSL_CIPHER_get_min_version
#define SSL_CIPHER_get_min_version
Definition: boringssl_prefix_symbols.h:52
tls_seal_record
bool tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, uint8_t type, const uint8_t *in, size_t in_len)
Definition: tls_record.cc:514
SSL3_MT_CCS
#define SSL3_MT_CCS
Definition: ssl3.h:326
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
Span< const uint8_t >
ERR_R_OVERFLOW
#define ERR_R_OVERFLOW
Definition: err.h:375
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
ssl.h
SSL_ERROR_WANT_WRITE
#define SSL_ERROR_WANT_WRITE
Definition: ssl.h:499
tls_finish_message
bool tls_finish_message(const SSL *ssl, CBB *cbb, Array< uint8_t > *out_msg)
Definition: s3_both.cc:184
SSL3_RT_HANDSHAKE
#define SSL3_RT_HANDSHAKE
Definition: ssl3.h:273
ssl_open_record_t
ssl_open_record_t
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:933
SSLMessage
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1140
EVP_has_aes_hardware
#define EVP_has_aes_hardware
Definition: boringssl_prefix_symbols.h:1729
CBB_add_bytes
#define CBB_add_bytes
Definition: boringssl_prefix_symbols.h:1025
SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE
#define SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE
Definition: ssl.h:5548
CBBFinishArray
OPENSSL_EXPORT bool CBBFinishArray(CBB *cbb, Array< uint8_t > *out)
Definition: ssl_lib.cc:190
BSSL_NAMESPACE_BEGIN
Definition: trust_token_test.cc:45
nid.h
ssl_st::s3
bssl::SSL3_STATE * s3
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3730
SSL3_RT_CHANGE_CIPHER_SPEC
#define SSL3_RT_CHANGE_CIPHER_SPEC
Definition: ssl3.h:271
rand.h
SSL_in_init
#define SSL_in_init
Definition: boringssl_prefix_symbols.h:401
ssl_open_record_success
@ ssl_open_record_success
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:934
md5.h
tls_flush_pending_hs_data
bool tls_flush_pending_hs_data(SSL *ssl)
Definition: s3_both.cc:244
CipherScorer::MinScore
Score MinScore() const
Definition: s3_both.cc:675
tls_add_change_cipher_spec
bool tls_add_change_cipher_spec(SSL *ssl)
Definition: s3_both.cc:266
SSL_CURVE_CECPQ2
#define SSL_CURVE_CECPQ2
Definition: ssl.h:2331
ssl_choose_tls13_cipher
const SSL_CIPHER * ssl_choose_tls13_cipher(CBS cipher_suites, uint16_t version, uint16_t group_id)
Definition: s3_both.cc:694
tls_flush_flight
int tls_flush_flight(SSL *ssl)
Definition: s3_both.cc:284
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
ssl_st::max_send_fragment
uint16_t max_send_fragment
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3717
ssl_open_record_error
@ ssl_open_record_error
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:938
OPENSSL_memmove
static void * OPENSSL_memmove(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:827
add_record_to_flight
static BSSL_NAMESPACE_BEGIN bool add_record_to_flight(SSL *ssl, uint8_t type, Span< const uint8_t > in)
Definition: s3_both.cc:137
SSL_R_RECORD_LENGTH_MISMATCH
#define SSL_R_RECORD_LENGTH_MISMATCH
Definition: ssl.h:5466
SSL_R_HTTP_REQUEST
#define SSL_R_HTTP_REQUEST
Definition: ssl.h:5424
CBS_get_bytes
#define CBS_get_bytes
Definition: boringssl_prefix_symbols.h:1067
SSL_get_cipher_by_value
#define SSL_get_cipher_by_value
Definition: boringssl_prefix_symbols.h:328
tls_append_handshake_data
bool tls_append_handshake_data(SSL *ssl, Span< const uint8_t > data)
Definition: s3_both.cc:552
CBS_get_u24
#define CBS_get_u24
Definition: boringssl_prefix_symbols.h:1076
ssl_write_buffer_flush
int ssl_write_buffer_flush(SSL *ssl)
Definition: ssl_buffer.cc:293
BUF_MEM_new
#define BUF_MEM_new
Definition: boringssl_prefix_symbols.h:1011
SSL_R_HTTPS_PROXY_REQUEST
#define SSL_R_HTTPS_PROXY_REQUEST
Definition: ssl.h:5423
Span::data
T * data() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:132
SSL_R_DECODE_ERROR
#define SSL_R_DECODE_ERROR
Definition: ssl.h:5405
mem.h
tls_next_message
void tls_next_message(SSL *ssl)
Definition: s3_both.cc:640
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
BIO_flush
#define BIO_flush
Definition: boringssl_prefix_symbols.h:786
tls_can_accept_handshake_data
bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert)
Definition: s3_both.cc:519
SSL3_RT_APPLICATION_DATA
#define SSL3_RT_APPLICATION_DATA
Definition: ssl3.h:274
SSL_R_RECORD_TOO_LARGE
#define SSL_R_RECORD_TOO_LARGE
Definition: ssl.h:5467
CipherScorer::Evaluate
Score Evaluate(const SSL_CIPHER *a) const
Definition: s3_both.cc:679
CBB_init_fixed
#define CBB_init_fixed
Definition: boringssl_prefix_symbols.h:1048
SSL2_MT_CLIENT_HELLO
#define SSL2_MT_CLIENT_HELLO
Definition: ssl3.h:130
SSL_CIPHER_get_max_version
#define SSL_CIPHER_get_max_version
Definition: boringssl_prefix_symbols.h:51
SSL3_RT_HEADER_LENGTH
#define SSL3_RT_HEADER_LENGTH
Definition: ssl3.h:206
SSL_AES128GCM
#define SSL_AES128GCM
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:558
ERR_R_MALLOC_FAILURE
#define ERR_R_MALLOC_FAILURE
Definition: err.h:371
SSL_R_EXCESSIVE_MESSAGE_SIZE
#define SSL_R_EXCESSIVE_MESSAGE_SIZE
Definition: ssl.h:5418
SSL_R_PROTOCOL_IS_SHUTDOWN
#define SSL_R_PROTOCOL_IS_SHUTDOWN
Definition: ssl.h:5461
absl::MakeConstSpan
constexpr Span< const T > MakeConstSpan(T *ptr, size_t size) noexcept
Definition: abseil-cpp/absl/types/span.h:707
cbb_st
Definition: bytestring.h:375
CBB_add_u24_length_prefixed
#define CBB_add_u24_length_prefixed
Definition: boringssl_prefix_symbols.h:1031


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:09