Improve TestConfig flags for initial and resumption connections.

Change-Id: I97a2920a08f995ea70425ad9126f1dced067f2a4
Reviewed-on: https://boringssl-review.googlesource.com/16084
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
Steven Valdez 2017-05-09 12:12:58 -04:00 committed by CQ bot account: commit-bot@chromium.org
parent 93731d9dd4
commit 873ebc9783
4 changed files with 117 additions and 85 deletions

View File

@ -60,6 +60,7 @@ OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
#include <vector>
#include "../../crypto/internal.h"
#include "../internal.h"
#include "async_bio.h"
#include "packeted_bio.h"
#include "test_config.h"
@ -754,10 +755,6 @@ static int AlpnSelectCallback(SSL* ssl, const uint8_t** out, uint8_t* outlen,
*out = (const uint8_t*)config->select_alpn.data();
*outlen = config->select_alpn.size();
if (GetTestState(ssl)->is_resume && config->select_resume_alpn.size() > 0) {
*out = (const uint8_t*)config->select_resume_alpn.data();
*outlen = config->select_resume_alpn.size();
}
return SSL_TLSEXT_ERR_OK;
}
@ -1028,7 +1025,17 @@ class SocketCloser {
const int sock_;
};
static bssl::UniquePtr<SSL_CTX> SetupCtx(const TestConfig *config) {
static void ssl_ctx_add_session(SSL_SESSION *session, void *void_param) {
SSL_SESSION *new_session = SSL_SESSION_dup(
session, SSL_SESSION_INCLUDE_NONAUTH | SSL_SESSION_INCLUDE_TICKET);
if (new_session != nullptr) {
SSL_CTX_add_session((SSL_CTX *)void_param, new_session);
}
SSL_SESSION_free(new_session);
}
static bssl::UniquePtr<SSL_CTX> SetupCtx(SSL_CTX *old_ctx,
const TestConfig *config) {
bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(
config->is_dtls ? DTLS_method() : TLS_method()));
if (!ssl_ctx) {
@ -1076,8 +1083,7 @@ static bssl::UniquePtr<SSL_CTX> SetupCtx(const TestConfig *config) {
NULL);
}
if (!config->select_alpn.empty() || !config->select_resume_alpn.empty() ||
config->decline_alpn) {
if (!config->select_alpn.empty() || config->decline_alpn) {
SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
}
@ -1166,6 +1172,16 @@ static bssl::UniquePtr<SSL_CTX> SetupCtx(const TestConfig *config) {
}
}
if (old_ctx) {
uint8_t keys[48];
if (!SSL_CTX_get_tlsext_ticket_keys(old_ctx, &keys, sizeof(keys)) ||
!SSL_CTX_set_tlsext_ticket_keys(ssl_ctx.get(), keys, sizeof(keys))) {
return nullptr;
}
lh_SSL_SESSION_doall_arg(old_ctx->sessions, ssl_ctx_add_session,
ssl_ctx.get());
}
return ssl_ctx;
}
@ -1410,22 +1426,13 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
}
}
std::string expected_alpn = config->expected_alpn;
if (is_resume && !config->expected_resume_alpn.empty()) {
expected_alpn = config->expected_resume_alpn;
}
bool expect_no_alpn = (!is_resume && config->expect_no_alpn) ||
(is_resume && config->expect_no_resume_alpn);
if (expect_no_alpn) {
expected_alpn.clear();
}
if (!expected_alpn.empty() || expect_no_alpn) {
if (!config->is_server) {
const uint8_t *alpn_proto;
unsigned alpn_proto_len;
SSL_get0_alpn_selected(ssl, &alpn_proto, &alpn_proto_len);
if (alpn_proto_len != expected_alpn.size() ||
OPENSSL_memcmp(alpn_proto, expected_alpn.data(), alpn_proto_len) != 0) {
if (alpn_proto_len != config->expected_alpn.size() ||
OPENSSL_memcmp(alpn_proto, config->expected_alpn.data(),
alpn_proto_len) != 0) {
fprintf(stderr, "negotiated alpn proto mismatch\n");
return false;
}
@ -1506,15 +1513,11 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
return false;
}
int expect_curve_id = config->expect_curve_id;
if (is_resume && config->expect_resume_curve_id != 0) {
expect_curve_id = config->expect_resume_curve_id;
}
if (expect_curve_id != 0) {
if (config->expect_curve_id != 0) {
uint16_t curve_id = SSL_get_curve_id(ssl);
if (static_cast<uint16_t>(expect_curve_id) != curve_id) {
if (static_cast<uint16_t>(config->expect_curve_id) != curve_id) {
fprintf(stderr, "curve_id was %04x, wanted %04x\n", curve_id,
static_cast<uint16_t>(expect_curve_id));
static_cast<uint16_t>(config->expect_curve_id));
return false;
}
}
@ -1635,10 +1638,6 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session,
SSL_CTX *ssl_ctx, const TestConfig *config,
bool is_resume, SSL_SESSION *session) {
if (is_resume && config->enable_resume_early_data) {
SSL_CTX_set_early_data_enabled(ssl_ctx, 1);
}
bssl::UniquePtr<SSL> ssl(SSL_new(ssl_ctx));
if (!ssl) {
return false;
@ -2130,8 +2129,9 @@ int main(int argc, char **argv) {
return 1;
}
TestConfig config;
if (!ParseConfig(argc - 1, argv + 1, &config)) {
TestConfig initial_config, resume_config;
if (!ParseConfig(argc - 1, argv + 1, false, &initial_config) ||
!ParseConfig(argc - 1, argv + 1, true, &resume_config)) {
return Usage(argv[0]);
}
@ -2142,30 +2142,33 @@ int main(int argc, char **argv) {
g_clock.tv_sec = 1234;
g_clock.tv_usec = 1234;
bssl::UniquePtr<SSL_CTX> ssl_ctx = SetupCtx(&config);
if (!ssl_ctx) {
ERR_print_errors_fp(stderr);
return 1;
}
bssl::UniquePtr<SSL_CTX> ssl_ctx;
bssl::UniquePtr<SSL_SESSION> session;
for (int i = 0; i < config.resume_count + 1; i++) {
for (int i = 0; i < initial_config.resume_count + 1; i++) {
bool is_resume = i > 0;
if (is_resume && !config.is_server && !session) {
TestConfig *config = is_resume ? &resume_config : &initial_config;
ssl_ctx = SetupCtx(ssl_ctx.get(), config);
if (!ssl_ctx) {
ERR_print_errors_fp(stderr);
return 1;
}
if (is_resume && !initial_config.is_server && !session) {
fprintf(stderr, "No session to offer.\n");
return 1;
}
bssl::UniquePtr<SSL_SESSION> offer_session = std::move(session);
if (!DoExchange(&session, ssl_ctx.get(), &config, is_resume,
if (!DoExchange(&session, ssl_ctx.get(), config, is_resume,
offer_session.get())) {
fprintf(stderr, "Connection %d failed.\n", i + 1);
ERR_print_errors_fp(stderr);
return 1;
}
if (config.resumption_delay != 0) {
g_clock.tv_sec += config.resumption_delay;
if (config->resumption_delay != 0) {
g_clock.tv_sec += config->resumption_delay;
}
}

View File

@ -1732,6 +1732,7 @@ func addBasicTests() {
"-false-start",
"-handshake-never-done",
"-advertise-alpn", "\x03foo",
"-expect-alpn", "foo",
},
shimWritesFirst: true,
shouldFail: true,
@ -1937,6 +1938,7 @@ func addBasicTests() {
"-false-start",
"-handshake-never-done",
"-advertise-alpn", "\x03foo",
"-expect-alpn", "foo",
},
shimWritesFirst: true,
shouldFail: true,
@ -4143,6 +4145,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) {
flags: []string{
"-false-start",
"-advertise-alpn", "\x03foo",
"-expect-alpn", "foo",
},
shimWritesFirst: true,
resumeSession: true,
@ -5001,6 +5004,7 @@ func addExtensionTests() {
flags: []string{
"-advertise-alpn", "\x03foo\x03bar",
"-allow-unknown-alpn-protos",
"-expect-alpn", "baz",
},
})
testCases = append(testCases, testCase{
@ -8011,6 +8015,7 @@ func addExportKeyingMaterialTests() {
flags: []string{
"-false-start",
"-advertise-alpn", "\x03foo",
"-expect-alpn", "foo",
},
shimWritesFirst: true,
exportKeyingMaterial: 1024,
@ -8674,8 +8679,8 @@ func addCurveTests() {
CurvePreferences: []CurveID{CurveP256},
},
flags: []string{
"-expect-curve-id", strconv.Itoa(int(CurveX25519)),
"-expect-resume-curve-id", strconv.Itoa(int(CurveP256)),
"-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)),
"-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)),
},
resumeSession: true,
})
@ -8691,8 +8696,8 @@ func addCurveTests() {
CurvePreferences: []CurveID{CurveP256},
},
flags: []string{
"-expect-curve-id", strconv.Itoa(int(CurveX25519)),
"-expect-resume-curve-id", strconv.Itoa(int(CurveP256)),
"-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)),
"-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)),
},
resumeSession: true,
})
@ -10398,8 +10403,8 @@ func addTLS13HandshakeTests() {
"-enable-early-data",
"-expect-early-data-info",
"-expect-reject-early-data",
"-expect-alpn", "foo",
"-expect-resume-alpn", "bar",
"-on-initial-expect-alpn", "foo",
"-on-resume-expect-alpn", "bar",
},
})
@ -10423,8 +10428,8 @@ func addTLS13HandshakeTests() {
"-enable-early-data",
"-expect-early-data-info",
"-expect-reject-early-data",
"-expect-no-alpn",
"-expect-resume-alpn", "foo",
"-on-initial-expect-alpn", "",
"-on-resume-expect-alpn", "foo",
},
})
@ -10448,8 +10453,8 @@ func addTLS13HandshakeTests() {
"-enable-early-data",
"-expect-early-data-info",
"-expect-reject-early-data",
"-expect-alpn", "foo",
"-expect-no-resume-alpn",
"-on-initial-expect-alpn", "foo",
"-on-resume-expect-alpn", "",
},
})
@ -10477,6 +10482,8 @@ func addTLS13HandshakeTests() {
"-advertise-alpn", "\x03foo\x03bar",
"-enable-early-data",
"-expect-early-data-info",
"-on-initial-expect-alpn", "foo",
"-on-resume-expect-alpn", "bar",
},
shouldFail: true,
expectedError: ":ALPN_MISMATCH_ON_EARLY_DATA:",
@ -10499,7 +10506,7 @@ func addTLS13HandshakeTests() {
},
resumeSession: true,
flags: []string{
"-enable-resume-early-data",
"-on-resume-enable-early-data",
"-expect-reject-early-data",
},
})
@ -10524,8 +10531,8 @@ func addTLS13HandshakeTests() {
resumeSession: true,
flags: []string{
"-enable-early-data",
"-select-alpn", "",
"-select-resume-alpn", "foo",
"-on-initial-select-alpn", "",
"-on-resume-select-alpn", "foo",
},
})
@ -10549,8 +10556,8 @@ func addTLS13HandshakeTests() {
resumeSession: true,
flags: []string{
"-enable-early-data",
"-select-alpn", "foo",
"-select-resume-alpn", "",
"-on-initial-select-alpn", "foo",
"-on-resume-select-alpn", "",
},
})
@ -10573,8 +10580,8 @@ func addTLS13HandshakeTests() {
resumeSession: true,
flags: []string{
"-enable-early-data",
"-select-alpn", "foo",
"-select-resume-alpn", "bar",
"-on-initial-select-alpn", "foo",
"-on-resume-select-alpn", "bar",
},
})
@ -11170,6 +11177,7 @@ func addExtraHandshakeTests() {
"-handshake-twice",
"-false-start",
"-advertise-alpn", "\x03foo",
"-expect-alpn", "foo",
},
shimWritesFirst: true,
shouldFail: true,

