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

Handshake Messages are not fragmented as per MaxFragmentLength Extension Negotiation. #387

Closed
JayaraghavendranK opened this Issue Jan 4, 2016 · 34 comments

Comments

Projects
None yet
@JayaraghavendranK

JayaraghavendranK commented Jan 4, 2016

As per RFC 6066,

"Once a maximum fragment length other than 2^14 has been successfully
negotiated, the client and server MUST immediately begin fragmenting
messages (including handshake messages) to ensure that no fragment
larger than the negotiated length is sent. "

But, looks like the mBed-TLS code doesn't handle this for handshake messages and handles this only for application data messages. Please check this.

@ciarmcom

This comment has been minimized.

Member

ciarmcom commented Jan 4, 2016

ARM Internal Ref: IOTSSL-592

@ciarmcom ciarmcom added the mirrored label Jan 4, 2016

@mpg mpg added the bug label Jan 4, 2016

@mpg

This comment has been minimized.

Contributor

mpg commented Jan 4, 2016

Thanks for your report. I agree we're currently not fully respecting the spec here, as we only fragment after the handshake. Unfortunately this is not an easy thing to fix. Can you please tell us more about the practical impact for you?

@JayaraghavendranK

This comment has been minimized.

JayaraghavendranK commented Jan 5, 2016

As I can see, during the configuration, you allow the user to set a mfl less than MBEDTLS_SSL_MAX_CONTENT_LEN. So, if a lower mfl is negotiated, the server will still receive a handshake packet which is larger than the negotiated fragment value and can lead to a failure of Handshake.

I guess ensuring that the mfl and the MBEDTLS_SSL_MAX_CONTENT_LEN share the same value always should do the trick or Am I missing something?

But, as of now, no fragmentation is supported at all at record layer for either TLS or DTLS. Is this understanding right?

@mpg

This comment has been minimized.

Contributor

mpg commented Jan 5, 2016

What I meant is: are you observing actual handshake failures due to this issue in a use case that's important to you, or for now is that only a theoretical issue?

@JayaraghavendranK

This comment has been minimized.

JayaraghavendranK commented Jan 5, 2016

Right now, it is only a theoretical issue. Not directly linked to any deployment use case.

@pdh11

This comment has been minimized.

pdh11 commented Apr 21, 2016

IMO negotiating max-fragment-length but failing to implement it for handshake records is kind of a bear-trap. TLS servers which implement RFC6066 section 4 correctly include GnuTLS and WolfSSL, and MbedTLS will not connect to either of them if told to offer the extension. If someone deploys an MbedTLS-based device which offers the extension, with the intention of later deploying a server which also understands it, they could get caught out when they do deploy a working server.

The test in mbedtls/tests/ssl-opt.sh which negotiates the max-fragment-length extension against a GnuTLS server is a teensy bit disingenuous IMO, as it chooses to negotiate a size of 4096, which is larger than any handshake packet would have been anyway. (Though with big enough keys or a long enough certificate chain, handshake messages can exceed 4096 bytes.) If that 4096 is changed to 512, the test fails.

In the meantime I suggest removing mbedtls_ssl_conf_max_frag_len (or making it a no-op) until handshake fragmentation is supported.

@dhessler

This comment has been minimized.

dhessler commented Jul 19, 2016

This is currently a blocking issue for me. I'm working with a resource constrained device using the max fragment size (with MBEDTLS_SSL_MAX_CONTENT_LEN set to 2048) in order to operate within my RAM limits.

Everything works just fine in MBEDTLS_SSL_VERIFY_NONE authmode; the handshake fails however when auth is required. The (node.js) server is using a CA chain with 2 certificates.

Not being able to raise the fragment size, are there any workarounds I have?
Is a fix actively being developed?

@gyanaranjanjena

This comment has been minimized.

gyanaranjanjena commented Aug 2, 2016

Is there any update to this , support for the fragmentation during handshake?

@pjbakker

This comment has been minimized.

Contributor

pjbakker commented Aug 3, 2016

It's in our queue. No further details available.

@dhessler

This comment has been minimized.

dhessler commented Dec 13, 2016

Are there any updates or activity here? This is quite a limitation for constrained environments which cannot support the overheard introduced by using the default max fragment length (16kB x2 for I/O buffers).

@ronpanto

This comment has been minimized.

ronpanto commented Jan 4, 2017

Any updates on this issue?

@mbedardh

This comment has been minimized.

mbedardh commented Mar 5, 2017

Even after handshake the fragment length does not work for me in a HTTP client implementation. I call this function without error in TlsStart:

if( ret = mbedtls_ssl_conf_max_frag_len( &conf, MBEDTLS_SSL_MAX_FRAG_LEN_4096 ) != 0)
{
    mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret );
}

