Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@chromium.org>2015-02-24 09:23:21 +0300
committerAdam Langley <agl@google.com>2015-02-26 00:22:35 +0300
commit6f5c0f4471469f290c91af9b35c6df063f041de2 (patch)
tree56bcf612e5e80792b419c0503c27d822a902f1ce
parent7c21925a10d451ed13ab201e0161dea40b974397 (diff)
Add tests for installing the certificate on the early callback.
Test both asynchronous and synchronous versions. This callback is somewhat different from others. It's NOT called a second time when the handshake is resumed. This appears to be intentional and not a mismerge from the internal patch. The caller is expected to set up any state before resuming the handshake state machine. Also test the early callback returning an error. Change-Id: If5e6eddd7007ea5cdd7533b4238e456106b95cbd Reviewed-on: https://boringssl-review.googlesource.com/3590 Reviewed-by: Adam Langley <agl@google.com>
-rw-r--r--include/openssl/ssl.h3
-rw-r--r--ssl/test/bssl_shim.cc88
-rw-r--r--ssl/test/runner/runner.go20
-rw-r--r--ssl/test/test_config.cc6
-rw-r--r--ssl/test/test_config.h2
5 files changed, 81 insertions, 38 deletions
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index c5645a4c..9cc8d3f2 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -805,7 +805,8 @@ struct ssl_ctx_st {
* before the decision whether to resume a session is made. It may return one
* to continue the handshake or zero to cause the handshake loop to return
* with an error and cause SSL_get_error to return
- * SSL_ERROR_PENDING_CERTIFICATE. */
+ * SSL_ERROR_PENDING_CERTIFICATE. Note: when the handshake loop is resumed, it
+ * will not call the callback a second time. */
int (*select_certificate_cb)(const struct ssl_early_callback_ctx *);
/* quiet_shutdown is true if the connection should not send a close_notify on
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 28846ca5..ad4fa1ad 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -139,39 +139,51 @@ static int SelectCertificateCallback(const struct ssl_early_callback_ctx *ctx) {
const TestConfig *config = GetConfigPtr(ctx->ssl);
GetTestState(ctx->ssl)->early_callback_called = true;
- if (config->expected_server_name.empty()) {
- return 1;
- }
+ if (!config->expected_server_name.empty()) {
+ const uint8_t *extension_data;
+ size_t extension_len;
+ CBS extension, server_name_list, host_name;
+ uint8_t name_type;
+
+ if (!SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
+ &extension_data,
+ &extension_len)) {
+ fprintf(stderr, "Could not find server_name extension.\n");
+ return -1;
+ }
- const uint8_t *extension_data;
- size_t extension_len;
- CBS extension, server_name_list, host_name;
- uint8_t name_type;
+ CBS_init(&extension, extension_data, extension_len);
+ if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
+ CBS_len(&extension) != 0 ||
+ !CBS_get_u8(&server_name_list, &name_type) ||
+ name_type != TLSEXT_NAMETYPE_host_name ||
+ !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
+ CBS_len(&server_name_list) != 0) {
+ fprintf(stderr, "Could not decode server_name extension.\n");
+ return -1;
+ }
- if (!SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
- &extension_data,
- &extension_len)) {
- fprintf(stderr, "Could not find server_name extension.\n");
- return -1;
+ if (!CBS_mem_equal(&host_name,
+ (const uint8_t*)config->expected_server_name.data(),
+ config->expected_server_name.size())) {
+ fprintf(stderr, "Server name mismatch.\n");
+ }
}
- CBS_init(&extension, extension_data, extension_len);
- if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
- CBS_len(&extension) != 0 ||
- !CBS_get_u8(&server_name_list, &name_type) ||
- name_type != TLSEXT_NAMETYPE_host_name ||
- !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
- CBS_len(&server_name_list) != 0) {
- fprintf(stderr, "Could not decode server_name extension.\n");
+ if (config->fail_early_callback) {
return -1;
}
- if (!CBS_mem_equal(&host_name,
- (const uint8_t*)config->expected_server_name.data(),
- config->expected_server_name.size())) {
- fprintf(stderr, "Server name mismatch.\n");
+ // Install the certificate in the early callback.
+ if (config->use_early_callback) {
+ if (config->async) {
+ // Install the certificate asynchronously.
+ return 0;
+ }
+ if (!InstallCertificate(ctx->ssl)) {
+ return -1;
+ }
}
-
return 1;
}
@@ -464,6 +476,9 @@ static bool RetryAsync(SSL *ssl, int ret, BIO *async,
GetTestState(ssl)->session =
std::move(GetTestState(ssl)->pending_session);
return true;
+ case SSL_ERROR_PENDING_CERTIFICATE:
+ // The handshake will resume without a second call to the early callback.
+ return InstallCertificate(ssl);
default:
return false;
}
@@ -492,12 +507,13 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
!SSL_set_mode(ssl.get(), SSL_MODE_SEND_FALLBACK_SCSV)) {
return false;
}
- if (config->async) {
- // TODO(davidben): Also test |s->ctx->client_cert_cb| on the client and
- // |s->ctx->select_certificate_cb| on the server.
- SSL_set_cert_cb(ssl.get(), CertCallback, NULL);
- } else if (!InstallCertificate(ssl.get())) {
- return false;
+ if (!config->use_early_callback) {
+ if (config->async) {
+ // TODO(davidben): Also test |s->ctx->client_cert_cb| on the client.
+ SSL_set_cert_cb(ssl.get(), CertCallback, NULL);
+ } else if (!InstallCertificate(ssl.get())) {
+ return false;
+ }
}
if (config->require_any_client_certificate) {
SSL_set_verify(ssl.get(), SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
@@ -650,6 +666,11 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
return false;
}
+ if (config->is_server && !GetTestState(ssl.get())->early_callback_called) {
+ fprintf(stderr, "early callback not called\n");
+ return false;
+ }
+
if (!config->expected_server_name.empty()) {
const char *server_name =
SSL_get_servername(ssl.get(), TLSEXT_NAMETYPE_host_name);
@@ -658,11 +679,6 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
server_name, config->expected_server_name.c_str());
return false;
}
-
- if (!GetTestState(ssl.get())->early_callback_called) {
- fprintf(stderr, "early callback not called\n");
- return false;
- }
}
if (!config->expected_certificate_types.empty()) {
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 1c844407..40798634 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -780,6 +780,14 @@ var testCases = []testCase{
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
+ {
+ testType: serverTest,
+ name: "FailEarlyCallback",
+ flags: []string{"-fail-early-callback"},
+ shouldFail: true,
+ expectedError: ":CONNECTION_REJECTED:",
+ expectedLocalError: "remote error: access denied",
+ },
}
func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, isResume bool) error {
@@ -1657,6 +1665,18 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
flags: append(flags, "-implicit-handshake"),
resumeSession: true,
})
+ testCases = append(testCases, testCase{
+ protocol: protocol,
+ testType: serverTest,
+ name: "Basic-Server-EarlyCallback" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: maxHandshakeRecordLength,
+ },
+ },
+ flags: append(flags, "-use-early-callback"),
+ resumeSession: true,
+ })
// TLS client auth.
testCases = append(testCases, testCase{
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index afcb1067..4db72b4f 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -73,6 +73,8 @@ const Flag<bool> kBoolFlags[] = {
&TestConfig::enable_signed_cert_timestamps },
{ "-fastradio-padding", &TestConfig::fastradio_padding },
{ "-implicit-handshake", &TestConfig::implicit_handshake },
+ { "-use-early-callback", &TestConfig::use_early_callback },
+ { "-fail-early-callback", &TestConfig::fail_early_callback },
};
const Flag<std::string> kStringFlags[] = {
@@ -138,7 +140,9 @@ TestConfig::TestConfig()
min_version(0),
max_version(0),
mtu(0),
- implicit_handshake(false) {
+ implicit_handshake(false),
+ use_early_callback(false),
+ fail_early_callback(false) {
}
bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 61b25c04..a54fb230 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -68,6 +68,8 @@ struct TestConfig {
int max_version;
int mtu;
bool implicit_handshake;
+ bool use_early_callback;
+ bool fail_early_callback;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);