-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Defragment ext test 3.6 #9976
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Defragment ext test 3.6 #9976
Conversation
03ef604 to
5d5d64a
Compare
39c85c4 to
6f55ec6
Compare
tests/suites/test_suite_ssl.data
Outdated
|
|
||
| TLS 1.3 srv, max early data size, HRR, 98, wsz=49 | ||
| tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97:0 | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest placing the new tests in a separate .data file. test_suite_ssl.data is already huge. Creating a new .data file for an existing .function file is trivial, it doesn't need to be recorded in any build script.
d301ac7 to
aa6d3d4
Compare
aa6d3d4 to
d1587e2
Compare
| @@ -0,0 +1,181 @@ | |||
| # (Minimal) ClientHello breakdown: | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before I review the test coverage, here's a list of things I would like to test. They don't have to all be done in this pull request, it's perfectly fine if anything missing is done in a follow-up.
- Receiving a handshake record that's larger than the handshake message length, when there is no partial handshake message already, and where the extra data is a valid handshake message. Test coalesced or split handshake messages #10045
- Receiving a handshake record that's larger than the handshake message length, when there is no partial handshake message already, and where the extra data is not a valid handshake message. Test coalesced or split handshake messages #10045
- Receiving a handshake record with a subsequent handshake fragment and more data after the expected end of the message, and where the extra data is a valid handshake message. Test coalesced or split handshake messages #10045
- Receiving a handshake record with a subsequent handshake fragment and more data after the expected end of the message, and where the extra data is not a valid handshake message. Test coalesced or split handshake messages #10045
- Receiving a handshake record that fits in the input buffer, but the total length of the message doesn't fit. "Send large fragmented ClientHello" test cases here
- Receiving a message whose length is ≥65536, meaning that it cannot be correctly formatted as a single reassembled record. "Send large fragmented ClientHello: length doesn't fit in two bytes" here
- Receiving a data message when there is a partial handshake message. "Inject ClientHello - TLS 1.3 fragmented 4 + appdata" here, plus "insert data record" in Test coalesced or split handshake messages #10045
- Receiving an alert message when there is a partial handshake message. "Inject ClientHello - TLS 1.3 fragmented 4 + alert" here, plus "insert alert record" in Test coalesced or split handshake messages #10045
- The peer closes the connection when there is a partial handshake message. "truncate at" in Test coalesced or split handshake messages #10045
- Receiving a 0-byte subsequent handshake fragment. Test coalesced or split handshake messages #10045 "empty record"
- Receiving a 1-byte subsequent handshake fragment. Done since Add basic handshake defragmentation tests in ssl-opt #9989.
- Receiving a 1-byte initial handshake fragment. Test coalesced or split handshake messages #10045
- Receiving a 3-byte initial handshake fragment. Done since Add basic handshake defragmentation tests in ssl-opt #9989.
- Receiving a fragmented ClientHello that initiates renegotiation.
These test cases should run both in TLS 1.2 and TLS 1.3 where applicable, and both with and without MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Receiving a message whose length is ≥65536, meaning that it cannot be correctly formatted as a single reassembled record.
Or buffer is 2^14 or smaller, so we'll end up rejecting fragments because they'd overflow our buffer before we get to this issue.
Receiving a 0-byte subsequent handshake fragment.
Note that 0-length handshake fragments are forbidden by the standard (both 1.2 and 1.3). (Only 0-length ApplicationData records are allowed.) Not saying we shouldn't test it, just saying I think the desired behaviour is for our code to reject it.
gilles-peskine-arm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am satisfied that in 1f216de, the tests do what they say on the tin, and they are explained as well as they can be given the time constraints. (Ideally I'd prefer not to rely on a bunch of hex strings, but moving away from that would take far more time than we have now.)
I want more test coverage before we release, but I'm in favor of merging this PR ASAP and improving coverage in a follow-up.
| ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { | ||
| MBEDTLS_SSL_DEBUG_MSG(1, ("non-handshake message in the middle" | ||
| " of a fragmented handshake message")); | ||
| return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocker: should we send an alert?
|
|
||
| /* Send initial fragment and have the server process it. */ | ||
| ret = mbedtls_test_mock_tcp_send_b(&client.socket, first_frag, first_len); | ||
| TEST_ASSERT(ret >= 0 && (size_t) ret == first_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: why not
| TEST_ASSERT(ret >= 0 && (size_t) ret == first_len); | |
| TEST_EQUAL(ret, (int) first_len); |
which prints out the values of ret and first_len if it fails?
| send_large_fragmented_hello:MBEDTLS_SSL_IN_CONTENT_LEN - 4:3:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA | ||
|
|
||
| Send large fragmented ClientHello: would fit without overhead #5 | ||
| send_large_fragmented_hello:MBEDTLS_SSL_IN_CONTENT_LEN - 4:4:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess after incremental defragmentation, we expect to add this?
Send large fragmented ClientHello: just fits
send_large_fragmented_hello:MBEDTLS_SSL_IN_CONTENT_LEN - 5:0:"":0
``
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well if we want it to return 0, we'll need to pass a valid supersize ClientHello. I think that can be achieved by putting junk into an unknown extension, but that would require changes to the test function.
Also, I'm not sure the previous negative tests will still be valid after incremental defrag: we have some extra room in the buffer for encryption overhead, that's unused for the unencrypted ClientHello, so I'm actually expecting we don't be getting the same error from fetch_input for messages just over the limit. We'll see when I rebase.
TBH I'm not sure what we should do here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'm going with the same invalid ClientHello as for the other tests. We'll know that defragmentation succeeded when we get a return value of MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION with Unsupported version of TLS in the logs as opposed MBEDTLS_ERR_SSL_BAD_INPUT_DATA + requesting more data than fits when it was too large for reassembly.
1f216de to
035a249
Compare
In addition to secp256r1 for the handshake, we need secp384r1 as it's used by the CA certificate. Caught by depends.py curves Also, for the "unknown ciphersuite" 1.2 test, use the same key type and all the same dependencies as of the "good" test above, to avoid having to determine a second set of correct dependencies just for this one. Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
We're not sending a signature_algorithm extension, which means SHA-1. Caught by depends.py hashes Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Declare the same dependencies as for the previous TLS 1.3 tests, except for part that varies with the cipher suite (ie AES-GCM). Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
This should avoid running into a bug with printf format specifiers one windows. It's also a logical move for actual tests: I used the highest debug level for discovery, but we don't need that all the time. Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
This is more flexible: the test data gets to decide whether we want to assert the presence of a pattern or not. Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
That way if it ever fails it will print the values. Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
Signed-off-by: Manuel Pégourié-Gonnard <[email protected]>
7932fbe to
43a04e7
Compare
|
Rebased on 3.6 now that #10043 is merged and Open CI came back fully green as expected. Ready for review, I will no longer be rebasing, nor pushing changes (except to address review feedback). |
gilles-peskine-arm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM at 43a04e7
As suggested by Minos, I'd like to add a test of a 1.2 ClientHello that's embedded in a larger record, followed in the same record by a ClientKeyExchange that would be valid for some server response. But that's technically out of scope here.
minosgalanakis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| /* Change 0 to 1 for debugging of test cases that use this function. */ | ||
| #if 0 | ||
| const char *q, *basename; | ||
| /* Extract basename from file */ | ||
| for (q = basename = file; *q != '\0'; q++) { | ||
| if (*q == '/' || *q == '\\') { | ||
| basename = q + 1; | ||
| } | ||
| } | ||
| printf("%s:%04d: |%d| %s", | ||
| basename, line, level, str); | ||
| #else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, that's very helpful!
Description
This adds three families of tests for TLS handshake defragmentation:
a. whose announced size is larger than our input buffer, or
b. whose size would fit except it doesn't due to fragmentation overhead.
In addition, there are a few test cases, with "for reference" in the name, that are really about validating the new test function rather than testing the library.
Regarding the kind of things being tested:
fetch_input()acts as a reliable defence against overflowing the input buffer).a. The case where the announced size if too large could perhaps be rejected earlier?
b. The case where the message would fit except for fragmentation overhead has been adapted to incremental defragmentation.
Depends on: #10043mergedPR checklist