SSL_export_keying_material should work in half-RTT.
QUIC will need to derive keys at this point. This also smooths over a
part of the server 0-RTT abstraction. Like with False Start, the SSL
object is largely in a functional state at this point.
Bug: 221
Change-Id: I4207d8cb1273a1156e728a7bff3943cc2c69e288
Reviewed-on: https://boringssl-review.googlesource.com/24224
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/err/ssl.errordata b/crypto/err/ssl.errordata
index f5c2873..58c9115 100644
--- a/crypto/err/ssl.errordata
+++ b/crypto/err/ssl.errordata
@@ -65,6 +65,7 @@
SSL,152,FRAGMENT_MISMATCH
SSL,153,GOT_NEXT_PROTO_WITHOUT_EXTENSION
SSL,154,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
+SSL,284,HANDSHAKE_NOT_COMPLETE
SSL,155,HTTPS_PROXY_REQUEST
SSL,156,HTTP_REQUEST
SSL,157,INAPPROPRIATE_FALLBACK
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 8dad6a4..066390b 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -4569,6 +4569,7 @@
#define SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE 281
#define SSL_R_EMPTY_HELLO_RETRY_REQUEST 282
#define SSL_R_EARLY_DATA_NOT_IN_USE 283
+#define SSL_R_HANDSHAKE_NOT_COMPLETE 284
#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
diff --git a/ssl/t1_enc.cc b/ssl/t1_enc.cc
index 4e81fe8..6b5447d 100644
--- a/ssl/t1_enc.cc
+++ b/ssl/t1_enc.cc
@@ -458,11 +458,16 @@
const uint8_t *context, size_t context_len,
int use_context) {
if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE);
return 0;
}
- // Exporters may not be used in the middle of a renegotiation.
- if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
+ // Exporters may be used in False Start and server 0-RTT, where the handshake
+ // has progressed enough. Otherwise, they may not be used during a handshake.
+ if (SSL_in_init(ssl) &&
+ !SSL_in_false_start(ssl) &&
+ !(SSL_is_server(ssl) && SSL_in_early_data(ssl))) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE);
return 0;
}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index fbd016a..4cfce26 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -9070,6 +9070,9 @@
config: Config{
MaxVersion: vers.version,
},
+ // Test the exporter in both initial and resumption
+ // handshakes.
+ resumeSession: true,
tls13Variant: vers.tls13Variant,
exportKeyingMaterial: 1024,
exportLabel: "label",
@@ -9106,6 +9109,28 @@
})
if vers.version >= VersionTLS13 {
+ // Test the exporters do not work while the client is
+ // sending 0-RTT data.
+ testCases = append(testCases, testCase{
+ name: "NoEarlyKeyingMaterial-Client-InEarlyData-" + vers.name,
+ config: Config{
+ MaxVersion: vers.version,
+ MaxEarlyDataSize: 16384,
+ },
+ resumeSession: true,
+ tls13Variant: vers.tls13Variant,
+ flags: []string{
+ "-enable-early-data",
+ "-expect-ticket-supports-early-data",
+ "-expect-accept-early-data",
+ "-on-resume-export-keying-material", "1024",
+ "-on-resume-export-label", "label",
+ "-on-resume-export-context", "context",
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_NOT_COMPLETE:",
+ })
+
// Test the early exporter works while the client is
// sending 0-RTT data. This data arrives during the
// server handshake, so we test it with ProtocolBugs.
@@ -9211,10 +9236,30 @@
expectedError: ":EARLY_DATA_NOT_IN_USE:",
})
- // Test the early exporter works on the server.
+ // Test the normal exporter on the server in half-RTT.
testCases = append(testCases, testCase{
testType: serverTest,
- name: "ExportEarlyKeyingMaterial-Server-" + vers.name,
+ name: "ExportKeyingMaterial-Server-HalfRTT-" + vers.name,
+ config: Config{
+ MaxVersion: vers.version,
+ Bugs: ProtocolBugs{
+ SendEarlyData: [][]byte{},
+ ExpectEarlyDataAccepted: true,
+ },
+ },
+ tls13Variant: vers.tls13Variant,
+ resumeSession: true,
+ exportKeyingMaterial: 1024,
+ exportLabel: "label",
+ exportContext: "context",
+ useExportContext: true,
+ flags: []string{"-enable-early-data"},
+ })
+
+ // Test the early exporter works on the server in half-RTT.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "ExportEarlyKeyingMaterial-Server-HalfRTT-" + vers.name,
config: Config{
MaxVersion: vers.version,
Bugs: ProtocolBugs{