Remove a spurious TLSProxy byte in TLSv1.3#5370
Closed
mattcaswell wants to merge 1 commit intoopenssl:masterfrom
Closed
Remove a spurious TLSProxy byte in TLSv1.3#5370mattcaswell wants to merge 1 commit intoopenssl:masterfrom
mattcaswell wants to merge 1 commit intoopenssl:masterfrom
Conversation
Member
Author
|
I found this based on a comment by @bernd-edlinger in #5067. It was a real case of "how did this ever work" for a while! |
Contributor
|
Could you double-check appveryor log and confirm that failure is unrelated. |
Member
|
@levitte I think this looks like we received a fragmented packet here: |
Member
|
I am pretty sure the test failure is unrelated. |
When the proxy re-encrypted a TLSv1.3 record it was adding a spurious byte onto the end. This commit removes that. The "extra" byte was intended to be the inner content type of the record. However, TLSProxy was actually adding the original encrypted data into the record (which already has the inner content type in it) and then adding the spurious additional content type byte on the end (and adjusting the record length accordingly). It is interesting to look at why this didn't cause a failure: The receiving peer first attempts to decrypt the data. Because this is TLSProxy we always use a GCM based ciphersuite with a 16 byte tag. When we decrypt this it actually gets diverted to the ossltest engine. All this does is go through the motions of encrypting/decrypting but just passes back the original data. Crucially it will never fail because of a bad tag! The receiving party thinks the spurious additional byte is part of the tag and the ossltest engine ignores it. This means the data that gets passed back to the record layer still has an additional spurious byte on it - but because the 16 byte tag has been removed, this is actually the first byte of the original tag. Again because we are using ossltest engine we aren't actually creating "real" tags - we only ever emit 16, 0 bytes for the tag. So the spurious additional byte always has the value 0. The TLSv1.3 spec says that records can have additional 0 bytes on the end of them - this is "padding". So the record layer interprets this 0 byte as padding and strips it off to end up with the originally transmitted record data - which it can now process successfully.
a4fd6ba to
85d1b19
Compare
Member
Author
|
Rebased as requested. |
bernd-edlinger
approved these changes
Feb 20, 2018
Member
Author
|
Pushed. Thanks. |
levitte
pushed a commit
that referenced
this pull request
Feb 21, 2018
When the proxy re-encrypted a TLSv1.3 record it was adding a spurious byte onto the end. This commit removes that. The "extra" byte was intended to be the inner content type of the record. However, TLSProxy was actually adding the original encrypted data into the record (which already has the inner content type in it) and then adding the spurious additional content type byte on the end (and adjusting the record length accordingly). It is interesting to look at why this didn't cause a failure: The receiving peer first attempts to decrypt the data. Because this is TLSProxy we always use a GCM based ciphersuite with a 16 byte tag. When we decrypt this it actually gets diverted to the ossltest engine. All this does is go through the motions of encrypting/decrypting but just passes back the original data. Crucially it will never fail because of a bad tag! The receiving party thinks the spurious additional byte is part of the tag and the ossltest engine ignores it. This means the data that gets passed back to the record layer still has an additional spurious byte on it - but because the 16 byte tag has been removed, this is actually the first byte of the original tag. Again because we are using ossltest engine we aren't actually creating "real" tags - we only ever emit 16, 0 bytes for the tag. So the spurious additional byte always has the value 0. The TLSv1.3 spec says that records can have additional 0 bytes on the end of them - this is "padding". So the record layer interprets this 0 byte as padding and strips it off to end up with the originally transmitted record data - which it can now process successfully. Reviewed-by: Bernd Edlinger <[email protected]> (Merged from #5370)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When the proxy re-encrypted a TLSv1.3 record it was adding a spurious
byte onto the end. This commit removes that.
The "extra" byte was intended to be the inner content type of the record.
However, TLSProxy was actually adding the original encrypted data into the
record (which already has the inner content type in it) and then adding
the spurious additional content type byte on the end (and adjusting the
record length accordingly).
It is interesting to look at why this didn't cause a failure:
The receiving peer first attempts to decrypt the data. Because this is
TLSProxy we always use a GCM based ciphersuite with a 16 byte tag. When
we decrypt this it actually gets diverted to the ossltest engine. All this
does is go through the motions of encrypting/decrypting but just passes
back the original data. Crucially it will never fail because of a bad tag!
The receiving party thinks the spurious additional byte is part of the
tag and the ossltest engine ignores it.
This means the data that gets passed back to the record layer still has
an additional spurious byte on it - but because the 16 byte tag has been
removed, this is actually the first byte of the original tag. Again
because we are using ossltest engine we aren't actually creating "real"
tags - we only ever emit 16, 0 bytes for the tag. So the spurious
additional byte always has the value 0. The TLSv1.3 spec says that records
can have additional 0 bytes on the end of them - this is "padding". So the
record layer interprets this 0 byte as padding and strips it off to end up
with the originally transmitted record data - which it can now process
successfully.
Checklist