update master-with-bazel from master branch

This commit is contained in:
BoringSSL Robot
2024-11-13 01:10:06 +00:00
6 changed files with 155 additions and 52 deletions
+3 -3
View File
@@ -2469,9 +2469,9 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in,
// When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a
// 16-byte key name and |iv| points to an IV. The length of the IV consumed must
// match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
// |callback| returns -1 to abort the handshake, 0 if decrypting the ticket
// failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed.
// This may be used to re-key the ticket.
// |callback| returns -1 to abort the handshake, 0 if the ticket key was
// unrecognized, and 1 or 2 on success. If it returns 2, the ticket will be
// renewed. This may be used to re-key the ticket.
//
// WARNING: |callback| wildly breaks the usual return value convention and is
// called in two different modes.
+3
View File
@@ -101,6 +101,9 @@ bool RetryAsync(SSL *ssl, int ret) {
case SSL_ERROR_WANT_CERTIFICATE_VERIFY:
test_state->custom_verify_ready = true;
return true;
case SSL_ERROR_PENDING_TICKET:
test_state->async_ticket_decrypt_ready = true;
return true;
default:
return false;
}
+55 -44
View File
@@ -8574,54 +8574,65 @@ func addExtensionTests() {
resumeSession: true,
expectResumeRejected: true,
})
// Test the ticket callback, with and without renewal.
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "TicketCallback-" + suffix,
config: Config{
MaxVersion: ver.version,
},
resumeSession: true,
flags: []string{"-use-ticket-callback"},
})
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "TicketCallback-Renew-" + suffix,
config: Config{
MaxVersion: ver.version,
Bugs: ProtocolBugs{
ExpectNewTicket: true,
// Test the ticket callbacks.
for _, aeadCallback := range []bool{false, true} {
flag := "-use-ticket-callback"
callbackSuffix := suffix
if aeadCallback {
flag = "-use-ticket-aead-callback"
callbackSuffix += "-AEAD"
}
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "TicketCallback-" + callbackSuffix,
config: Config{
MaxVersion: ver.version,
},
},
flags: []string{"-use-ticket-callback", "-renew-ticket"},
resumeSession: true,
})
resumeSession: true,
flags: []string{flag},
})
// Only the old callback supports renewal.
if !aeadCallback {
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "TicketCallback-Renew-" + callbackSuffix,
config: Config{
MaxVersion: ver.version,
Bugs: ProtocolBugs{
ExpectNewTicket: true,
},
},
flags: []string{flag, "-renew-ticket"},
resumeSession: true,
})
}
// Test that the ticket callback is only called once when everything before
// it in the ClientHello is asynchronous. This corrupts the ticket so
// certificate selection callbacks run.
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "TicketCallback-SingleCall-" + suffix,
config: Config{
MaxVersion: ver.version,
Bugs: ProtocolBugs{
FilterTicket: func(in []byte) ([]byte, error) {
in[len(in)-1] ^= 1
return in, nil
// Test that the ticket callback is only called once when everything before
// it in the ClientHello is asynchronous. This corrupts the ticket so
// certificate selection callbacks run.
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "TicketCallback-SingleCall-" + callbackSuffix,
config: Config{
MaxVersion: ver.version,
Bugs: ProtocolBugs{
FilterTicket: func(in []byte) ([]byte, error) {
in[len(in)-1] ^= 1
return in, nil
},
},
},
},
resumeSession: true,
expectResumeRejected: true,
flags: []string{
"-use-ticket-callback",
"-async",
},
})
resumeSession: true,
expectResumeRejected: true,
flags: []string{
flag,
"-async",
},
})
}
// Resume with various lengths of ticket session id.
if ver.version < VersionTLS13 {
+92 -5
View File
@@ -28,6 +28,7 @@
#include <memory>
#include <type_traits>
#include <openssl/aead.h>
#include <openssl/base64.h>
#include <openssl/hmac.h>
#include <openssl/hpke.h>
@@ -354,7 +355,8 @@ const Flag<TestConfig> *FindFlag(const char *name) {
BoolFlag("-implicit-handshake", &TestConfig::implicit_handshake),
BoolFlag("-use-early-callback", &TestConfig::use_early_callback),
BoolFlag("-fail-early-callback", &TestConfig::fail_early_callback),
BoolFlag("-fail-early-callback-ech-rewind", &TestConfig::fail_early_callback_ech_rewind),
BoolFlag("-fail-early-callback-ech-rewind",
&TestConfig::fail_early_callback_ech_rewind),
BoolFlag("-install-ddos-callback", &TestConfig::install_ddos_callback),
BoolFlag("-fail-ddos-callback", &TestConfig::fail_ddos_callback),
BoolFlag("-fail-cert-callback", &TestConfig::fail_cert_callback),
@@ -375,9 +377,10 @@ const Flag<TestConfig> *FindFlag(const char *name) {
&TestConfig::expect_reject_early_data),
BoolFlag("-expect-no-offer-early-data",
&TestConfig::expect_no_offer_early_data),
BoolFlag("-expect-no-server-name",
&TestConfig::expect_no_server_name),
BoolFlag("-expect-no-server-name", &TestConfig::expect_no_server_name),
BoolFlag("-use-ticket-callback", &TestConfig::use_ticket_callback),
BoolFlag("-use-ticket-aead-callback",
&TestConfig::use_ticket_aead_callback),
BoolFlag("-renew-ticket", &TestConfig::renew_ticket),
BoolFlag("-enable-early-data", &TestConfig::enable_early_data),
Base64Flag("-expect-ocsp-response", &TestConfig::expect_ocsp_response),
@@ -1214,6 +1217,88 @@ static const SSL_PRIVATE_KEY_METHOD g_async_private_key_method = {
AsyncPrivateKeyComplete,
};
static size_t AsyncTicketMaxOverhead(SSL *ssl) {
const EVP_AEAD *aead = EVP_aead_aes_128_gcm_siv();
return EVP_AEAD_max_overhead(aead) + EVP_AEAD_nonce_length(aead);
}
static int AsyncTicketSeal(SSL *ssl, uint8_t *out, size_t *out_len,
size_t max_out_len, const uint8_t *in,
size_t in_len) {
auto out_span = bssl::MakeSpan(out, max_out_len);
// Encrypt the ticket with the all zero key and a random nonce.
static const uint8_t kKey[16] = {0};
const EVP_AEAD *aead = EVP_aead_aes_128_gcm_siv();
size_t nonce_len = EVP_AEAD_nonce_length(aead);
if (out_span.size() < nonce_len) {
return 0;
}
auto nonce = out_span.first(nonce_len);
out_span = out_span.subspan(nonce_len);
RAND_bytes(nonce.data(), nonce.size());
bssl::ScopedEVP_AEAD_CTX ctx;
size_t len;
if (!EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_128_gcm_siv(), kKey,
sizeof(kKey), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr) ||
!EVP_AEAD_CTX_seal(ctx.get(), out_span.data(), &len, out_span.size(),
nonce.data(), nonce.size(), in, in_len,
/*ad=*/nullptr, /*ad_len=*/0)) {
return 0;
}
*out_len = nonce.size() + len;
return 1;
}
static ssl_ticket_aead_result_t AsyncTicketOpen(SSL *ssl, uint8_t *out,
size_t *out_len,
size_t max_out_len,
const uint8_t *in,
size_t in_len) {
auto in_span = bssl::MakeSpan(in, in_len);
const TestConfig *test_config = GetTestConfig(ssl);
TestState *test_state = GetTestState(ssl);
if (test_state->ticket_decrypt_done) {
fprintf(stderr, "AsyncTicketOpen called after completion.\n");
return ssl_ticket_aead_error;
}
if (test_config->renew_ticket) {
fprintf(stderr, "-renew-ticket not supported with async tickets.\n");
return ssl_ticket_aead_error;
}
if (test_config->async && !test_state->async_ticket_decrypt_ready) {
return ssl_ticket_aead_retry;
}
const EVP_AEAD *aead = EVP_aead_aes_128_gcm_siv();
size_t nonce_len = EVP_AEAD_nonce_length(aead);
if (in_span.size() < nonce_len) {
return ssl_ticket_aead_error;
}
auto nonce = in_span.first(nonce_len);
in_span = in_span.subspan(nonce_len);
static const uint8_t kKey[16] = {0};
bssl::ScopedEVP_AEAD_CTX ctx;
if (!EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_128_gcm_siv(), kKey,
sizeof(kKey), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
return ssl_ticket_aead_error;
}
if (!EVP_AEAD_CTX_open(ctx.get(), out, out_len, max_out_len, nonce.data(),
nonce.size(), in_span.data(), in_span.size(),
/*ad=*/nullptr, /*ad_len=*/0)) {
ERR_clear_error();
return ssl_ticket_aead_ignore_ticket;
}
test_state->ticket_decrypt_done = true;
return ssl_ticket_aead_success;
}
static const SSL_TICKET_AEAD_METHOD g_async_ticket_aead_method = {
AsyncTicketMaxOverhead,
AsyncTicketSeal,
AsyncTicketOpen,
};
static bssl::UniquePtr<SSL_CREDENTIAL> CredentialFromConfig(
const TestConfig &config, const CredentialConfig &cred_config, int number) {
bssl::UniquePtr<SSL_CREDENTIAL> cred;
@@ -1758,8 +1843,10 @@ bssl::UniquePtr<SSL_CTX> TestConfig::SetupCtx(SSL_CTX *old_ctx) const {
SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback);
SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
if (use_ticket_callback || handshake_hints) {
// If using handshake hints, always enable the ticket callback, so we can
if (use_ticket_aead_callback) {
SSL_CTX_set_ticket_aead_method(ssl_ctx.get(), &g_async_ticket_aead_method);
} else if (use_ticket_callback || handshake_hints) {
// If using handshake hints, always enable some ticket callback, so we can
// check that hints only mismatch when allowed. The ticket callback also
// uses a constant key, which simplifies the test.
SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx.get(), TicketKeyCallback);
+1
View File
@@ -137,6 +137,7 @@ struct TestConfig {
bool expect_no_offer_early_data = false;
bool expect_no_server_name = false;
bool use_ticket_callback = false;
bool use_ticket_aead_callback = false;
bool renew_ticket = false;
bool enable_early_data = false;
std::string ocsp_response;
+1
View File
@@ -56,6 +56,7 @@ struct TestState {
unsigned private_key_retries = 0;
bool got_new_session = false;
bssl::UniquePtr<SSL_SESSION> new_session;
bool async_ticket_decrypt_ready = false;
bool ticket_decrypt_done = false;
bool alpn_select_done = false;
bool early_callback_ready = false;