summaryrefslogtreecommitdiffstats
path: root/ssl/s3_lib.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-01-10 23:02:28 +0000
committerMatt Caswell <matt@openssl.org>2017-01-30 10:17:00 +0000
commitc7f47786a5e5f68dc33091ffb2a42e51a73de3a1 (patch)
tree6ca73f81c1017d62f50a09cd130fdb013df8b0f4 /ssl/s3_lib.c
parent0386aad1ab472a4059da85131cceca15aab5ebae (diff)
Move state machine knowledge out of the record layer
The record layer was making decisions that should really be left to the state machine around unexpected handshake messages that are received after the initial handshake (i.e. renegotiation related messages). This commit removes that code from the record layer and updates the state machine accordingly. This simplifies the state machine and paves the way for handling other messages post-handshake such as the NewSessionTicket in TLSv1.3. Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2259)
Diffstat (limited to 'ssl/s3_lib.c')
-rw-r--r--ssl/s3_lib.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index ff4a03b147..1655333b13 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3822,7 +3822,7 @@ int ssl3_write(SSL *s, const void *buf, size_t len, size_t *written)
{
clear_sys_error();
if (s->s3->renegotiate)
- ssl3_renegotiate_check(s);
+ ssl3_renegotiate_check(s, 0);
return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len,
written);
@@ -3835,7 +3835,7 @@ static int ssl3_read_internal(SSL *s, void *buf, size_t len, int peek,
clear_sys_error();
if (s->s3->renegotiate)
- ssl3_renegotiate_check(s);
+ ssl3_renegotiate_check(s, 0);
s->s3->in_read_app_data = 1;
ret =
s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, NULL, buf, len,
@@ -3878,14 +3878,22 @@ int ssl3_renegotiate(SSL *s)
return (1);
}
-int ssl3_renegotiate_check(SSL *s)
+/*
+ * Check if we are waiting to do a renegotiation and if so whether now is a
+ * good time to do it. If |initok| is true then we are being called from inside
+ * the state machine so ignore the result of SSL_in_init(s). Otherwise we
+ * should not do a renegotiation if SSL_in_init(s) is true. Returns 1 if we
+ * should do a renegotiation now and sets up the state machine for it. Otherwise
+ * returns 0.
+ */
+int ssl3_renegotiate_check(SSL *s, int initok)
{
int ret = 0;
if (s->s3->renegotiate) {
if (!RECORD_LAYER_read_pending(&s->rlayer)
&& !RECORD_LAYER_write_pending(&s->rlayer)
- && !SSL_in_init(s)) {
+ && (initok || !SSL_in_init(s))) {
/*
* if we are the server, and we have sent a 'RENEGOTIATE'
* message, we need to set the state machine into the renegotiate
@@ -3898,7 +3906,7 @@ int ssl3_renegotiate_check(SSL *s)
ret = 1;
}
}
- return (ret);
+ return ret;
}
/*