View File

@ -85,7 +85,6 @@ const Flag<bool> kBoolFlags[] = {
{ "-use-ticket-callback", &TestConfig::use_ticket_callback },
{ "-renew-ticket", &TestConfig::renew_ticket },
{ "-enable-early-data", &TestConfig::enable_early_data },
{ "-enable-resume-early-data", &TestConfig::enable_resume_early_data },
{ "-enable-client-custom-extension",
&TestConfig::enable_client_custom_extension },
{ "-enable-server-custom-extension",
@ -125,8 +124,6 @@ const Flag<bool> kBoolFlags[] = {
{ "-expect-no-session-id", &TestConfig::expect_no_session_id },
{ "-expect-accept-early-data", &TestConfig::expect_accept_early_data },
{ "-expect-reject-early-data", &TestConfig::expect_reject_early_data },
{ "-expect-no-alpn", &TestConfig::expect_no_alpn },
{ "-expect-no-resume-alpn", &TestConfig::expect_no_resume_alpn },
{ "-no-op-extra-handshake", &TestConfig::no_op_extra_handshake },
{ "-handshake-twice", &TestConfig::handshake_twice },
{ "-allow-unknown-alpn-protos", &TestConfig::allow_unknown_alpn_protos },
@ -145,10 +142,8 @@ const Flag<std::string> kStringFlags[] = {
{ "-host-name", &TestConfig::host_name },
{ "-advertise-alpn", &TestConfig::advertise_alpn },
{ "-expect-alpn", &TestConfig::expected_alpn },
{ "-expect-resume-alpn", &TestConfig::expected_resume_alpn },
{ "-expect-advertised-alpn", &TestConfig::expected_advertised_alpn },
{ "-select-alpn", &TestConfig::select_alpn },
{ "-select-resume-alpn", &TestConfig::select_resume_alpn },
{ "-psk", &TestConfig::psk },
{ "-psk-identity", &TestConfig::psk_identity },
{ "-srtp-profiles", &TestConfig::srtp_profiles },
@ -182,7 +177,6 @@ const Flag<int> kIntFlags[] = {
{ "-expect-peer-signature-algorithm",
&TestConfig::expect_peer_signature_algorithm },
{ "-expect-curve-id", &TestConfig::expect_curve_id },
{ "-expect-resume-curve-id", &TestConfig::expect_resume_curve_id },
{ "-initial-timeout-duration-ms", &TestConfig::initial_timeout_duration_ms },
{ "-max-cert-list", &TestConfig::max_cert_list },
{ "-expect-cipher-aes", &TestConfig::expect_cipher_aes },
@ -198,28 +192,54 @@ const Flag<std::vector<int>> kIntVectorFlags[] = {
{ "-verify-prefs", &TestConfig::verify_prefs },
};
const char kInit[] = "-on-initial";
const char kResume[] = "-on-resume";
} // namespace
bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
bool ParseConfig(int argc, char **argv, bool is_resume,
TestConfig *out_config) {
for (int i = 0; i < argc; i++) {
bool *bool_field = FindField(out_config, kBoolFlags, argv[i]);
bool skip = false;
char *flag = argv[i];
const char *prefix = is_resume ? kResume : kInit;
const char *opposite = is_resume ? kInit : kResume;
if (strncmp(flag, prefix, strlen(prefix)) == 0) {
flag = flag + strlen(prefix);
for (int j = 0; j < argc; j++) {
if (strcmp(argv[j], flag) == 0) {
fprintf(stderr, "Can't use default and prefixed arguments: %s\n",
flag);
return false;
}
}
} else if (strncmp(flag, opposite, strlen(opposite)) == 0) {
flag = flag + strlen(opposite);
skip = true;
}
bool *bool_field = FindField(out_config, kBoolFlags, flag);
if (bool_field != NULL) {
*bool_field = true;
if (!skip) {
*bool_field = true;
}
continue;
}
std::string *string_field = FindField(out_config, kStringFlags, argv[i]);
std::string *string_field = FindField(out_config, kStringFlags, flag);
if (string_field != NULL) {
i++;
if (i >= argc) {
fprintf(stderr, "Missing parameter\n");
return false;
}
string_field->assign(argv[i]);
if (!skip) {
string_field->assign(argv[i]);
}
continue;
}
std::string *base64_field = FindField(out_config, kBase64Flags, argv[i]);
std::string *base64_field = FindField(out_config, kBase64Flags, flag);
if (base64_field != NULL) {
i++;
if (i >= argc) {
@ -238,23 +258,28 @@ bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
fprintf(stderr, "Invalid base64: %s\n", argv[i]);
return false;
}
base64_field->assign(reinterpret_cast<const char *>(decoded.get()), len);
if (!skip) {
base64_field->assign(reinterpret_cast<const char *>(decoded.get()),
len);
}
continue;
}
int *int_field = FindField(out_config, kIntFlags, argv[i]);
int *int_field = FindField(out_config, kIntFlags, flag);
if (int_field) {
i++;
if (i >= argc) {
fprintf(stderr, "Missing parameter\n");
return false;
}
*int_field = atoi(argv[i]);
if (!skip) {
*int_field = atoi(argv[i]);
}
continue;
}
std::vector<int> *int_vector_field =
FindField(out_config, kIntVectorFlags, argv[i]);
FindField(out_config, kIntVectorFlags, flag);
if (int_vector_field) {
i++;
if (i >= argc) {
@ -263,11 +288,13 @@ bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
}
// Each instance of the flag adds to the list.
int_vector_field->push_back(atoi(argv[i]));
if (!skip) {
int_vector_field->push_back(atoi(argv[i]));
}
continue;
}
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
fprintf(stderr, "Unknown argument: %s\n", flag);
return false;
}

View File

@ -53,12 +53,8 @@ struct TestConfig {
std::string host_name;
std::string advertise_alpn;
std::string expected_alpn;
std::string expected_resume_alpn;
bool expect_no_alpn = false;
bool expect_no_resume_alpn = false;
std::string expected_advertised_alpn;
std::string select_alpn;
std::string select_resume_alpn;
bool decline_alpn = false;
bool expect_session_miss = false;
bool expect_extended_master_secret = false;
@ -94,7 +90,6 @@ struct TestConfig {
bool use_ticket_callback = false;
bool renew_ticket = false;
bool enable_early_data = false;
bool enable_resume_early_data = false;
bool enable_client_custom_extension = false;
bool enable_server_custom_extension = false;
bool custom_extension_skip = false;
@ -114,7 +109,6 @@ struct TestConfig {
bool p384_only = false;
bool enable_all_curves = false;
int expect_curve_id = 0;
int expect_resume_curve_id = 0;
bool use_old_client_cert_callback = false;
int initial_timeout_duration_ms = 0;
std::string use_client_ca_list;
@ -147,7 +141,7 @@ struct TestConfig {
bool enable_ed25519 = false;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);
bool ParseConfig(int argc, char **argv, bool is_resume, TestConfig *out_config);
#endif // HEADER_TEST_CONFIG