handshake_util.cc
Go to the documentation of this file.
1 /* Copyright (c) 2018, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include "handshake_util.h"
16 
17 #include <assert.h>
18 #if defined(HANDSHAKER_SUPPORTED)
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <spawn.h>
22 #include <sys/socket.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <sys/wait.h>
26 #include <unistd.h>
27 #endif
28 
29 #include <functional>
30 #include <map>
31 #include <vector>
32 
33 #include "async_bio.h"
34 #include "packeted_bio.h"
35 #include "test_config.h"
36 #include "test_state.h"
37 
38 #include <openssl/bytestring.h>
39 #include <openssl/ssl.h>
40 
41 using namespace bssl;
42 
43 bool RetryAsync(SSL *ssl, int ret) {
44  const TestConfig *config = GetTestConfig(ssl);
46  if (ret >= 0) {
47  return false;
48  }
49 
50  int ssl_err = SSL_get_error(ssl, ret);
51  if (ssl_err == SSL_ERROR_WANT_RENEGOTIATE && config->renegotiate_explicit) {
52  test_state->explicit_renegotiates++;
53  return SSL_renegotiate(ssl);
54  }
55 
56  if (test_state->quic_transport && ssl_err == SSL_ERROR_WANT_READ) {
57  return test_state->quic_transport->ReadHandshake();
58  }
59 
60  if (!config->async) {
61  // Only asynchronous tests should trigger other retries.
62  return false;
63  }
64 
65  if (test_state->packeted_bio != nullptr &&
66  PacketedBioAdvanceClock(test_state->packeted_bio)) {
67  // The DTLS retransmit logic silently ignores write failures. So the test
68  // may progress, allow writes through synchronously.
69  AsyncBioEnforceWriteQuota(test_state->async_bio, false);
70  int timeout_ret = DTLSv1_handle_timeout(ssl);
71  AsyncBioEnforceWriteQuota(test_state->async_bio, true);
72 
73  if (timeout_ret < 0) {
74  fprintf(stderr, "Error retransmitting.\n");
75  return false;
76  }
77  return true;
78  }
79 
80  // See if we needed to read or write more. If so, allow one byte through on
81  // the appropriate end to maximally stress the state machine.
82  switch (ssl_err) {
84  AsyncBioAllowRead(test_state->async_bio, 1);
85  return true;
87  AsyncBioAllowWrite(test_state->async_bio, 1);
88  return true;
90  test_state->cert_ready = true;
91  return true;
93  test_state->session = std::move(test_state->pending_session);
94  return true;
96  test_state->early_callback_ready = true;
97  return true;
99  test_state->private_key_retries++;
100  return true;
102  test_state->custom_verify_ready = true;
103  return true;
104  default:
105  return false;
106  }
107 }
108 
109 int CheckIdempotentError(const char *name, SSL *ssl,
110  std::function<int()> func) {
111  int ret = func();
112  int ssl_err = SSL_get_error(ssl, ret);
114  if (ssl_err == SSL_ERROR_SSL || ssl_err == SSL_ERROR_ZERO_RETURN) {
115  int ret2 = func();
116  int ssl_err2 = SSL_get_error(ssl, ret2);
117  uint32_t err2 = ERR_peek_error();
118  if (ret != ret2 || ssl_err != ssl_err2 || err != err2) {
119  fprintf(stderr, "Repeating %s did not replay the error.\n", name);
120  char buf[256];
121  ERR_error_string_n(err, buf, sizeof(buf));
122  fprintf(stderr, "Wanted: %d %d %s\n", ret, ssl_err, buf);
123  ERR_error_string_n(err2, buf, sizeof(buf));
124  fprintf(stderr, "Got: %d %d %s\n", ret2, ssl_err2, buf);
125  // runner treats exit code 90 as always failing. Otherwise, it may
126  // accidentally consider the result an expected protocol failure.
127  exit(90);
128  }
129  }
130  return ret;
131 }
132 
133 #if defined(HANDSHAKER_SUPPORTED)
134 
135 // MoveBIOs moves the |BIO|s of |src| to |dst|. It is used for handoff.
136 static void MoveBIOs(SSL *dest, SSL *src) {
137  BIO *rbio = SSL_get_rbio(src);
138  BIO_up_ref(rbio);
139  SSL_set0_rbio(dest, rbio);
140 
141  BIO *wbio = SSL_get_wbio(src);
142  BIO_up_ref(wbio);
143  SSL_set0_wbio(dest, wbio);
144 
145  SSL_set0_rbio(src, nullptr);
146  SSL_set0_wbio(src, nullptr);
147 }
148 
149 static bool HandoffReady(SSL *ssl, int ret) {
150  return ret < 0 && SSL_get_error(ssl, ret) == SSL_ERROR_HANDOFF;
151 }
152 
153 static ssize_t read_eintr(int fd, void *out, size_t len) {
154  ssize_t ret;
155  do {
156  ret = read(fd, out, len);
157  } while (ret < 0 && errno == EINTR);
158  return ret;
159 }
160 
161 static ssize_t write_eintr(int fd, const void *in, size_t len) {
162  ssize_t ret;
163  do {
164  ret = write(fd, in, len);
165  } while (ret < 0 && errno == EINTR);
166  return ret;
167 }
168 
169 static ssize_t waitpid_eintr(pid_t pid, int *wstatus, int options) {
170  pid_t ret;
171  do {
172  ret = waitpid(pid, wstatus, options);
173  } while (ret < 0 && errno == EINTR);
174  return ret;
175 }
176 
177 // Proxy relays data between |socket|, which is connected to the client, and the
178 // handshaker, which is connected to the numerically specified file descriptors,
179 // until the handshaker returns control.
180 static bool Proxy(BIO *socket, bool async, int control, int rfd, int wfd) {
181  for (;;) {
182  fd_set rfds;
183  FD_ZERO(&rfds);
184  FD_SET(wfd, &rfds);
185  FD_SET(control, &rfds);
186  int fd_max = wfd > control ? wfd : control;
187  if (select(fd_max + 1, &rfds, nullptr, nullptr, nullptr) == -1) {
188  perror("select");
189  return false;
190  }
191 
192  char buf[64];
193  ssize_t bytes;
194  if (FD_ISSET(wfd, &rfds) &&
195  (bytes = read_eintr(wfd, buf, sizeof(buf))) > 0) {
196  char *b = buf;
197  while (bytes) {
198  int written = BIO_write(socket, b, bytes);
199  if (!written) {
200  fprintf(stderr, "BIO_write wrote nothing\n");
201  return false;
202  }
203  if (written < 0) {
204  if (async) {
206  continue;
207  }
208  fprintf(stderr, "BIO_write failed\n");
209  return false;
210  }
211  b += written;
212  bytes -= written;
213  }
214  // Flush all pending data from the handshaker to the client before
215  // considering control messages.
216  continue;
217  }
218 
219  if (!FD_ISSET(control, &rfds)) {
220  continue;
221  }
222 
223  char msg;
224  if (read_eintr(control, &msg, 1) != 1) {
225  perror("read");
226  return false;
227  }
228  switch (msg) {
229  case kControlMsgDone:
230  return true;
231  case kControlMsgError:
232  return false;
233  case kControlMsgWantRead:
234  break;
235  default:
236  fprintf(stderr, "Unknown control message from handshaker: %c\n", msg);
237  return false;
238  }
239 
240  auto proxy_data = [&](uint8_t *out, size_t len) -> bool {
241  if (async) {
243  }
244 
245  while (len > 0) {
246  int bytes_read = BIO_read(socket, out, len);
247  if (bytes_read < 1) {
248  fprintf(stderr, "BIO_read failed\n");
249  return false;
250  }
251 
252  ssize_t bytes_written = write_eintr(rfd, out, bytes_read);
253  if (bytes_written == -1) {
254  perror("write");
255  return false;
256  }
257  if (bytes_written != bytes_read) {
258  fprintf(stderr, "short write (%zu of %d bytes)\n", bytes_written,
259  bytes_read);
260  return false;
261  }
262 
263  len -= bytes_read;
264  out += bytes_read;
265  }
266  return true;
267  };
268 
269  // Process one SSL record at a time. That way, we don't send the handshaker
270  // anything it doesn't want to process, e.g. early data.
272  if (!proxy_data(header, sizeof(header))) {
273  return false;
274  }
275  if (header[1] != 3) {
276  fprintf(stderr, "bad header\n");
277  return false;
278  }
279  size_t remaining = (header[3] << 8) + header[4];
280  while (remaining > 0) {
281  uint8_t readbuf[64];
282  size_t len = remaining > sizeof(readbuf) ? sizeof(readbuf) : remaining;
283  if (!proxy_data(readbuf, len)) {
284  return false;
285  }
286  remaining -= len;
287  }
288 
289  // The handshaker blocks on the control channel, so we have to signal
290  // it that the data have been written.
291  msg = kControlMsgWriteCompleted;
292  if (write_eintr(control, &msg, 1) != 1) {
293  perror("write");
294  return false;
295  }
296  }
297 }
298 
299 class ScopedFD {
300  public:
301  ScopedFD() : fd_(-1) {}
302  explicit ScopedFD(int fd) : fd_(fd) {}
303  ~ScopedFD() { Reset(); }
304 
305  ScopedFD(ScopedFD &&other) { *this = std::move(other); }
306  ScopedFD &operator=(ScopedFD &&other) {
307  Reset(other.fd_);
308  other.fd_ = -1;
309  return *this;
310  }
311 
312  int fd() const { return fd_; }
313 
314  void Reset(int fd = -1) {
315  if (fd_ >= 0) {
316  close(fd_);
317  }
318  fd_ = fd;
319  }
320 
321  private:
322  int fd_;
323 };
324 
325 class ScopedProcess {
326  public:
327  ScopedProcess() : pid_(-1) {}
328  ~ScopedProcess() { Reset(); }
329 
330  ScopedProcess(ScopedProcess &&other) { *this = std::move(other); }
331  ScopedProcess &operator=(ScopedProcess &&other) {
332  Reset(other.pid_);
333  other.pid_ = -1;
334  return *this;
335  }
336 
337  pid_t pid() const { return pid_; }
338 
339  void Reset(pid_t pid = -1) {
340  if (pid_ >= 0) {
341  kill(pid_, SIGTERM);
342  int unused;
343  Wait(&unused);
344  }
345  pid_ = pid;
346  }
347 
348  bool Wait(int *out_status) {
349  if (pid_ < 0) {
350  return false;
351  }
352  if (waitpid_eintr(pid_, out_status, 0) != pid_) {
353  return false;
354  }
355  pid_ = -1;
356  return true;
357  }
358 
359  private:
360  pid_t pid_;
361 };
362 
363 class FileActionsDestroyer {
364  public:
365  explicit FileActionsDestroyer(posix_spawn_file_actions_t *actions)
366  : actions_(actions) {}
367  ~FileActionsDestroyer() { posix_spawn_file_actions_destroy(actions_); }
368  FileActionsDestroyer(const FileActionsDestroyer &) = delete;
369  FileActionsDestroyer &operator=(const FileActionsDestroyer &) = delete;
370 
371  private:
372  posix_spawn_file_actions_t *actions_;
373 };
374 
375 // StartHandshaker starts the handshaker process and, on success, returns a
376 // handle to the process in |*out|. It sets |*out_control| to a control pipe to
377 // the process. |map_fds| maps from desired fd number in the child process to
378 // the source fd in the calling process. |close_fds| is the list of additional
379 // fds to close, which may overlap with |map_fds|. Other than stdin, stdout, and
380 // stderr, the status of fds not listed in either set is undefined.
381 static bool StartHandshaker(ScopedProcess *out, ScopedFD *out_control,
382  const TestConfig *config, bool is_resume,
383  std::map<int, int> map_fds,
384  std::vector<int> close_fds) {
385  if (config->handshaker_path.empty()) {
386  fprintf(stderr, "no -handshaker-path specified\n");
387  return false;
388  }
389  struct stat dummy;
390  if (stat(config->handshaker_path.c_str(), &dummy) == -1) {
391  perror(config->handshaker_path.c_str());
392  return false;
393  }
394 
395  std::vector<const char *> args;
396  args.push_back(config->handshaker_path.c_str());
397  static const char kResumeFlag[] = "-handshaker-resume";
398  if (is_resume) {
399  args.push_back(kResumeFlag);
400  }
401  // config->argv omits argv[0].
402  for (int j = 0; j < config->argc; ++j) {
403  args.push_back(config->argv[j]);
404  }
405  args.push_back(nullptr);
406 
407  // A datagram socket guarantees that writes are all-or-nothing.
408  int control[2];
409  if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, control) != 0) {
410  perror("socketpair");
411  return false;
412  }
413  ScopedFD scoped_control0(control[0]), scoped_control1(control[1]);
414  close_fds.push_back(control[0]);
415  map_fds[kFdControl] = control[1];
416 
417  posix_spawn_file_actions_t actions;
418  if (posix_spawn_file_actions_init(&actions) != 0) {
419  return false;
420  }
421  FileActionsDestroyer actions_destroyer(&actions);
422  for (int fd : close_fds) {
423  if (posix_spawn_file_actions_addclose(&actions, fd) != 0) {
424  return false;
425  }
426  }
427  if (!map_fds.empty()) {
428  int max_fd = STDERR_FILENO;
429  for (const auto &pair : map_fds) {
430  max_fd = std::max(max_fd, pair.first);
431  max_fd = std::max(max_fd, pair.second);
432  }
433  // |map_fds| may contain cycles, so make a copy of all the source fds.
434  // |posix_spawn| can only use |dup2|, not |dup|, so we assume |max_fd| is
435  // the last fd we care about inheriting. |temp_fds| maps from fd number in
436  // the parent process to a temporary fd number in the child process.
437  std::map<int, int> temp_fds;
438  int next_fd = max_fd + 1;
439  for (const auto &pair : map_fds) {
440  if (temp_fds.count(pair.second)) {
441  continue;
442  }
443  temp_fds[pair.second] = next_fd;
444  if (posix_spawn_file_actions_adddup2(&actions, pair.second, next_fd) !=
445  0 ||
446  posix_spawn_file_actions_addclose(&actions, pair.second) != 0) {
447  return false;
448  }
449  next_fd++;
450  }
451  for (const auto &pair : map_fds) {
452  if (posix_spawn_file_actions_adddup2(&actions, temp_fds[pair.second],
453  pair.first) != 0) {
454  return false;
455  }
456  }
457  // Clean up temporary fds.
458  for (int fd = max_fd + 1; fd < next_fd; fd++) {
459  if (posix_spawn_file_actions_addclose(&actions, fd) != 0) {
460  return false;
461  }
462  }
463  }
464 
465  fflush(stdout);
466  fflush(stderr);
467 
468  // MSan doesn't know that |posix_spawn| initializes its output, so initialize
469  // it to -1.
470  pid_t pid = -1;
471  if (posix_spawn(&pid, args[0], &actions, nullptr,
472  const_cast<char *const *>(args.data()), environ) != 0) {
473  return false;
474  }
475 
476  out->Reset(pid);
477  *out_control = std::move(scoped_control0);
478  return true;
479 }
480 
481 // RunHandshaker forks and execs the handshaker binary, handing off |input|,
482 // and, after proxying some amount of handshake traffic, handing back |out|.
483 static bool RunHandshaker(BIO *bio, const TestConfig *config, bool is_resume,
485  std::vector<uint8_t> *out) {
486  int rfd[2], wfd[2];
487  // We use pipes, rather than some other mechanism, for their buffers. During
488  // the handshake, this process acts as a dumb proxy until receiving the
489  // handback signal, which arrives asynchronously. The race condition means
490  // that this process could incorrectly proxy post-handshake data from the
491  // client to the handshaker.
492  //
493  // To avoid this, this process never proxies data to the handshaker that the
494  // handshaker has not explicitly requested as a result of hitting
495  // |SSL_ERROR_WANT_READ|. Pipes allow the data to sit in a buffer while the
496  // two processes synchronize over the |control| channel.
497  if (pipe(rfd) != 0) {
498  perror("pipe");
499  return false;
500  }
501  ScopedFD rfd0_closer(rfd[0]), rfd1_closer(rfd[1]);
502 
503  if (pipe(wfd) != 0) {
504  perror("pipe");
505  return false;
506  }
507  ScopedFD wfd0_closer(wfd[0]), wfd1_closer(wfd[1]);
508 
509  ScopedProcess handshaker;
510  ScopedFD control;
511  if (!StartHandshaker(
512  &handshaker, &control, config, is_resume,
513  {{kFdProxyToHandshaker, rfd[0]}, {kFdHandshakerToProxy, wfd[1]}},
514  {rfd[1], wfd[0]})) {
515  return false;
516  }
517 
518  rfd0_closer.Reset();
519  wfd1_closer.Reset();
520 
521  if (write_eintr(control.fd(), input.data(), input.size()) == -1) {
522  perror("write");
523  return false;
524  }
525  bool ok = Proxy(bio, config->async, control.fd(), rfd[1], wfd[0]);
526  int wstatus;
527  if (!handshaker.Wait(&wstatus)) {
528  perror("waitpid");
529  return false;
530  }
531  if (ok && wstatus) {
532  fprintf(stderr, "handshaker exited irregularly\n");
533  return false;
534  }
535  if (!ok) {
536  return false; // This is a "good", i.e. expected, error.
537  }
538 
539  constexpr size_t kBufSize = 1024 * 1024;
540  std::vector<uint8_t> buf(kBufSize);
541  ssize_t len = read_eintr(control.fd(), buf.data(), buf.size());
542  if (len == -1) {
543  perror("read");
544  return false;
545  }
546  buf.resize(len);
547  *out = std::move(buf);
548  return true;
549 }
550 
551 static bool RequestHandshakeHint(const TestConfig *config, bool is_resume,
552  Span<const uint8_t> input, bool *out_has_hints,
553  std::vector<uint8_t> *out_hints) {
554  ScopedProcess handshaker;
555  ScopedFD control;
556  if (!StartHandshaker(&handshaker, &control, config, is_resume, {}, {})) {
557  return false;
558  }
559 
560  if (write_eintr(control.fd(), input.data(), input.size()) == -1) {
561  perror("write");
562  return false;
563  }
564 
565  char msg;
566  if (read_eintr(control.fd(), &msg, 1) != 1) {
567  perror("read");
568  return false;
569  }
570 
571  switch (msg) {
572  case kControlMsgDone: {
573  constexpr size_t kBufSize = 1024 * 1024;
574  out_hints->resize(kBufSize);
575  ssize_t len =
576  read_eintr(control.fd(), out_hints->data(), out_hints->size());
577  if (len == -1) {
578  perror("read");
579  return false;
580  }
581  out_hints->resize(len);
582  *out_has_hints = true;
583  break;
584  }
585  case kControlMsgError:
586  *out_has_hints = false;
587  break;
588  default:
589  fprintf(stderr, "Unknown control message from handshaker: %c\n", msg);
590  return false;
591  }
592 
593  int wstatus;
594  if (!handshaker.Wait(&wstatus)) {
595  perror("waitpid");
596  return false;
597  }
598  if (wstatus) {
599  fprintf(stderr, "handshaker exited irregularly\n");
600  return false;
601  }
602 
603  return true;
604 }
605 
606 // PrepareHandoff accepts the |ClientHello| from |ssl| and serializes state to
607 // be passed to the handshaker. The serialized state includes both the SSL
608 // handoff, as well test-related state.
609 static bool PrepareHandoff(SSL *ssl, SettingsWriter *writer,
610  std::vector<uint8_t> *out_handoff) {
611  SSL_set_handoff_mode(ssl, 1);
612 
613  const TestConfig *config = GetTestConfig(ssl);
614  int ret = -1;
615  do {
617  "SSL_do_handshake", ssl,
618  [&]() -> int { return SSL_do_handshake(ssl); });
619  } while (!HandoffReady(ssl, ret) &&
620  config->async &&
621  RetryAsync(ssl, ret));
622  if (!HandoffReady(ssl, ret)) {
623  fprintf(stderr, "Handshake failed while waiting for handoff.\n");
624  return false;
625  }
626 
627  ScopedCBB cbb;
629  if (!CBB_init(cbb.get(), 512) ||
630  !SSL_serialize_handoff(ssl, cbb.get(), &hello) ||
631  !writer->WriteHandoff({CBB_data(cbb.get()), CBB_len(cbb.get())}) ||
632  !SerializeContextState(SSL_get_SSL_CTX(ssl), cbb.get()) ||
633  !GetTestState(ssl)->Serialize(cbb.get())) {
634  fprintf(stderr, "Handoff serialisation failed.\n");
635  return false;
636  }
637  out_handoff->assign(CBB_data(cbb.get()),
638  CBB_data(cbb.get()) + CBB_len(cbb.get()));
639  return true;
640 }
641 
642 // DoSplitHandshake delegates the SSL handshake to a separate process, called
643 // the handshaker. This process proxies I/O between the handshaker and the
644 // client, using the |BIO| from |ssl|. After a successful handshake, |ssl| is
645 // replaced with a new |SSL| object, in a way that is intended to be invisible
646 // to the caller.
647 bool DoSplitHandshake(UniquePtr<SSL> *ssl, SettingsWriter *writer,
648  bool is_resume) {
649  assert(SSL_get_rbio(ssl->get()) == SSL_get_wbio(ssl->get()));
650  std::vector<uint8_t> handshaker_input;
651  const TestConfig *config = GetTestConfig(ssl->get());
652  // out is the response from the handshaker, which includes a serialized
653  // handback message, but also serialized updates to the |TestState|.
654  std::vector<uint8_t> out;
655  if (!PrepareHandoff(ssl->get(), writer, &handshaker_input) ||
656  !RunHandshaker(SSL_get_rbio(ssl->get()), config, is_resume,
657  handshaker_input, &out)) {
658  fprintf(stderr, "Handoff failed.\n");
659  return false;
660  }
661 
662  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl->get());
663  UniquePtr<SSL> ssl_handback = config->NewSSL(ctx, nullptr, nullptr);
664  if (!ssl_handback) {
665  return false;
666  }
667  CBS output, handback;
668  CBS_init(&output, out.data(), out.size());
669  if (!CBS_get_u24_length_prefixed(&output, &handback) ||
671  !SetTestState(ssl_handback.get(), TestState::Deserialize(&output, ctx)) ||
672  !GetTestState(ssl_handback.get()) || !writer->WriteHandback(handback) ||
673  !SSL_apply_handback(ssl_handback.get(), handback)) {
674  fprintf(stderr, "Handback failed.\n");
675  return false;
676  }
677  MoveBIOs(ssl_handback.get(), ssl->get());
678  GetTestState(ssl_handback.get())->async_bio =
679  GetTestState(ssl->get())->async_bio;
680  GetTestState(ssl->get())->async_bio = nullptr;
681 
682  *ssl = std::move(ssl_handback);
683  return true;
684 }
685 
686 bool GetHandshakeHint(SSL *ssl, SettingsWriter *writer, bool is_resume,
687  const SSL_CLIENT_HELLO *client_hello) {
688  ScopedCBB input;
689  CBB child;
690  if (!CBB_init(input.get(), client_hello->client_hello_len + 256) ||
692  !CBB_add_bytes(&child, client_hello->client_hello,
693  client_hello->client_hello_len) ||
695  !SSL_serialize_capabilities(ssl, &child) || //
696  !CBB_flush(input.get())) {
697  return false;
698  }
699 
700  bool has_hints;
701  std::vector<uint8_t> hints;
702  if (!RequestHandshakeHint(
703  GetTestConfig(ssl), is_resume,
704  MakeConstSpan(CBB_data(input.get()), CBB_len(input.get())),
705  &has_hints, &hints)) {
706  return false;
707  }
708  if (has_hints &&
709  (!writer->WriteHints(hints) ||
710  !SSL_set_handshake_hints(ssl, hints.data(), hints.size()))) {
711  return false;
712  }
713 
714  return true;
715 }
716 
717 #endif // defined(HANDSHAKER_SUPPORTED)
environ
char ** environ
Definition: bloaty/third_party/googletest/googlemock/test/gmock_leak_test.py:41
CBS_get_u24_length_prefixed
#define CBS_get_u24_length_prefixed
Definition: boringssl_prefix_symbols.h:1077
CBB_flush
#define CBB_flush
Definition: boringssl_prefix_symbols.h:1045
CBB_data
#define CBB_data
Definition: boringssl_prefix_symbols.h:1040
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
absl::str_format_internal::LengthMod::j
@ j
cbs_st
Definition: bytestring.h:39
ctx
Definition: benchmark-async.c:30
GetTestState
TestState * GetTestState(const SSL *ssl)
Definition: test_state.cc:62
bio_st
Definition: bio.h:822
demumble_test.stdout
stdout
Definition: demumble_test.py:38
test_state.h
write
#define write
Definition: test-fs.c:47
SSL_ERROR_WANT_READ
#define SSL_ERROR_WANT_READ
Definition: ssl.h:494
GetTestConfig
const TestConfig * GetTestConfig(const SSL *ssl)
Definition: third_party/boringssl-with-bazel/src/ssl/test/test_config.cc:499
SSL_ERROR_SSL
#define SSL_ERROR_SSL
Definition: ssl.h:485
options
double_dict options[]
Definition: capstone_test.c:55
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
SSL_serialize_capabilities
#define SSL_serialize_capabilities
Definition: boringssl_prefix_symbols.h:431
error_ref_leak.err
err
Definition: error_ref_leak.py:35
SerializeContextState
bool SerializeContextState(SSL_CTX *ctx, CBB *cbb)
Definition: test_state.cc:85
bssl
Definition: hpke_test.cc:37
DTLSv1_handle_timeout
#define DTLSv1_handle_timeout
Definition: boringssl_prefix_symbols.h:33
SSL_do_handshake
#define SSL_do_handshake
Definition: boringssl_prefix_symbols.h:297
setup.name
name
Definition: setup.py:542
BIO_write
#define BIO_write
Definition: boringssl_prefix_symbols.h:870
SSL_renegotiate
#define SSL_renegotiate
Definition: boringssl_prefix_symbols.h:425
AsyncBioEnforceWriteQuota
void AsyncBioEnforceWriteQuota(BIO *bio, bool enforce)
Definition: async_bio.cc:185
ssl_early_callback_ctx::client_hello_len
size_t client_hello_len
Definition: ssl.h:4189
BIO_read
#define BIO_read
Definition: boringssl_prefix_symbols.h:831
CBS_init
#define CBS_init
Definition: boringssl_prefix_symbols.h:1085
TestConfig
Definition: third_party/boringssl-with-bazel/src/ssl/test/test_config.h:27
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
test_config.h
PacketedBioAdvanceClock
bool PacketedBioAdvanceClock(BIO *bio)
Definition: packeted_bio.cc:249
ssl_ctx_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3404
async_bio.h
SSL_ERROR_WANT_RENEGOTIATE
#define SSL_ERROR_WANT_RENEGOTIATE
Definition: ssl.h:587
SSL_ERROR_WANT_PRIVATE_KEY_OPERATION
#define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION
Definition: ssl.h:558
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
TestState::Deserialize
static std::unique_ptr< TestState > Deserialize(CBS *cbs, SSL_CTX *ctx)
Definition: test_state.cc:149
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
SSL_set_handshake_hints
#define SSL_set_handshake_hints
Definition: boringssl_prefix_symbols.h:464
test_state
Definition: invalid_call_argument_test.cc:37
bytestring.h
hello
static z_const char hello[]
Definition: bloaty/third_party/zlib/test/example.c:29
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
ssize_t
intptr_t ssize_t
Definition: win.h:27
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
SSL_get_error
#define SSL_get_error
Definition: boringssl_prefix_symbols.h:340
mox.Reset
def Reset(*args)
Definition: bloaty/third_party/protobuf/python/mox.py:257
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
AsyncBioAllowWrite
void AsyncBioAllowWrite(BIO *bio, size_t count)
Definition: async_bio.cc:177
config
struct config_s config
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
ssl_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3698
ssl_early_callback_ctx
Definition: ssl.h:4186
ScopedFD
Definition: third_party/boringssl-with-bazel/src/tool/internal.h:47
ERR_peek_error
#define ERR_peek_error
Definition: boringssl_prefix_symbols.h:1428
SSL_get_rbio
#define SSL_get_rbio
Definition: boringssl_prefix_symbols.h:366
bytes_read
static size_t bytes_read
Definition: test-ipc-heavy-traffic-deadlock-bug.c:47
header
struct absl::base_internal::@2940::AllocList::Header header
BIO_up_ref
#define BIO_up_ref
Definition: boringssl_prefix_symbols.h:866
close
#define close
Definition: test-fs.c:48
googletest-filter-unittest.child
child
Definition: bloaty/third_party/googletest/googletest/test/googletest-filter-unittest.py:62
handshake_util.h
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
ERR_error_string_n
#define ERR_error_string_n
Definition: boringssl_prefix_symbols.h:1416
TestState
Definition: test_state.h:27
Span< const uint8_t >
tests.qps.qps_worker.dest
dest
Definition: qps_worker.py:45
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
RetryAsync
bool RetryAsync(SSL *ssl, int ret)
Definition: handshake_util.cc:43
ssl.h
writer
void writer(void *n)
Definition: libuv/docs/code/locks/main.c:22
SSL_set0_rbio
#define SSL_set0_rbio
Definition: boringssl_prefix_symbols.h:436
SSL_ERROR_WANT_WRITE
#define SSL_ERROR_WANT_WRITE
Definition: ssl.h:499
SetTestState
bool SetTestState(SSL *ssl, std::unique_ptr< TestState > state)
Definition: test_state.cc:52
CBB_add_bytes
#define CBB_add_bytes
Definition: boringssl_prefix_symbols.h:1025
read
int read(izstream &zs, T *x, Items items)
Definition: bloaty/third_party/zlib/contrib/iostream2/zstream.h:115
func
const EVP_CIPHER *(* func)(void)
Definition: cipher_extra.c:73
SSL_ERROR_PENDING_SESSION
#define SSL_ERROR_PENDING_SESSION
Definition: ssl.h:543
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
packeted_bio.h
async
uv_async_t async
Definition: libuv/docs/code/progress/main.c:8
SSL_ERROR_ZERO_RETURN
#define SSL_ERROR_ZERO_RETURN
Definition: ssl.h:518
AsyncBioAllowRead
void AsyncBioAllowRead(BIO *bio, size_t count)
Definition: async_bio.cc:169
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
SSL_set0_wbio
#define SSL_set0_wbio
Definition: boringssl_prefix_symbols.h:438
ok
bool ok
Definition: async_end2end_test.cc:197
absl::ABSL_NAMESPACE_BEGIN::dummy
int dummy
Definition: function_type_benchmark.cc:28
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
stat
#define stat
Definition: test-fs.c:50
bytes_written
static size_t bytes_written
Definition: test-ipc-heavy-traffic-deadlock-bug.c:46
ssl_early_callback_ctx::client_hello
const uint8_t * client_hello
Definition: ssl.h:4188
SSL_get_wbio
#define SSL_get_wbio
Definition: boringssl_prefix_symbols.h:394
SSL_get_SSL_CTX
#define SSL_get_SSL_CTX
Definition: boringssl_prefix_symbols.h:326
test_server.socket
socket
Definition: test_server.py:65
SSL_ERROR_WANT_X509_LOOKUP
#define SSL_ERROR_WANT_X509_LOOKUP
Definition: ssl.h:507
CBB_len
#define CBB_len
Definition: boringssl_prefix_symbols.h:1049
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
TestState::async_bio
BIO * async_bio
Definition: test_state.h:40
SSL_ERROR_PENDING_CERTIFICATE
#define SSL_ERROR_PENDING_CERTIFICATE
Definition: ssl.h:550
pair
std::pair< std::string, std::string > pair
Definition: abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc:78
SSL_set_handoff_mode
void SSL_set_handoff_mode(SSL *ssl, bool on)
Definition: ssl_lib.cc:452
SSL_serialize_handoff
bool SSL_serialize_handoff(const SSL *ssl, CBB *out, SSL_CLIENT_HELLO *out_hello)
Definition: handoff.cc:76
SSL3_RT_HEADER_LENGTH
#define SSL3_RT_HEADER_LENGTH
Definition: ssl3.h:206
SSL_ERROR_WANT_CERTIFICATE_VERIFY
#define SSL_ERROR_WANT_CERTIFICATE_VERIFY
Definition: ssl.h:577
DeserializeContextState
bool DeserializeContextState(CBS *cbs, SSL_CTX *ctx)
Definition: test_state.cc:106
errno.h
SSL_apply_handback
bool SSL_apply_handback(SSL *ssl, Span< const uint8_t > handback)
Definition: handoff.cc:442
BSSL_NAMESPACE_BEGIN::MoveBIOs
void MoveBIOs(SSL *dest, SSL *src)
Definition: ssl_test.cc:5116
CheckIdempotentError
int CheckIdempotentError(const char *name, SSL *ssl, std::function< int()> func)
Definition: handshake_util.cc:109
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
SSL_ERROR_HANDOFF
#define SSL_ERROR_HANDOFF
Definition: ssl.h:579
CBB_add_u24_length_prefixed
#define CBB_add_u24_length_prefixed
Definition: boringssl_prefix_symbols.h:1031
SettingsWriter
Definition: settings_writer.h:25


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:10