And, I have these defines:

#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
#define MBEDTLS_SSL_MAX_CONTENT_LEN 4096

After successful handshake, the server sends more that 4k data so I get this error:

Read from server:../src/mbedtls/ssl_tls.c:3525: bad message length

The server is nginx v1.10 and I am not sure if it supports Fragment Length (RFC 6066 Section 4) ?

Any help would be appreciated. Any other settings or macro to invoke?

@kanchanjunga2016

This comment has been minimized.

kanchanjunga2016 commented Sep 1, 2017

Hello,

I am porting the Mbedtls DTLS 1.2 to use it in resources constrained device and low bandwidth link which can't support fragment size larger than 512. I have now run into the show stopper to use MBEDTLS due to this issue. I am wondering if this issue will be fixed to support in handshake.

If so is there any timeline when this will be fixed. Any feedback is greatly appreciated.

@gonzobrandon

This comment has been minimized.

gonzobrandon commented Nov 30, 2017

Indeed, this issue is a show stopper for us. We are limited to around 512 per fragment when sending over 802.15.4 network. We're already up against a ram limit. WolfSSL implemented a handshake fragmenter over 2 years ago. Don't want to switch to their suite if don't have to.

@balabharathi

This comment has been minimized.

balabharathi commented Apr 11, 2018

Is there any update on this issue. We need this feature for our low memory footprint device.

@kanchanjunga2016

This comment has been minimized.

kanchanjunga2016 commented Apr 11, 2018

Hi. This is still an issue and has not fixed. I was hoping it get fixed.

We try adding support but we decided to use wolfssl since wolfssl supports this features which you might want to consider.

@carterw

This comment has been minimized.

carterw commented Apr 16, 2018

I am seeing this same problem. A perfectly valid certificate is being rejected with;
mbedtls_ssl_handshake error: -7200

@hanno-arm

This comment has been minimized.

Contributor

hanno-arm commented Apr 17, 2018

@carterw Do you refer to an incoming or an outgoing certificate? Large incoming certificate should be handled correctly at the moment.

We are currently rewriting the messaging layer, in particular adding the long-awaited support for fragmentation for outgoing messages.

@carterw

This comment has been minimized.

carterw commented Apr 17, 2018

The problem I am seeing involves handshaking with a server that has a known-valid incoming certificate. Handshaking works with most servers, but mine appears to have a relatively long intermediate certificate chain which may be overflowing a buffer.

I'm using Micropython, which seems to have incorporated mbedtls, but the version being used may be out of date. Can you tell me which files(s) were involved in the fix?

@hanno-arm

This comment has been minimized.

Contributor

hanno-arm commented Apr 17, 2018

@carterw From your explanations I am not yet clear on whether you're running Mbed TLS on a client or server, and whether you use TLS or DTLS - could you please clarify? The fragmentation for outgoing handshake messages in both TLS and DTLS is work in progress, as is the reassembly of incoming handshake messages in TLS, while the fragmentation for incoming messages in DTLS is implemented and expected to work.

@carterw

This comment has been minimized.

carterw commented Apr 17, 2018

Sorry for the confusion. I'm running a client that is attempting a handshake with a webserver.

The code that is invoking the handshake looks like this (returns an error code of -7200);
ret = mbedtls_ssl_handshake(&o->ssl)

The server that is showing the failure (my server) is at the following URL;
https://canulus.com

The webserver is running Nginx and the certificate shows as good when I run the usual 3rd party checks against it. Can you shed any light on what might be the problem?

@hanno-arm

This comment has been minimized.

Contributor

hanno-arm commented Apr 18, 2018

