Maintain SSL_HANDSHAKE lifetime outside of handshake_func.
We currently look up SSL_HANDSHAKE off of ssl->s3->hs everywhere, but
this is a little dangerous. Unlike ssl->s3->tmp, ssl->s3->hs may not be
present. Right now we just know not to call some functions outside the
handshake.
Instead, code which expects to only be called during a handshake should
take an explicit SSL_HANDSHAKE * parameter and can assume it non-NULL.
This replaces the SSL * parameter. Instead, that is looked up from
hs->ssl.
Code which is called in both cases, reads from ssl->s3->hs. Ultimately,
we should get to the point that all direct access of ssl->s3->hs needs
to be NULL-checked.
As a start, manage the lifetime of the ssl->s3->hs in SSL_do_handshake.
This allows the top-level handshake_func hooks to be passed in the
SSL_HANDSHAKE *. Later work will route it through the stack. False Start
is a little wonky, but I think this is cleaner overall.
Change-Id: I26dfeb95f1bc5a0a630b5c442c90c26a6b9e2efe
Reviewed-on: https://boringssl-review.googlesource.com/12236
Reviewed-by: Steven Valdez <svaldez@google.com>
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 aafad33..76a9de0 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -624,7 +624,28 @@
return 1;
}
- return ssl->handshake_func(ssl);
+ /* Set up a new handshake if necessary. */
+ if (ssl->state == SSL_ST_INIT && ssl->s3->hs == NULL) {
+ ssl->s3->hs = ssl_handshake_new(ssl);
+ if (ssl->s3->hs == NULL) {
+ return -1;
+ }
+ }
+
+ /* Run the handshake. */
+ assert(ssl->s3->hs != NULL);
+ int ret = ssl->handshake_func(ssl->s3->hs);
+ if (ret <= 0) {
+ return ret;
+ }
+
+ /* Destroy the handshake object if the handshake has completely finished. */
+ if (!SSL_in_init(ssl)) {
+ ssl_handshake_free(ssl->s3->hs);
+ ssl->s3->hs = NULL;
+ }
+
+ return 1;
}
int SSL_connect(SSL *ssl) {