-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Comply with the received Record Size Limit extension #7455
Comply with the received Record Size Limit extension #7455
Conversation
2561fff
to
7ad693c
Compare
@yanesca I have two open questions regarding my implementation and would like to get some feedback on these: 1: 2: Thanks! |
7ad693c
to
d7d5c10
Compare
I removed This made the changes in However, Now I'm wondering how to fix this properly. Any hints? |
Yes, it is. For now we just want to do some smoke testing. Adding unit tests and extensive testing is out of scope for this PR and will be done in #7027.
We can calculate it right here rounding down to a multiple of |
I suggest we don't remove MBEDTLS_SSL_RECORD_SIZE_LIMIT from the exclude list in config.py just yet. We can do that later after the feature is complete and we have added extensive unit tests. |
d7d5c10
to
38d0046
Compare
Done, with subtracting 1 byte after rounding to account for the content type that will be added afterwards.
Reverted both the change to |
38d0046
to
cacf1dc
Compare
cacf1dc
to
e900345
Compare
@KloolK This PR is something that we still need and a contribution we want to take, we are just struggling to find the review bandwidth for it at the moment. I just wanted to give you a heads up that it looks like it will take some time until we will be able to schedule the review. Thanks again for your contribution and thank you for your patience. |
We are aiming to finish up some outstanding TLS 1.3 work in Q4, including this PR, for release in Mbed TLS 3.6. So we do expect to pick this up in the near future. |
Hi @KloolK, can I check if you will have time to make the changes requested, or would you like us to finish off this PR? |
Hi @tom-cosgrove-arm I don't expect to have much time in the coming weeks unfortunately. Feel free to finish this off. |
c1578c2
to
9aec1c7
Compare
library/ssl_msg.c
Outdated
@@ -917,6 +917,7 @@ int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl, | |||
#endif | |||
size_t add_data_len; | |||
size_t post_avail; | |||
int max_out_record_len = mbedtls_ssl_get_max_out_record_payload(ssl); |
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.
There are many failures in CI that's because, in mbedtls_ssl_get_max_out_record_payload
, we call mbedtls_ssl_get_output_max_frag_len
which tries to access ssl->conf-mfl_code
.
However, in some test cases, we only test specific functionality so we don't call mbedtls_ssl_setup()
. ssl_crypt_record
in test_suite_ssl.function
is an example.
Edit: This commit is a workaround to fix aforementioned issue.
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.
Follow-up:
I found another issue is that we have test cases which set max_fragment_length
to 512
and which, in DTLS, set mtu = 512
. It has same problem as RecordLimitSize=512
due to size of Certificate.
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.
@yanrayw could you please point me to a test that has this problem?
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.
@yanesca There are many failed components in CI. Take ./tests/scripts/all.sh --seed 4 --keep-going test_tls13
as an example. We see this log
[2023-12-06T22:50:06.787Z] Record crypt, AES-128-CBC, 1.2, SHA-384 ........................... /var/lib/build/library/ssl_tls.c:3430:47: runtime error: member access within null pointer of type 'const struct mbedtls_ssl_config'
That's because we try to access in NULL
pointer in the test case, which matches this comment.
As for the problem mentioned in this comment, we see this error log
[2023-12-06T22:50:06.786Z] Sending app data via TLS, MFL=512 without fragmentation ........... FAILED
[2023-12-06T22:50:06.786Z] mbedtls_test_move_handshake_to_state(&(client.ssl), &(server.ssl), MBEDTLS_SSL_HANDSHAKE_OVER) == expected_handshake_result
[2023-12-06T22:50:06.786Z] at line 2100, /var/lib/build/tests/src/test_helpers/ssl_helpers.c
[2023-12-06T22:50:06.786Z] Sending app data via TLS, MFL=512 with fragmentation .............. FAILED
[2023-12-06T22:50:06.786Z] mbedtls_test_move_handshake_to_state(&(client.ssl), &(server.ssl), MBEDTLS_SSL_HANDSHAKE_OVER) == expected_handshake_result
[2023-12-06T22:50:06.786Z] at line 2100, /var/lib/build/tests/src/test_helpers/ssl_helpers.c
and log from ssl-opt.sh
[2023-12-06T23:12:25.052Z] DTLS fragmenting: both (MTU=512) ....................................... RETRY(client-timeout) RETRY(client-timeout) FAIL
[2023-12-06T23:12:25.052Z] ! bad client exit code (expected 0, got 143)
which is caused by this check since max_out_record_len
is smaller than certificate
.
Please let me know if anything is not correct from my understanding.
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 think the problem is checking on maximum fragment length according to this: https://github.com/Mbed-TLS/mbedtls/blob/development/include/mbedtls/ssl.h#L4262-L4264 we do not support currently maximum fragment length during handshake so I added a check for if we are in handshake or not.
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 @yanrayw, I think @waleed-elmelegy-arm 's solution should resolve the issue.
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.
Thanks! CI is still not happy, might be related to mtu
in DTLS
. I haven't looked into it.
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 looked into the failure and the reason is the certificate being to big while doing handshake and this is in DTLS so we now check the MTU in case of DTLS so the only solutions are to use smaller certificate or disable 512 bytes tests, in this case the good thing is this is a test that is using mbedtls as a server and a client so we might be able to use secp192 certificate since GnuTLS is not involved but I will check other failing tests to confirm.
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.
That doesn't add up, we fragment handshake messages in DTLS. How can the certificate be too big?
MbedTLS currently does not support maximum fragment length during handshake so we skip it for now. Signed-off-by: Waleed Elmelegy <[email protected]>
This reverts commit 419f841. Signed-off-by: Waleed Elmelegy <[email protected]>
Revert back checking on handshake messages length due to limitation on our fragmentation support of handshake messages. Signed-off-by: Waleed Elmelegy <[email protected]>
2cf8e7b
to
26e3698
Compare
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've reviewed the library code. Please find my comments below. I have started to look at the tests as well but not completely.
Signed-off-by: Waleed Elmelegy <[email protected]>
Signed-off-by: Waleed Elmelegy <[email protected]>
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've re-reviewed the library code and reviewed the tests.
Signed-off-by: Waleed Elmelegy <[email protected]>
Signed-off-by: Waleed Elmelegy <[email protected]>
Signed-off-by: Waleed Elmelegy <[email protected]>
Signed-off-by: Waleed Elmelegy <[email protected]>
Signed-off-by: Waleed Elmelegy <[email protected]>
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.
One comment not addressed yet it seems, otherwise this looks good to me. Otherwise, as you have experienced with the tests, currently we can not reach the maximum payload of 16384 in TLS 1.3 records. I have created #8671 to track that.
Signed-off-by: Waleed Elmelegy <[email protected]>
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.
The description of mbedtls_ssl_get_output_record_size_limit() is outdated. Otherwise this looks good to me.
Co-authored-by: Ronald Cron <[email protected]> Signed-off-by: Waleed-Ziad Maamoun-Elmelegy <[email protected]>
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, thanks.
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.
Looks good to me; nice work.
Some minor comments; I'm not sure if they need to be addressed as part of this PR, or could be handled (if necessary) in the other PR
@@ -2610,6 +2618,13 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session, | |||
session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0); | |||
p += 4; | |||
#endif | |||
#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) | |||
if (end - p < 2) { | |||
return 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'd like to think that if someone was using Mbed TLS just before this PR, and had a saved session, then recompiled with this PR, and tried to resume, they'd get an MBEDTLS_ERR_SSL_VERSION_MISMATCH
(considering it the version of the data, rather than just the version of the library) error, not a MBEDTLS_ERR_SSL_BAD_INPUT_DATA
error, although I suspect the caller would treat both identically.
That would suggest that MBEDTLS_SSL_RECORD_SIZE_LIMIT
should be incorporated in SSL_SERIALIZED_SESSION_CONFIG_BITFLAG
However, the same reasoning applies to MBEDTLS_SSL_EARLY_DATA
, so this looks like pre-existing, rather than anything else, and I'm mainly making the observation here, rather than asking for a change.
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.
That would suggest that
MBEDTLS_SSL_RECORD_SIZE_LIMIT
should be incorporated inSSL_SERIALIZED_SESSION_CONFIG_BITFLAG
That's a good point. I think we overlooked this aspect of serialized sessions while working on new session tickets, early data and now record size limit. I am creating an issue to address that: #8686.
size_t record_size_limit = max_len; | ||
|
||
if (ssl->session != NULL && | ||
ssl->session->record_size_limit >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN && |
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.
It's not clear to me under what circumstances we would put a value < MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN
into the session. Would it make more sense to verify when populating ssl->session->record_size_limit
and then be able to skip the check 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.
If we do not receive any record size limit extension then ssl->session->record_size_limit
is equal to zero. Thus to me this check is to detect if the peer sent a record size limit or not.
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.
Ah - if this test had been for > 0
then I might have thought that.
Would (in the future, not this PR) it make more sense to set this to the value to use for record size and use it unconditionally?
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.
Yes that would be an improvement.
@@ -1776,6 +1776,10 @@ int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session, | |||
} | |||
#endif /* MBEDTLS_SSL_CLI_C */ | |||
|
|||
#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) | |||
session->record_size_limit = 2048; |
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.
What if MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN
> 2048?
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.
MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN is defined by RFC 8449 to be equal to 64. We should probably add a comment where MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN is defined to make that clear.
# -s "Received alert \[110]: An unsupported extension was sent" | ||
# -c "RecordSizeLimit: 16385 Bytes" | ||
|
||
# In the following (9) tests, --recordsize is the value used by the G_NEXT_CLI (3.7.2) to configure the |
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; only if making other changes) 9
seems to be a number that won't be maintained (as tests are added and removed in this section, it's likely that at some point we'll forget to update this number) so best removed. Would it be better to have an "end of record size limit tests" comment?
|
||
# In the following (9) tests, --recordsize is the value used by the G_NEXT_CLI (3.7.2) to configure the | ||
# maximum record size using "https://gnutls.org/reference/gnutls-gnutls.html#gnutls-record-set-max-size". | ||
# There is currently a lower limit of 512, caused by this function not respecting the |
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; not sure if worth an update to the PR on its own)
On first (and second!) reading, it wasn't clear to me that "this function" referred to the function documented in the URL on the line above, mainly because it wasn't clear that the object of "using" was a function.
I wonder if it would be better to be explicit about gnutls_record_set_max_size()
rather than saying "this function", or if "that function" would work just as well.
# https://gnutls.org/reference/gnutls-gnutls.html#gnutls-record-set-max-recv-size. | ||
# There is currently an upper limit of 4096, caused by the cli arg parser: | ||
# https://gitlab.com/gnutls/gnutls/-/blob/3.7.2/src/cli-args.def#L395. | ||
# Thus, these tests are currently limit to that value range. |
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) Best be explicit. Also, should be limited
# Thus, these tests are currently limit to that value range. | |
# Thus, these tests are currently limited to the value range 512-4096. |
# Thus, these tests are currently limit to that value range. | ||
# Moreover, the value sent in the extension is expected to be larger by one compared | ||
# to the value passed on the cli: | ||
# https://gitlab.com/gnutls/gnutls/-/blob/3.7.2/lib/ext/record_size_limit.c#L142 |
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.
Is it is expected to be
or just will be
?
Also, the value sent in the extension will be one larger than the value set at the command line:
?
|
||
if (ssl->transform_out != NULL && | ||
ssl->transform_out->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { | ||
/* RFC 8449, section 4: |
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.
It's not immediately clear why this is not within the MBEDTLS_SSL_RECORD_SIZE_LIMIT
block. Some of the text in Ronald's comment might help here
Do we still need to be able to craft a small certificate for future testing, as mentioned in Janos' comment? If so, removing curves smaller than 255 bits (issue 8136) might be a problem! |
I do not think that this would improve much the testing of the record size limit code as now we have tests with a record size limit of 512 using a pre-shared key. |
Fixes #7010
Gatekeeper checklist