@carterw Since you are using TLS (not DTLS), for which incoming handshake message reassembly is indeed not yet implemented but work in progress, it may be the case that the lack of this is the reason for your failure. However, to be sure, we need more information on the configuration of your client (e.g. are you using the MaximumFragmentLength extension? What's the size of incoming and outgoing data buffers, as configured by MBEDTLS_SSL_MAX_CONTENT_LEN) and the debugging log. Would you be willing to open a post in our forum or write me a mail, so that we can continue discussion there?

@carterw

This comment has been minimized.

carterw commented Apr 18, 2018

Thanks, I posted to the forum, topic "Handshake Messages are not fragmented".

MBEDTLS_SSL_MAX_CONTENT_LEN in the client is set to 16384. On the server side I have set the ssl_buffer_size to 1k but that doesn't help, possibly because this may only affect the size of data buffers after handshake. It is very possible that my client can't actually allocate 16384 bytes, it is very memory-constrained. I'll post the debug messages in the forum topic, thanks.

@carterw

This comment has been minimized.

carterw commented Apr 19, 2018

Any clues on this? Why would I be seeing;

ssl_tls.c:3487: input record: msgtype = 22, version = [3:3], msglen = 4586
ssl_tls.c:3518: bad message length
ssl_tls.c:4360: mbedtls_ssl_read_record() returned -29184 (-0x7200)
@hanno-arm

This comment has been minimized.

Contributor

hanno-arm commented Apr 19, 2018

@carterw I have replied to you in the support forum.

@EvgeniyVasyliev

This comment has been minimized.

EvgeniyVasyliev commented May 5, 2018

Hi, there!

I am facing a same problem. I am doing a HTTPS server and one of the options is a file upload (size is in average around 300 kb). So, mbedTLS in my case is working as a server and firmware file is arriving to server in a POST request with HTTP header stating Content-Length to 300 kb. At attempt to read the data using a function mbedtls_ssl_read it gives out error 0x7200, which means MBEDTLS_ERR_SSL_INVALID_RECORD. However in case if I try to upload a firmware with size of several bytes (specially made small just for test) - then everything is working OK.

I checked various sources and found that the problem can be solved by enabling the RFC 6066 max_fragment_length extension in the TLS config of the server. Thus I want to use a function mbedtls_ssl_conf_max_frag_len(&sslConfig, MBEDTLS_SSL_MAX_FRAG_LEN_4096) to solve this problem.

Can you please inform if mbedTLS is supporting this option in current release or no (in the posts above I did not find any confirmation to it)?

@EvgeniyVasyliev

This comment has been minimized.

EvgeniyVasyliev commented May 5, 2018

Addition to my previous message:

I have tried to use a functions
mbedtls_ssl_conf_max_frag_len(&sslConfig, MBEDTLS_SSL_MAX_FRAG_LEN_4096)
and
mbedtls_ssl_conf_max_frag_len(&sslConfig, MBEDTLS_SSL_MAX_FRAG_LEN_2048)

but seems they give no effect. I am still facing an error MBEDTLS_ERR_SSL_INVALID_RECORD (-29184 or -0x7200) at attempt to upload a file with big size.

Can anyone support how to use function mbedtls_ssl_conf_max_frag_len correctly to make it work?

Please note that I have MBEDTLS_SSL_MAX_FRAGMENT_LENGTH defined in mbedtls_config.h

@MabezDev

This comment has been minimized.

MabezDev commented May 8, 2018

@EvgeniyVasyliev I've just ran into this issue, you need a server that supports the extension, most popular servers use openSSL which has only recently got support and is not in a stable release.

@EvgeniyVasyliev

This comment has been minimized.

EvgeniyVasyliev commented May 9, 2018

@MabezDev
Thank you for response! I am using mbedTLS server over lwIP on STM32F427 MCU. I found a post describing that a person was able to use it: lwip.100.n7.nabble.com/PolarSSL-and-mbedTLS-td28851i20.html#message29012. However I am still struggling how to use it in mbedTLS...

@malachib

This comment has been minimized.

malachib commented Jun 19, 2018

I'm currently trying to make a DTLS server. If I understand correctly, DTLS protocol https://tools.ietf.org/html/rfc6347#section-4.2.3 calls for fragmentation during any handshake messages larger than a PMTU. If I further understand correctly, that feature is on the way for outgoing DTLS handshakes, but not implemented yet?

@mpg

This comment has been minimized.

Contributor

mpg commented Aug 16, 2018

Note: for DTLS, this is currently being implemented in this PR, with a goal of merging it in the next release: #1939

@sbutcher-arm

This comment has been minimized.

Collaborator

sbutcher-arm commented Sep 13, 2018

@mpg - this looks like it's only been fixed for DTLS. Do we need to reopen it for TLS? Or maybe it would be better to open a new issue?

cc: @hanno-arm

@mpg

This comment has been minimized.

Contributor

mpg commented Sep 17, 2018

@sbutcher-arm I think it might be clearer to open a new issue. That way, people who explicitly care about fragmentation and reassembly for TLS (we currently support neither - but they should be separate issues) can be more visible by posting on the new issue rather than this one that already has a complex comment history.

(I think this is important because I'm genuinely curious how many people care about that for TLS. My intuition would be much less than for DTLS, but as always I can be mistaken, especially when it comes to the real world, so if my intuition is wrong, I'd be happy for counter-examples to be clearly visible rather than buried in a long thread.)

@hanno-arm

This comment has been minimized.

Contributor

hanno-arm commented Sep 17, 2018

@sbutcher-arm I agree with @mpg that we should track this in a separate issue, for the 'external' reason @mpg stated, and also because the way TLS and DTLS fragmentation work internally are fundamentally different.

Note: TLS fragmentation is already implemented in MPS, so I suggest we don't implement it on top of the current stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment