Fixed wrong key usage for finish message when using early data #171
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 I used TLS-Attacker in client mode for testing early data, I found that the server side couldn't decrypt the Finished Message in the second handshake.
How to reproduce
openssl s_server -cert ./server_cert.pem -key ./server_key.pem -tls1_3 -early_data -no_anti_replay -trace
java -jar ./apps/TLS-Client.jar -connect localhost:4433 -config ./tls13_0rtt_short.txt
tls13_0rtt_short.txt
Error on server side:
After some digging I think I found the root cause. The Finished message is encrypted with the same key as the EndOfEarlyData message. To see this, you can put
at the beginning of
public void encrypt(Record record) throws CryptoException { }
in "TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/record/cipher/RecordAEADCipher.java"But EndOfEarlyData message needs to be encrypted under client_early_traffic_secret and the Finished message with client_handshake_traffic_secret (compare RFC8446, chapter 4.5 and 7.3).
I implemented a rough workaround to fix the client behavior in the second handshake flow. Roughly speaking, at the point where the client receives the server's Finish message, we precalculate the handshake_traffic_secret and store it in TlsContext (see FinishHandler.java) even though the next secret to be used is early_traffic_secret for sending EndOfEarlyData message.
When this message is sent out, we set the active key set to the stored handshake_traffic_secret so that the following Finish message sent by the client to the server is correctly encrypted (see EndOfEarlyDataHandler.java)
Disclaimer: This is working when using TLS-Attacker in client mode but not yet for the server mode. I will update this draft PR accordingly.