Add a test for the ticket callback.
Change-Id: I7b2a4f617bd8d49c86fdaaf45bf67e0170bbd44f
Reviewed-on: https://boringssl-review.googlesource.com/5230
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index e8575a5..f324d39 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -38,7 +38,10 @@
#include <openssl/bio.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
+#include <openssl/cipher.h>
#include <openssl/err.h>
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <memory>
@@ -443,6 +446,30 @@
return 1;
}
+static int TicketKeyCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
+ EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
+ int encrypt) {
+ // This is just test code, so use the all-zeros key.
+ static const uint8_t kZeros[16] = {0};
+
+ if (encrypt) {
+ memcpy(key_name, kZeros, sizeof(kZeros));
+ RAND_bytes(iv, 16);
+ } else if (memcmp(key_name, kZeros, 16) != 0) {
+ return 0;
+ }
+
+ if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
+ !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
+ return -1;
+ }
+
+ if (!encrypt) {
+ return GetConfigPtr(ssl)->renew_ticket ? 2 : 1;
+ }
+ return 1;
+}
+
// Connect returns a new socket connected to localhost on |port| or -1 on
// error.
static int Connect(uint16_t port) {
@@ -548,6 +575,10 @@
SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback);
SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
+ if (config->use_ticket_callback) {
+ SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx.get(), TicketKeyCallback);
+ }
+
return ssl_ctx;
}
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index 928c2b2..c7ccf80 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -720,6 +720,10 @@
// EmptyCertificateList, if true, causes the server to send an empty
// certificate list in the Certificate message.
EmptyCertificateList bool
+
+ // ExpectNewTicket, if true, causes the client to abort if it does not
+ // receive a new ticket.
+ ExpectNewTicket bool
}
func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index a950313..00bff0e 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -786,6 +786,9 @@
}
if !hs.serverHello.ticketSupported {
+ if c.config.Bugs.ExpectNewTicket {
+ return errors.New("tls: expected new ticket")
+ }
if hs.session == nil && len(hs.serverHello.sessionId) > 0 {
session.sessionId = hs.serverHello.sessionId
hs.session = session
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 3506e05..5c66741 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -2841,6 +2841,24 @@
resumeSession: true,
expectResumeRejected: true,
})
+ // Test the ticket callback, with and without renewal.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback",
+ resumeSession: true,
+ flags: []string{"-use-ticket-callback"},
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback-Renew",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectNewTicket: true,
+ },
+ },
+ flags: []string{"-use-ticket-callback", "-renew-ticket"},
+ resumeSession: true,
+ })
// Resume with an oversized session id.
testCases = append(testCases, testCase{
testType: serverTest,
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 00dec32..b4da5ce 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -85,6 +85,8 @@
{ "-use-async-private-key", &TestConfig::use_async_private_key },
{ "-expect-ticket-renewal", &TestConfig::expect_ticket_renewal },
{ "-expect-no-session", &TestConfig::expect_no_session },
+ { "-use-ticket-callback", &TestConfig::use_ticket_callback },
+ { "-renew-ticket", &TestConfig::renew_ticket },
};
const Flag<std::string> kStringFlags[] = {
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index e7230a7..6e0b2e4 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -82,6 +82,8 @@
bool use_async_private_key = false;
bool expect_ticket_renewal = false;
bool expect_no_session = false;
+ bool use_ticket_callback = false;
+ bool renew_ticket = false;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);