handshaker.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. #include <errno.h>
  15. #include <fcntl.h>
  16. #include <signal.h>
  17. #include <unistd.h>
  18. #include <openssl/bytestring.h>
  19. #include <openssl/rand.h>
  20. #include <openssl/ssl.h>
  21. #include "../internal.h"
  22. #include "handshake_util.h"
  23. #include "test_config.h"
  24. #include "test_state.h"
  25. using namespace bssl;
  26. namespace {
  27. bool HandbackReady(SSL *ssl, int ret) {
  28. return ret < 0 && SSL_get_error(ssl, ret) == SSL_ERROR_HANDBACK;
  29. }
  30. bool Handshaker(const TestConfig *config, int rfd, int wfd,
  31. Span<const uint8_t> input, int control) {
  32. UniquePtr<SSL_CTX> ctx = config->SetupCtx(/*old_ctx=*/nullptr);
  33. if (!ctx) {
  34. return false;
  35. }
  36. UniquePtr<SSL> ssl = config->NewSSL(ctx.get(), nullptr, false, nullptr);
  37. // Set |O_NONBLOCK| in order to break out of the loop when we hit
  38. // |SSL_ERROR_WANT_READ|, so that we can send |kControlMsgWantRead| to the
  39. // proxy.
  40. if (fcntl(rfd, F_SETFL, O_NONBLOCK) != 0) {
  41. perror("fcntl");
  42. return false;
  43. }
  44. SSL_set_rfd(ssl.get(), rfd);
  45. SSL_set_wfd(ssl.get(), wfd);
  46. CBS cbs, handoff;
  47. CBS_init(&cbs, input.data(), input.size());
  48. if (!CBS_get_asn1_element(&cbs, &handoff, CBS_ASN1_SEQUENCE) ||
  49. !DeserializeContextState(&cbs, ctx.get()) ||
  50. !SetTestState(ssl.get(), TestState::Deserialize(&cbs, ctx.get())) ||
  51. !GetTestState(ssl.get()) ||
  52. !SSL_apply_handoff(ssl.get(), handoff)) {
  53. fprintf(stderr, "Handoff application failed.\n");
  54. return false;
  55. }
  56. int ret = 0;
  57. for (;;) {
  58. ret = CheckIdempotentError(
  59. "SSL_do_handshake", ssl.get(),
  60. [&]() -> int { return SSL_do_handshake(ssl.get()); });
  61. if (SSL_get_error(ssl.get(), ret) == SSL_ERROR_WANT_READ) {
  62. // Synchronize with the proxy, i.e. don't let the handshake continue until
  63. // the proxy has sent more data.
  64. char msg = kControlMsgWantRead;
  65. if (write(control, &msg, 1) != 1 ||
  66. read(control, &msg, 1) != 1 ||
  67. msg != kControlMsgWriteCompleted) {
  68. fprintf(stderr, "read via proxy failed\n");
  69. return false;
  70. }
  71. continue;
  72. }
  73. if (!RetryAsync(ssl.get(), ret)) {
  74. break;
  75. }
  76. }
  77. if (!HandbackReady(ssl.get(), ret)) {
  78. ERR_print_errors_fp(stderr);
  79. return false;
  80. }
  81. ScopedCBB output;
  82. CBB handback;
  83. Array<uint8_t> bytes;
  84. if (!CBB_init(output.get(), 1024) ||
  85. !CBB_add_u24_length_prefixed(output.get(), &handback) ||
  86. !SSL_serialize_handback(ssl.get(), &handback) ||
  87. !SerializeContextState(ssl->ctx.get(), output.get()) ||
  88. !GetTestState(ssl.get())->Serialize(output.get()) ||
  89. !CBBFinishArray(output.get(), &bytes)) {
  90. fprintf(stderr, "Handback serialisation failed.\n");
  91. return false;
  92. }
  93. char msg = kControlMsgHandback;
  94. if (write(control, &msg, 1) == -1 ||
  95. write(control, bytes.data(), bytes.size()) == -1) {
  96. perror("write");
  97. return false;
  98. }
  99. return true;
  100. }
  101. ssize_t read_eintr(int fd, void *out, size_t len) {
  102. ssize_t ret;
  103. do {
  104. ret = read(fd, out, len);
  105. } while (ret < 0 && errno == EINTR);
  106. return ret;
  107. }
  108. ssize_t write_eintr(int fd, const void *in, size_t len) {
  109. ssize_t ret;
  110. do {
  111. ret = write(fd, in, len);
  112. } while (ret < 0 && errno == EINTR);
  113. return ret;
  114. }
  115. } // namespace
  116. int main(int argc, char **argv) {
  117. TestConfig initial_config, resume_config, retry_config;
  118. if (!ParseConfig(argc - 1, argv + 1, &initial_config, &resume_config,
  119. &retry_config)) {
  120. return 2;
  121. }
  122. const TestConfig *config = initial_config.handshaker_resume
  123. ? &resume_config : &initial_config;
  124. #if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
  125. if (initial_config.handshaker_resume) {
  126. // If the PRNG returns exactly the same values when trying to resume then a
  127. // "random" session ID will happen to exactly match the session ID
  128. // "randomly" generated on the initial connection. The client will thus
  129. // incorrectly believe that the server is resuming.
  130. uint8_t byte;
  131. RAND_bytes(&byte, 1);
  132. }
  133. #endif // BORINGSSL_UNSAFE_DETERMINISTIC_MODE
  134. // read() will return the entire message in one go, because it's a datagram
  135. // socket.
  136. constexpr size_t kBufSize = 1024 * 1024;
  137. bssl::UniquePtr<uint8_t> buf((uint8_t *) OPENSSL_malloc(kBufSize));
  138. ssize_t len = read_eintr(kFdControl, buf.get(), kBufSize);
  139. if (len == -1) {
  140. perror("read");
  141. return 2;
  142. }
  143. Span<uint8_t> handoff(buf.get(), len);
  144. if (!Handshaker(config, kFdProxyToHandshaker, kFdHandshakerToProxy, handoff,
  145. kFdControl)) {
  146. char msg = kControlMsgError;
  147. if (write_eintr(kFdControl, &msg, 1) != 1) {
  148. return 3;
  149. }
  150. return 1;
  151. }
  152. return 0;
  153. }