Add SSL_send_fatal_alert.
WebRTC want to be able to send a random alert. Add an API for this.
Change-Id: Id3113d68f25748729fd9e9a91dbbfa93eead12c3
Reviewed-on: https://boringssl-review.googlesource.com/8950
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 8328421..2608d87 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -737,6 +737,20 @@
return ssl->s3->recv_shutdown == ssl_shutdown_close_notify;
}
+int SSL_send_fatal_alert(SSL *ssl, uint8_t alert) {
+ if (ssl->s3->alert_dispatch) {
+ if (ssl->s3->send_alert[0] != SSL3_AL_FATAL ||
+ ssl->s3->send_alert[1] != alert) {
+ /* We are already attempting to write a different alert. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
+ return -1;
+ }
+ return ssl->method->dispatch_alert(ssl);
+ }
+
+ return ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+}
+
int SSL_get_error(const SSL *ssl, int ret_code) {
int reason;
uint32_t err;
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index edf0fe0..dd7d3a5 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -1017,6 +1017,17 @@
return ret;
}
+// DoSendFatalAlert calls |SSL_send_fatal_alert|, resolving any asynchronous
+// operations. It returns the result of the final |SSL_send_fatal_alert| call.
+static int DoSendFatalAlert(SSL *ssl, uint8_t alert) {
+ const TestConfig *config = GetTestConfig(ssl);
+ int ret;
+ do {
+ ret = SSL_send_fatal_alert(ssl, alert);
+ } while (config->async && RetryAsync(ssl, ret));
+ return ret;
+}
+
// CheckHandshakeProperties checks, immediately after |ssl| completes its
// initial handshake (or False Starts), whether all the properties are
// consistent with the test configuration and invariants.
@@ -1472,6 +1483,13 @@
}
}
+ if (config->send_alert) {
+ if (DoSendFatalAlert(ssl.get(), SSL_AD_DECOMPRESSION_FAILURE) < 0) {
+ return false;
+ }
+ return true;
+ }
+
if (config->write_different_record_sizes) {
if (config->is_dtls) {
fprintf(stderr, "write_different_record_sizes not supported for DTLS\n");
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index f8cb4d9..8ad9962 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -3335,6 +3335,14 @@
})
}
+ tests = append(tests, testCase{
+ name: "ShimSendAlert",
+ flags: []string{"-send-alert"},
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedLocalError: "remote error: decompression failure",
+ })
+
if config.protocol == tls {
tests = append(tests, testCase{
name: "Renegotiate-Client",
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index d242f7a..2fa1f17 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -104,6 +104,7 @@
{ "-use-old-client-cert-callback",
&TestConfig::use_old_client_cert_callback },
{ "-use-null-client-ca-list", &TestConfig::use_null_client_ca_list },
+ { "-send-alert", &TestConfig::send_alert },
};
const Flag<std::string> kStringFlags[] = {
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 690fbe7..f6a1f12 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -112,6 +112,7 @@
bool use_old_client_cert_callback = false;
int initial_timeout_duration_ms = 0;
bool use_null_client_ca_list = false;
+ bool send_alert = false;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);