Skip to content

Comments

Fix SSL_key_update() problems#16077

Closed
mattcaswell wants to merge 2 commits intoopenssl:masterfrom
mattcaswell:key-update-read
Closed

Fix SSL_key_update() problems#16077
mattcaswell wants to merge 2 commits intoopenssl:masterfrom
mattcaswell:key-update-read

Conversation

@mattcaswell
Copy link
Member

This contains 2 fixes affecting SSL_key_update():

  • Don't reset the packet pointer in ssl3_setup_read_buffer

Sometimes this function gets called when the buffers have already been
set up. If there is already a partial packet in the read buffer then the
packet pointer will be set to an incorrect value. The packet pointer already
gets reset to the correct value when we first read a packet anyway, so we
don't also need to do it in ssl3_setup_read_buffer.

  • Disallow SSL_key_update() if there are writes pending

If an application is halfway through writing application data it should
not be allowed to attempt an SSL_key_update() operation. Instead the
SSL_write() operation should be completed.

The former issue can result in a "bad record mac" problem if a partial record read occurs around the same time as a key update.

Fixes #13729
Fixes #12485

PR #16021 will provide tests for these scenarios.

This should also be applied to 1.1.1, but I will wait until this is approved to create a PR there since it requires some minor adjustment there.

Sometimes this function gets called when the buffers have already been
set up. If there is already a partial packet in the read buffer then the
packet pointer will be set to an incorrect value. The packet pointer already
gets reset to the correct value when we first read a packet anyway, so we
don't also need to do it in ssl3_setup_read_buffer.

Fixes openssl#13729
If an application is halfway through writing application data it should
not be allowed to attempt an SSL_key_update() operation. Instead the
SSL_write() operation should be completed.

Fixes openssl#12485
@mattcaswell mattcaswell added branch: master Applies to master branch approval: review pending This pull request needs review by a committer labels Jul 14, 2021
@t8m t8m added approval: done This pull request has the required number of approvals triaged: bug The issue/pr is/fixes a bug and removed approval: review pending This pull request needs review by a committer labels Jul 14, 2021
Copy link
Contributor

@kaduk kaduk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Don't reset the packet pointer in ssl3_setup_read_buffer
    Sometimes this function gets called when the buffers have already been
    set up. If there is already a partial packet in the read buffer then the
    packet pointer will be set to an incorrect value. The packet pointer already
    gets reset to the correct value when we first read a packet anyway, so we
    don't also need to do it in ssl3_setup_read_buffer.

The main initialization of s->rlayer.packet in ssl3_read_n() seems to only occur in the !extend case; in the extend case we seem to memmove from the current packet value before updating it. I guess it would be a programming error to call the "extend" case without a preceding "non-extend" case, so maybe that's good enough.

(Also, the comment at the top of the body of ssl3_read_n() refers to s->packet and s->packet_length, which seems out of date with respect to the RECORD_LAYER abstraction.)

return 0;
}

