Fix SSL_clear's interaction with session resumption.
Prior to 87eab4902d1003983079881d3ee8a66ec2eaccc2, due to some
confusions between configuration and connection state, SSL_clear had the
side effect of offering the previously established session on the new
connection.
wpa_supplicant relies on this behavior, so restore it for TLS 1.2 and
below and add a test. (This behavior is largely incompatible with TLS
1.3's post-handshake tickets, so it won't work in 1.3. It'll act as if
we configured an unresumable session instead.)
Change-Id: Iaee8c0afc1cb65c0ab7397435602732b901b1c2d
Reviewed-on: https://boringssl-review.googlesource.com/12632
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@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 47ecd48..eed82b0 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2877,6 +2877,15 @@
}
int SSL_clear(SSL *ssl) {
+ /* In OpenSSL, reusing a client |SSL| with |SSL_clear| causes the previously
+ * established session to be offered the next time around. wpa_supplicant
+ * depends on this behavior, so emulate it. */
+ SSL_SESSION *session = NULL;
+ if (!ssl->server && ssl->s3->established_session != NULL) {
+ session = ssl->s3->established_session;
+ SSL_SESSION_up_ref(session);
+ }
+
/* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
* |SSL_clear| because it is per-connection state rather than configuration
* state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
@@ -2902,6 +2911,7 @@
ssl->method->ssl_free(ssl);
if (!ssl->method->ssl_new(ssl)) {
+ SSL_SESSION_free(session);
return 0;
}
@@ -2909,6 +2919,11 @@
ssl->d1->mtu = mtu;
}
+ if (session != NULL) {
+ SSL_set_session(ssl, session);
+ SSL_SESSION_free(session);
+ }
+
return 1;
}