您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /* Copyright (c) 2014, 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 <openssl/base.h>
  15. #include <openssl/err.h>
  16. #include <openssl/pem.h>
  17. #include <openssl/ssl.h>
  18. #include "../crypto/test/scoped_types.h"
  19. #include "../ssl/test/scoped_types.h"
  20. #include "internal.h"
  21. #include "transport_common.h"
  22. static const struct argument kArguments[] = {
  23. {
  24. "-connect", kRequiredArgument,
  25. "The hostname and port of the server to connect to, e.g. foo.com:443",
  26. },
  27. {
  28. "-cipher", kOptionalArgument,
  29. "An OpenSSL-style cipher suite string that configures the offered ciphers",
  30. },
  31. {
  32. "-max-version", kOptionalArgument,
  33. "The maximum acceptable protocol version",
  34. },
  35. {
  36. "-min-version", kOptionalArgument,
  37. "The minimum acceptable protocol version",
  38. },
  39. {
  40. "-server-name", kOptionalArgument,
  41. "The server name to advertise",
  42. },
  43. {
  44. "-select-next-proto", kOptionalArgument,
  45. "An NPN protocol to select if the server supports NPN",
  46. },
  47. {
  48. "-alpn-protos", kOptionalArgument,
  49. "A comma-separated list of ALPN protocols to advertise",
  50. },
  51. {
  52. "-fallback-scsv", kBooleanArgument,
  53. "Enable FALLBACK_SCSV",
  54. },
  55. {
  56. "-ocsp-stapling", kBooleanArgument,
  57. "Advertise support for OCSP stabling",
  58. },
  59. {
  60. "-signed-certificate-timestamps", kBooleanArgument,
  61. "Advertise support for signed certificate timestamps",
  62. },
  63. {
  64. "-channel-id-key", kOptionalArgument,
  65. "The key to use for signing a channel ID",
  66. },
  67. {
  68. "", kOptionalArgument, "",
  69. },
  70. };
  71. static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
  72. ScopedBIO bio(BIO_new(BIO_s_file()));
  73. if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
  74. return nullptr;
  75. }
  76. ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr,
  77. nullptr));
  78. return pkey;
  79. }
  80. static bool VersionFromString(uint16_t *out_version,
  81. const std::string& version) {
  82. if (version == "ssl3") {
  83. *out_version = SSL3_VERSION;
  84. return true;
  85. } else if (version == "tls1" || version == "tls1.0") {
  86. *out_version = TLS1_VERSION;
  87. return true;
  88. } else if (version == "tls1.1") {
  89. *out_version = TLS1_1_VERSION;
  90. return true;
  91. } else if (version == "tls1.2") {
  92. *out_version = TLS1_2_VERSION;
  93. return true;
  94. }
  95. return false;
  96. }
  97. static int NextProtoSelectCallback(SSL* ssl, uint8_t** out, uint8_t* outlen,
  98. const uint8_t* in, unsigned inlen, void* arg) {
  99. *out = reinterpret_cast<uint8_t *>(arg);
  100. *outlen = strlen(reinterpret_cast<const char *>(arg));
  101. return SSL_TLSEXT_ERR_OK;
  102. }
  103. bool Client(const std::vector<std::string> &args) {
  104. if (!InitSocketLibrary()) {
  105. return false;
  106. }
  107. std::map<std::string, std::string> args_map;
  108. if (!ParseKeyValueArguments(&args_map, args, kArguments)) {
  109. PrintUsage(kArguments);
  110. return false;
  111. }
  112. ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_client_method()));
  113. const char *keylog_file = getenv("SSLKEYLOGFILE");
  114. if (keylog_file) {
  115. BIO *keylog_bio = BIO_new_file(keylog_file, "a");
  116. if (!keylog_bio) {
  117. ERR_print_errors_cb(PrintErrorCallback, stderr);
  118. return false;
  119. }
  120. SSL_CTX_set_keylog_bio(ctx.get(), keylog_bio);
  121. }
  122. if (args_map.count("-cipher") != 0 &&
  123. !SSL_CTX_set_cipher_list(ctx.get(), args_map["-cipher"].c_str())) {
  124. fprintf(stderr, "Failed setting cipher list\n");
  125. return false;
  126. }
  127. if (args_map.count("-max-version") != 0) {
  128. uint16_t version;
  129. if (!VersionFromString(&version, args_map["-max-version"])) {
  130. fprintf(stderr, "Unknown protocol version: '%s'\n",
  131. args_map["-max-version"].c_str());
  132. return false;
  133. }
  134. SSL_CTX_set_max_version(ctx.get(), version);
  135. }
  136. if (args_map.count("-min-version") != 0) {
  137. uint16_t version;
  138. if (!VersionFromString(&version, args_map["-min-version"])) {
  139. fprintf(stderr, "Unknown protocol version: '%s'\n",
  140. args_map["-min-version"].c_str());
  141. return false;
  142. }
  143. SSL_CTX_set_min_version(ctx.get(), version);
  144. }
  145. if (args_map.count("-select-next-proto") != 0) {
  146. const std::string &proto = args_map["-select-next-proto"];
  147. if (proto.size() > 255) {
  148. fprintf(stderr, "Bad NPN protocol: '%s'\n", proto.c_str());
  149. return false;
  150. }
  151. // |SSL_CTX_set_next_proto_select_cb| is not const-correct.
  152. SSL_CTX_set_next_proto_select_cb(ctx.get(), NextProtoSelectCallback,
  153. const_cast<char *>(proto.c_str()));
  154. }
  155. if (args_map.count("-alpn-protos") != 0) {
  156. const std::string &alpn_protos = args_map["-alpn-protos"];
  157. std::vector<uint8_t> wire;
  158. size_t i = 0;
  159. while (i <= alpn_protos.size()) {
  160. size_t j = alpn_protos.find(',', i);
  161. if (j == std::string::npos) {
  162. j = alpn_protos.size();
  163. }
  164. size_t len = j - i;
  165. if (len > 255) {
  166. fprintf(stderr, "Invalid ALPN protocols: '%s'\n", alpn_protos.c_str());
  167. return false;
  168. }
  169. wire.push_back(static_cast<uint8_t>(len));
  170. wire.resize(wire.size() + len);
  171. memcpy(wire.data() + wire.size() - len, alpn_protos.data() + i, len);
  172. i = j + 1;
  173. }
  174. if (SSL_CTX_set_alpn_protos(ctx.get(), wire.data(), wire.size()) != 0) {
  175. return false;
  176. }
  177. }
  178. if (args_map.count("-fallback-scsv") != 0) {
  179. SSL_CTX_set_mode(ctx.get(), SSL_MODE_SEND_FALLBACK_SCSV);
  180. }
  181. if (args_map.count("-ocsp-stapling") != 0) {
  182. SSL_CTX_enable_ocsp_stapling(ctx.get());
  183. }
  184. if (args_map.count("-signed-certificate-timestamps") != 0) {
  185. SSL_CTX_enable_signed_cert_timestamps(ctx.get());
  186. }
  187. if (args_map.count("-channel-id-key") != 0) {
  188. ScopedEVP_PKEY pkey = LoadPrivateKey(args_map["-channel-id-key"]);
  189. if (!pkey || !SSL_CTX_set1_tls_channel_id(ctx.get(), pkey.get())) {
  190. return false;
  191. }
  192. ctx->tlsext_channel_id_enabled_new = 1;
  193. }
  194. int sock = -1;
  195. if (!Connect(&sock, args_map["-connect"])) {
  196. return false;
  197. }
  198. ScopedBIO bio(BIO_new_socket(sock, BIO_CLOSE));
  199. ScopedSSL ssl(SSL_new(ctx.get()));
  200. if (args_map.count("-server-name") != 0) {
  201. SSL_set_tlsext_host_name(ssl.get(), args_map["-server-name"].c_str());
  202. }
  203. SSL_set_bio(ssl.get(), bio.get(), bio.get());
  204. bio.release();
  205. int ret = SSL_connect(ssl.get());
  206. if (ret != 1) {
  207. int ssl_err = SSL_get_error(ssl.get(), ret);
  208. fprintf(stderr, "Error while connecting: %d\n", ssl_err);
  209. ERR_print_errors_cb(PrintErrorCallback, stderr);
  210. return false;
  211. }
  212. fprintf(stderr, "Connected.\n");
  213. PrintConnectionInfo(ssl.get());
  214. bool ok = TransferData(ssl.get(), sock);
  215. return ok;
  216. }