if (RECORD_LAYER_write_pending(&s->rlayer)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, should the check in SSL_new_session_ticket() use RECORD_LAYER_write_pending() instead of peeking into s->rlayer.wbuf[0].left?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It probably should (different PR though)

@hou2gou
Copy link
Contributor

hou2gou commented Jul 15, 2021

(Also, the comment at the top of the body of ssl3_read_n() refers to s->packet and s->packet_length, which seems out of date with respect to the RECORD_LAYER abstraction.) The following comments have the same problem.

if (more > 0) {
/* now s->packet_length == SSL3_RT_HEADER_LENGTH */
rret = ssl3_read_n(s, more, more, 1, 0, &n);
if (rret <= 0)
return rret; /* error or non-blocking io */
}
/* set state for later operations */
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
/*
* At this point, s->packet_length == SSL3_RT_HEADER_LENGTH
* + thisrr->length, or s->packet_length == SSL2_RT_HEADER_LENGTH
* + thisrr->length and we have that many bytes in s->packet
*/
if (thisrr->rec_version == SSL2_VERSION) {

@mattcaswell
Copy link
Member Author

Hmmmm. Strangely I just saw the message "First-time contributors need a maintainer to approve running workflows" for this PR, and I had to approve the run despite all commits in it being authored by me. I could have sworn I'd made a few commits to this repo before now...

mattcaswell added a commit to mattcaswell/openssl that referenced this pull request Jul 15, 2021
Various comments referred to s->packet and s->packet_length instead of
s->rlayer.packet and s->rlayer.packet_length. Also fixed is a spot where
RECORD_LAYER_write_pending() should have been used. Based on the review
comments in openssl#16077.
@mattcaswell
Copy link
Member Author

I've created #16086 to address the problems identified in the various comments (plus a few other instances I found). I also fixed SSL_new_session_ticket to use RECORD_LAYER_write_pending().

@openssl-machine
Copy link
Collaborator

24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually.

@kaduk
Copy link
Contributor

kaduk commented Jul 15, 2021

I think this should go to 1.1.1 as well (the cherry-pick is clean).

@kaduk
Copy link
Contributor

kaduk commented Jul 15, 2021

the cherry-pick is clean

... but ERR_raise() doesn't exist on 1.1.1

@mattcaswell
Copy link
Member Author

... but ERR_raise() doesn't exist on 1.1.1

Yeah, as I said in the introduction to this PR:

This should also be applied to 1.1.1, but I will wait until this is approved to create a PR there since it requires some minor adjustment there.

@t8m t8m added approval: ready to merge The 24 hour grace period has passed, ready to merge and removed approval: done This pull request has the required number of approvals labels Jul 16, 2021
openssl-machine pushed a commit that referenced this pull request Jul 16, 2021
Sometimes this function gets called when the buffers have already been
set up. If there is already a partial packet in the read buffer then the
packet pointer will be set to an incorrect value. The packet pointer already
gets reset to the correct value when we first read a packet anyway, so we
don't also need to do it in ssl3_setup_read_buffer.

Fixes #13729

Reviewed-by: Tomas Mraz <[email protected]>
(Merged from #16077)
openssl-machine pushed a commit that referenced this pull request Jul 16, 2021
If an application is halfway through writing application data it should
not be allowed to attempt an SSL_key_update() operation. Instead the
SSL_write() operation should be completed.

Fixes #12485

Reviewed-by: Tomas Mraz <[email protected]>
(Merged from #16077)
@t8m
Copy link
Member

t8m commented Jul 16, 2021

Merged to master. Thanks.

@t8m t8m closed this Jul 16, 2021
@t8m
Copy link
Member

t8m commented Jul 16, 2021

I've now noticed that I've accidentally forgot to add @kaduk to reviewed-by. I am sorry for that.

openssl-machine pushed a commit that referenced this pull request Jul 17, 2021
Various comments referred to s->packet and s->packet_length instead of
s->rlayer.packet and s->rlayer.packet_length. Also fixed is a spot where
RECORD_LAYER_write_pending() should have been used. Based on the review
comments in #16077.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Ben Kaduk <[email protected]>
(Merged from #16086)
kaduk pushed a commit to kaduk/openssl that referenced this pull request Jul 17, 2021
Various comments referred to s->packet and s->packet_length instead of
s->rlayer.packet and s->rlayer.packet_length. Also fixed is a spot where
RECORD_LAYER_write_pending() should have been used. Based on the review
comments in openssl#16077.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Ben Kaduk <[email protected]>
(Merged from openssl#16086)

(cherry picked from commit ca00152)
openssl-machine pushed a commit that referenced this pull request Jul 20, 2021
Various comments referred to s->packet and s->packet_length instead of
s->rlayer.packet and s->rlayer.packet_length. Also fixed is a spot where
RECORD_LAYER_write_pending() should have been used. Based on the review
comments in #16077.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Ben Kaduk <[email protected]>

(cherry picked from commit ca00152)

Reviewed-by: Paul Dale <[email protected]>
(Merged from #16105)