test_config.cc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include "test_config.h"
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <memory>
  14. #include <openssl/evp.h>
  15. namespace {
  16. template <typename T>
  17. struct Flag {
  18. const char *flag;
  19. T TestConfig::*member;
  20. };
  21. // FindField looks for the flag in |flags| that matches |flag|. If one is found,
  22. // it returns a pointer to the corresponding field in |config|. Otherwise, it
  23. // returns NULL.
  24. template<typename T, size_t N>
  25. T *FindField(TestConfig *config, const Flag<T> (&flags)[N], const char *flag) {
  26. for (size_t i = 0; i < N; i++) {
  27. if (strcmp(flag, flags[i].flag) == 0) {
  28. return &(config->*(flags[i].member));
  29. }
  30. }
  31. return NULL;
  32. }
  33. const Flag<bool> kBoolFlags[] = {
  34. { "-server", &TestConfig::is_server },
  35. { "-dtls", &TestConfig::is_dtls },
  36. { "-fallback-scsv", &TestConfig::fallback_scsv },
  37. { "-require-any-client-certificate",
  38. &TestConfig::require_any_client_certificate },
  39. { "-async", &TestConfig::async },
  40. { "-write-different-record-sizes",
  41. &TestConfig::write_different_record_sizes },
  42. { "-partial-write", &TestConfig::partial_write },
  43. { "-no-tls13", &TestConfig::no_tls13 },
  44. { "-no-tls12", &TestConfig::no_tls12 },
  45. { "-no-tls11", &TestConfig::no_tls11 },
  46. { "-no-tls1", &TestConfig::no_tls1 },
  47. { "-no-ssl3", &TestConfig::no_ssl3 },
  48. { "-shim-writes-first", &TestConfig::shim_writes_first },
  49. { "-expect-session-miss", &TestConfig::expect_session_miss },
  50. { "-decline-alpn", &TestConfig::decline_alpn },
  51. { "-expect-extended-master-secret",
  52. &TestConfig::expect_extended_master_secret },
  53. { "-implicit-handshake", &TestConfig::implicit_handshake },
  54. { "-handshake-never-done", &TestConfig::handshake_never_done },
  55. { "-use-export-context", &TestConfig::use_export_context },
  56. { "-expect-ticket-renewal", &TestConfig::expect_ticket_renewal },
  57. { "-expect-no-session", &TestConfig::expect_no_session },
  58. { "-use-ticket-callback", &TestConfig::use_ticket_callback },
  59. { "-renew-ticket", &TestConfig::renew_ticket },
  60. { "-enable-client-custom-extension",
  61. &TestConfig::enable_client_custom_extension },
  62. { "-enable-server-custom-extension",
  63. &TestConfig::enable_server_custom_extension },
  64. { "-custom-extension-skip", &TestConfig::custom_extension_skip },
  65. { "-custom-extension-fail-add", &TestConfig::custom_extension_fail_add },
  66. { "-check-close-notify", &TestConfig::check_close_notify },
  67. { "-shim-shuts-down", &TestConfig::shim_shuts_down },
  68. { "-verify-fail", &TestConfig::verify_fail },
  69. { "-verify-peer", &TestConfig::verify_peer },
  70. { "-expect-verify-result", &TestConfig::expect_verify_result },
  71. { "-renegotiate-freely", &TestConfig::renegotiate_freely },
  72. { "-p384-only", &TestConfig::p384_only },
  73. { "-enable-all-curves", &TestConfig::enable_all_curves },
  74. { "-use-sparse-dh-prime", &TestConfig::use_sparse_dh_prime },
  75. { "-use-old-client-cert-callback",
  76. &TestConfig::use_old_client_cert_callback },
  77. { "-use-null-client-ca-list", &TestConfig::use_null_client_ca_list },
  78. { "-peek-then-read", &TestConfig::peek_then_read },
  79. };
  80. const Flag<std::string> kStringFlags[] = {
  81. { "-key-file", &TestConfig::key_file },
  82. { "-cert-file", &TestConfig::cert_file },
  83. { "-expect-server-name", &TestConfig::expected_server_name },
  84. { "-advertise-npn", &TestConfig::advertise_npn },
  85. { "-expect-next-proto", &TestConfig::expected_next_proto },
  86. { "-select-next-proto", &TestConfig::select_next_proto },
  87. { "-host-name", &TestConfig::host_name },
  88. { "-advertise-alpn", &TestConfig::advertise_alpn },
  89. { "-expect-alpn", &TestConfig::expected_alpn },
  90. { "-expect-advertised-alpn", &TestConfig::expected_advertised_alpn },
  91. { "-select-alpn", &TestConfig::select_alpn },
  92. { "-psk", &TestConfig::psk },
  93. { "-psk-identity", &TestConfig::psk_identity },
  94. { "-srtp-profiles", &TestConfig::srtp_profiles },
  95. { "-cipher", &TestConfig::cipher },
  96. { "-export-label", &TestConfig::export_label },
  97. { "-export-context", &TestConfig::export_context },
  98. };
  99. const Flag<std::string> kBase64Flags[] = {
  100. { "-expect-certificate-types", &TestConfig::expected_certificate_types },
  101. };
  102. const Flag<int> kIntFlags[] = {
  103. { "-port", &TestConfig::port },
  104. { "-resume-count", &TestConfig::resume_count },
  105. { "-min-version", &TestConfig::min_version },
  106. { "-max-version", &TestConfig::max_version },
  107. { "-mtu", &TestConfig::mtu },
  108. { "-export-keying-material", &TestConfig::export_keying_material },
  109. { "-expect-total-renegotiations", &TestConfig::expect_total_renegotiations },
  110. { "-max-cert-list", &TestConfig::max_cert_list },
  111. };
  112. } // namespace
  113. bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
  114. for (int i = 0; i < argc; i++) {
  115. bool *bool_field = FindField(out_config, kBoolFlags, argv[i]);
  116. if (bool_field != NULL) {
  117. *bool_field = true;
  118. continue;
  119. }
  120. std::string *string_field = FindField(out_config, kStringFlags, argv[i]);
  121. if (string_field != NULL) {
  122. const char *val;
  123. i++;
  124. if (i >= argc) {
  125. fprintf(stderr, "Missing parameter\n");
  126. return false;
  127. }
  128. /*
  129. * Fix up the -cipher argument. runner uses "DEFAULT:NULL-SHA" to enable
  130. * the NULL-SHA cipher. However in OpenSSL "DEFAULT" permanently switches
  131. * off NULL ciphers, so we use "ALL:NULL-SHA" instead.
  132. */
  133. if (strcmp(argv[i - 1], "-cipher") == 0
  134. && strcmp(argv[i], "DEFAULT:NULL-SHA") == 0)
  135. val = "ALL:NULL-SHA";
  136. else
  137. val = argv[i];
  138. string_field->assign(val);
  139. continue;
  140. }
  141. std::string *base64_field = FindField(out_config, kBase64Flags, argv[i]);
  142. if (base64_field != NULL) {
  143. i++;
  144. if (i >= argc) {
  145. fprintf(stderr, "Missing parameter\n");
  146. return false;
  147. }
  148. std::unique_ptr<uint8_t[]> decoded(new uint8_t[strlen(argv[i])]);
  149. int len = EVP_DecodeBlock(decoded.get(),
  150. reinterpret_cast<const uint8_t *>(argv[i]),
  151. strlen(argv[i]));
  152. if (len < 0) {
  153. fprintf(stderr, "Invalid base64: %s\n", argv[i]);
  154. return false;
  155. }
  156. base64_field->assign(reinterpret_cast<const char *>(decoded.get()), len);
  157. continue;
  158. }
  159. int *int_field = FindField(out_config, kIntFlags, argv[i]);
  160. if (int_field) {
  161. i++;
  162. if (i >= argc) {
  163. fprintf(stderr, "Missing parameter\n");
  164. return false;
  165. }
  166. *int_field = atoi(argv[i]);
  167. continue;
  168. }
  169. fprintf(stderr, "Unknown argument: %s\n", argv[i]);
  170. exit(89);
  171. return false;
  172. }
  173. return true;
  174. }