[openssl-dev] [openssl.org #3712] TLS Renegotiation with Java is broken

classic Classic list List threaded Threaded
72 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

[openssl-dev] [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
On Wed Feb 18 21:12:09 2015, [hidden email] wrote:

> I ran into this problem while connecting to a PostgreSQL server
> (PostgreSQL uses OpenSSL
> for SSL support) with a Java client using
> the PostgreSQL JDBC driver (which uses
> the Java Secure Socket
> Extension which is part of Oracle's Java Runtime Environment).
> Since database connections are potentially long-lived, the PostgreSQL
> server will
> trigger a renegotiation after a certain amount of data
> has been exchanged via the
> TLS channel; this amount is configurable
> with the parameter "ssl_renegotiation_limit".
>
> This renegotiation is
> always aborted by OpenSSL with the error "unexpected record".
> I could
> reproduce the problem with OpenSSL 1.0.1e on Linux and OpenSSL 1.0.1j
> on
> Windows using Oracle JRE 1.7.0_71 and 1.7.0_75 on the client side.
> The protocol version in effect is TLS 1.2 (0x303).
>

There were some fixes related to renegotiation handling in OpenSSL which first
appeared in 1.0.1k. Can you see if this problem still happens in the latest
version of OpenSSL?

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl-dev] [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
On Wednesday 18 February 2015 23:49:39 Stephen Henson via RT wrote:

> On Wed Feb 18 21:12:09 2015, [hidden email] wrote:
> > I ran into this problem while connecting to a PostgreSQL server
> > (PostgreSQL uses OpenSSL
> > for SSL support) with a Java client using
> > the PostgreSQL JDBC driver (which uses
> > the Java Secure Socket
> > Extension which is part of Oracle's Java Runtime Environment).
> > Since database connections are potentially long-lived, the PostgreSQL
> > server will
> > trigger a renegotiation after a certain amount of data
> > has been exchanged via the
> > TLS channel; this amount is configurable
> > with the parameter "ssl_renegotiation_limit".
> >
> > This renegotiation is
> > always aborted by OpenSSL with the error "unexpected record".
> > I could
> > reproduce the problem with OpenSSL 1.0.1e on Linux and OpenSSL 1.0.1j
> > on
> > Windows using Oracle JRE 1.7.0_71 and 1.7.0_75 on the client side.
> > The protocol version in effect is TLS 1.2 (0x303).
>
> There were some fixes related to renegotiation handling in OpenSSL which
> first appeared in 1.0.1k. Can you see if this problem still happens in the
> latest version of OpenSSL?

I was able to reproduce this issue on master, OpenSSL_1_0_2-stable and
OpenSSL_1_0_1-stable branches as of *now* (2015-02-19).

I have a standalone (python - tlsfuzzer/tlslite) reproducer for that, but the
code is pre-alpha quality, I'll try to publish it anyway.

I've done it with server running in -legacy_renegotiation mode, but I'm not
sure if this can have any impact on it.

--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic


_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl-dev] [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
In reply to this post by Rich Salz via RT
On Thursday 19 February 2015 13:48:43 Hubert Kario wrote:

> On Wednesday 18 February 2015 23:49:39 Stephen Henson via RT wrote:
> > On Wed Feb 18 21:12:09 2015, [hidden email] wrote:
> > > I ran into this problem while connecting to a PostgreSQL server
> > > (PostgreSQL uses OpenSSL
> > > for SSL support) with a Java client using
> > > the PostgreSQL JDBC driver (which uses
> > > the Java Secure Socket
> > > Extension which is part of Oracle's Java Runtime Environment).
> > > Since database connections are potentially long-lived, the PostgreSQL
> > > server will
> > > trigger a renegotiation after a certain amount of data
> > > has been exchanged via the
> > > TLS channel; this amount is configurable
> > > with the parameter "ssl_renegotiation_limit".
> > >
> > > This renegotiation is
> > > always aborted by OpenSSL with the error "unexpected record".
> > > I could
> > > reproduce the problem with OpenSSL 1.0.1e on Linux and OpenSSL 1.0.1j
> > > on
> > > Windows using Oracle JRE 1.7.0_71 and 1.7.0_75 on the client side.
> > > The protocol version in effect is TLS 1.2 (0x303).
> >
> > There were some fixes related to renegotiation handling in OpenSSL which
> > first appeared in 1.0.1k. Can you see if this problem still happens in the
> > latest version of OpenSSL?
>
> I was able to reproduce this issue on master, OpenSSL_1_0_2-stable and
> OpenSSL_1_0_1-stable branches as of *now* (2015-02-19).
>
> I have a standalone (python - tlsfuzzer/tlslite) reproducer for that, but
> the code is pre-alpha quality, I'll try to publish it anyway.
>
> I've done it with server running in -legacy_renegotiation mode, but I'm not
> sure if this can have any impact on it.

Ok, the reproducer is available:
openssl req -x509 -newkey rsa:1024 -keyout localhost.key -out localhost.crt \
-subj /CN=localhost -nodes -batch -sha1
openssl s_server -key /tmp/localhost.key -cert /tmp/localhost.crt \
-legacy_renegotiation

In another console:
git clone https://github.com/tomato42/tlslite-1.git --branch ort-3712
git clone https://github.com/tomato42/tlsfuzzer.git
cd tlsfuzzer
PYTHONPATH=.:../tlslite-1/ python scripts/test-tls-server.py

That will cause the openssl process to report:
140090260403872:error:140940F5:SSL routines:ssl3_read_bytes:unexpected
record:s3_pkt.c:1610:

You'll need python 2.6, 3.2 or later (though I haven't verified if this exact
reproducer works on 2.6, so 2.7 is recommended)
--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic


_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
In reply to this post by Rich Salz via RT
I have made the reproducer cleaner and it should use relatively stable
API's of tlsfuzzer now.

openssl req -x509 -newkey rsa -keyout localhost.key -out localhost.crt\
-nodes -batch
~/dev/openssl/apps/openssl s_server -key localhost.key -cert\
localhost.crt

pip install --pre tlslite-ng
git clone https://github.com/tomato42/tlsfuzzer.git

cd tlsfuzzer
PYTHONPATH=. python scripts/test-openssl-3712.py

--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

signature.asc (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Matt Caswell-2


On 24/09/15 21:40, Hubert Kario via RT wrote:

> I have made the reproducer cleaner and it should use relatively stable
> API's of tlsfuzzer now.
>
> openssl req -x509 -newkey rsa -keyout localhost.key -out localhost.crt\
> -nodes -batch
> ~/dev/openssl/apps/openssl s_server -key localhost.key -cert\
> localhost.crt
>
> pip install --pre tlslite-ng
> git clone https://github.com/tomato42/tlsfuzzer.git
>
> cd tlsfuzzer
> PYTHONPATH=. python scripts/test-openssl-3712.py
This is really nice! Thanks Hubert.

I've been looking into this issue. The reason this fails is because at
some point in the past there has been an explicit design decision to
disallow it. The relevant code is here:

        /*
         * At this point, we were expecting handshake data, but have
         * application data.  If the library was running inside ssl3_read()
         * (i.e. in_read_app_data is set) and it makes sense to read
         * application data at this point (session renegotiation not yet
         * started), we will indulge it.
         */
        if (s->s3->in_read_app_data &&
            (s->s3->total_renegotiations != 0) &&
            (((s->state & SSL_ST_CONNECT) &&
              (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
              (s->state <= SSL3_ST_CR_SRVR_HELLO_A)
             ) || ((s->state & SSL_ST_ACCEPT) &&
                   (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
                   (s->state >= SSL3_ST_SR_CLNT_HELLO_A)
             )
            )) {
            s->s3->in_read_app_data = 2;
            return (-1);
        } else {
            al = SSL_AD_UNEXPECTED_MESSAGE;
            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
            goto f_err;
        }

So to pull this conditional apart a bit:

s->s3->in_read_app_data : we were originally called by SSL_read

AND

s->s3->total_renegotiations != 0 : we have started at least one
renegotiation at some point (*see below)

AND

(
  ((s->state & SSL_ST_CONNECT) &&
  (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
  (s->state <= SSL3_ST_CR_SRVR_HELLO_A) : we are a client and are in a
  state where we have started to write/have finished writing a
  ClientHello out but have not yet received a ServerHello.

  OR

  (s->state & SSL_ST_ACCEPT) &&
  (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
  (s->state >= SSL3_ST_SR_CLNT_HELLO_A) : we are a server and are about
to write a HelloVerifyRequest, or we are in the process of reading a
ClientHello

)


Aside from whether this is the correct logic or not I think there is a
related bug here in the total_renegotiations value. I believe this is
intended to count up the number of renegotiations that have occurred. As
far as I can determine this is incremented when:
- There is an explicit call to SSL_renegotiate() or
SSL_renegotiate_abbreviated()
OR
- As a client we initiate a renegotiation following receipt of a
HelloRequest

So it does not seem to get incremented when, as a server and after the
initial handshake has completed, we receive an unsolicited ClientHello,
i.e. client initiated renegotiation as in your reproducer code. This
alone is sufficient for your test case to fail, but even fixing it won't
solve the problem due to the intent of the logic above.

The above logic can be traced back to this commit:

commit b35e9050f282c5ea2164bd5b08ed34d03accf45f
Author:     Bodo Möller <[hidden email]>
AuthorDate: Sun Feb 20 23:04:06 2000 +0000
Commit:     Bodo Möller <[hidden email]>
CommitDate: Sun Feb 20 23:04:06 2000 +0000

    Tolerate fragmentation and interleaving in the SSL 3/TLS record layer.


Note the date of February 2000! The OP correctly cites RFC 5246 (TLS1.2)
and RFC 4346 (TLS1.1) as follows:

   Note: Data of different TLS Record layer content types MAY be
   interleaved.  Application data is generally of lower precedence for
   transmission than other content types.  However, records MUST be
   delivered to the network in the same order as they are protected by
   the record layer.  Recipients MUST receive and process interleaved
   application layer traffic during handshakes subsequent to the first
   one on a connection.

As the OP also observes:
"The last sentence clearly puts the blame on OpenSSL.
This seems to be an addition in TLS 1.1 since it cannot be found in RFC
2246."

Clearly the code commit pre-dates the publication of TLS1.1 (April 2006)
and is a carry over from the ambiguous situation as it is in TLS1.0.
Therefore this does seem to be an OpenSSL bug.

However, I have some concerns with the wording of the RFC. It seems to
place no limits whatsoever on when it is valid to receive app data in
the handshake. By the wording in the RFC it would be valid for app data
to be received *after* the ChangeCipherSpec has been received but
*before* the Finished has been processed. This seems dangerous to me
because it is not until the Finished is processed that we verify the
handshake data MAC - and yet we could already have acted upon app data
received. I assume the intent was to allow the interleaved app data only
up until the point that the CCS is received. I have attached a patch for
1.0.2 that implements that logic.

Matt


_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

interleave-data-102.patch (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT


On 24/09/15 21:40, Hubert Kario via RT wrote:

> I have made the reproducer cleaner and it should use relatively stable
> API's of tlsfuzzer now.
>
> openssl req -x509 -newkey rsa -keyout localhost.key -out localhost.crt\
> -nodes -batch
> ~/dev/openssl/apps/openssl s_server -key localhost.key -cert\
> localhost.crt
>
> pip install --pre tlslite-ng
> git clone https://github.com/tomato42/tlsfuzzer.git
>
> cd tlsfuzzer
> PYTHONPATH=. python scripts/test-openssl-3712.py
This is really nice! Thanks Hubert.

I've been looking into this issue. The reason this fails is because at
some point in the past there has been an explicit design decision to
disallow it. The relevant code is here:

        /*
         * At this point, we were expecting handshake data, but have
         * application data.  If the library was running inside ssl3_read()
         * (i.e. in_read_app_data is set) and it makes sense to read
         * application data at this point (session renegotiation not yet
         * started), we will indulge it.
         */
        if (s->s3->in_read_app_data &&
            (s->s3->total_renegotiations != 0) &&
            (((s->state & SSL_ST_CONNECT) &&
              (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
              (s->state <= SSL3_ST_CR_SRVR_HELLO_A)
             ) || ((s->state & SSL_ST_ACCEPT) &&
                   (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
                   (s->state >= SSL3_ST_SR_CLNT_HELLO_A)
             )
            )) {
            s->s3->in_read_app_data = 2;
            return (-1);
        } else {
            al = SSL_AD_UNEXPECTED_MESSAGE;
            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
            goto f_err;
        }

So to pull this conditional apart a bit:

s->s3->in_read_app_data : we were originally called by SSL_read

AND

s->s3->total_renegotiations != 0 : we have started at least one
renegotiation at some point (*see below)

AND

(
  ((s->state & SSL_ST_CONNECT) &&
  (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
  (s->state <= SSL3_ST_CR_SRVR_HELLO_A) : we are a client and are in a
  state where we have started to write/have finished writing a
  ClientHello out but have not yet received a ServerHello.

  OR

  (s->state & SSL_ST_ACCEPT) &&
  (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
  (s->state >= SSL3_ST_SR_CLNT_HELLO_A) : we are a server and are about
to write a HelloVerifyRequest, or we are in the process of reading a
ClientHello

)


Aside from whether this is the correct logic or not I think there is a
related bug here in the total_renegotiations value. I believe this is
intended to count up the number of renegotiations that have occurred. As
far as I can determine this is incremented when:
- There is an explicit call to SSL_renegotiate() or
SSL_renegotiate_abbreviated()
OR
- As a client we initiate a renegotiation following receipt of a
HelloRequest

So it does not seem to get incremented when, as a server and after the
initial handshake has completed, we receive an unsolicited ClientHello,
i.e. client initiated renegotiation as in your reproducer code. This
alone is sufficient for your test case to fail, but even fixing it won't
solve the problem due to the intent of the logic above.

The above logic can be traced back to this commit:

commit b35e9050f282c5ea2164bd5b08ed34d03accf45f
Author:     Bodo Möller <[hidden email]>
AuthorDate: Sun Feb 20 23:04:06 2000 +0000
Commit:     Bodo Möller <[hidden email]>
CommitDate: Sun Feb 20 23:04:06 2000 +0000

    Tolerate fragmentation and interleaving in the SSL 3/TLS record layer.


Note the date of February 2000! The OP correctly cites RFC 5246 (TLS1.2)
and RFC 4346 (TLS1.1) as follows:

   Note: Data of different TLS Record layer content types MAY be
   interleaved.  Application data is generally of lower precedence for
   transmission than other content types.  However, records MUST be
   delivered to the network in the same order as they are protected by
   the record layer.  Recipients MUST receive and process interleaved
   application layer traffic during handshakes subsequent to the first
   one on a connection.

As the OP also observes:
"The last sentence clearly puts the blame on OpenSSL.
This seems to be an addition in TLS 1.1 since it cannot be found in RFC
2246."

Clearly the code commit pre-dates the publication of TLS1.1 (April 2006)
and is a carry over from the ambiguous situation as it is in TLS1.0.
Therefore this does seem to be an OpenSSL bug.

However, I have some concerns with the wording of the RFC. It seems to
place no limits whatsoever on when it is valid to receive app data in
the handshake. By the wording in the RFC it would be valid for app data
to be received *after* the ChangeCipherSpec has been received but
*before* the Finished has been processed. This seems dangerous to me
because it is not until the Finished is processed that we verify the
handshake data MAC - and yet we could already have acted upon app data
received. I assume the intent was to allow the interleaved app data only
up until the point that the CCS is received. I have attached a patch for
1.0.2 that implements that logic.

Matt



_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

interleave-data-102.patch (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
In reply to this post by Matt Caswell-2
On Friday 25 September 2015 10:47:42 Matt Caswell wrote:

> However, I have some concerns with the wording of the RFC. It seems to
> place no limits whatsoever on when it is valid to receive app data in
> the handshake. By the wording in the RFC it would be valid for app
> data to be received *after* the ChangeCipherSpec has been received
> but *before* the Finished has been processed. This seems dangerous to
> me because it is not until the Finished is processed that we verify
> the handshake data MAC - and yet we could already have acted upon app
> data received. I assume the intent was to allow the interleaved app
> data only up until the point that the CCS is received. I have
> attached a patch for 1.0.2 that implements that logic.
yes, I think the only place in which the handshake protocol and
application data _can't_ be interleaved is between the CCS and Finished.

Or in other words, the following sections from RFC 5246 apply:

   Application data MUST NOT be sent prior to the
   completion of the first handshake (before a cipher suite other than
   TLS_NULL_WITH_NULL_NULL is established).

and:

      A Finished message is always sent immediately after a change
      cipher spec message to verify that the key exchange and
      authentication processes were successful.

and:

   It is a fatal error if a Finished message is not preceded by a
   ChangeCipherSpec message at the appropriate point in the handshake.

isn't overruled by:

   Recipients MUST receive and process interleaved
   application layer traffic during handshakes subsequent to the first
   one on a connection.
--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

signature.asc (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Matt Caswell-2


On 25/09/15 11:25, Hubert Kario via RT wrote:
>
>       A Finished message is always sent immediately after a change
>       cipher spec message to verify that the key exchange and
>       authentication processes were successful.

This is perhaps the key statement. It could do with being more explicit
if the intent here is to disallow interleaved app data.

Matt

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Matt Caswell-2
In reply to this post by Rich Salz via RT


On 25/09/15 11:25, Hubert Kario via RT wrote:

> On Friday 25 September 2015 10:47:42 Matt Caswell wrote:
>> However, I have some concerns with the wording of the RFC. It seems to
>> place no limits whatsoever on when it is valid to receive app data in
>> the handshake. By the wording in the RFC it would be valid for app
>> data to be received *after* the ChangeCipherSpec has been received
>> but *before* the Finished has been processed. This seems dangerous to
>> me because it is not until the Finished is processed that we verify
>> the handshake data MAC - and yet we could already have acted upon app
>> data received. I assume the intent was to allow the interleaved app
>> data only up until the point that the CCS is received. I have
>> attached a patch for 1.0.2 that implements that logic.
>
> yes, I think the only place in which the handshake protocol and
> application data _can't_ be interleaved is between the CCS and Finished.

It would be nice to have a test for that wouldn't it ;-)

Matt

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Karthikeyan Bhargavan
During renegotiation, app data should not appear between CCS and finished, but some implementations (e.g. NSS) do allow this.
I would consider it a state machine bug, although finding a serious exploit is not so easy.

> On 25 Sep 2015, at 12:40, Matt Caswell <[hidden email]> wrote:
>
>
>
> On 25/09/15 11:25, Hubert Kario via RT wrote:
>> On Friday 25 September 2015 10:47:42 Matt Caswell wrote:
>>> However, I have some concerns with the wording of the RFC. It seems to
>>> place no limits whatsoever on when it is valid to receive app data in
>>> the handshake. By the wording in the RFC it would be valid for app
>>> data to be received *after* the ChangeCipherSpec has been received
>>> but *before* the Finished has been processed. This seems dangerous to
>>> me because it is not until the Finished is processed that we verify
>>> the handshake data MAC - and yet we could already have acted upon app
>>> data received. I assume the intent was to allow the interleaved app
>>> data only up until the point that the CCS is received. I have
>>> attached a patch for 1.0.2 that implements that logic.
>>
>> yes, I think the only place in which the handshake protocol and
>> application data _can't_ be interleaved is between the CCS and Finished.
>
> It would be nice to have a test for that wouldn't it ;-)
>
> Matt
>
> _______________________________________________
> openssl-dev mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Hubert Kario
In reply to this post by Matt Caswell-2
On Friday 25 September 2015 11:40:27 Matt Caswell wrote:

> On 25/09/15 11:25, Hubert Kario via RT wrote:
> > On Friday 25 September 2015 10:47:42 Matt Caswell wrote:
> >> However, I have some concerns with the wording of the RFC. It seems
> >> to place no limits whatsoever on when it is valid to receive app
> >> data in the handshake. By the wording in the RFC it would be valid
> >> for app data to be received *after* the ChangeCipherSpec has been
> >> received but *before* the Finished has been processed. This seems
> >> dangerous to me because it is not until the Finished is processed
> >> that we verify the handshake data MAC - and yet we could already
> >> have acted upon app data received. I assume the intent was to
> >> allow the interleaved app data only up until the point that the
> >> CCS is received. I have attached a patch for 1.0.2 that implements
> >> that logic.
> >
> > yes, I think the only place in which the handshake protocol and
> > application data _can't_ be interleaved is between the CCS and
> > Finished.
> It would be nice to have a test for that wouldn't it ;-)
yeah, but it will be hard to do, you know, with it requiring an TLS
implementation to misbehave ;)

I'll make one as soon as I'll finish the test cases for record layer
fragmentation of initial Client Hello (there are few bugs there too)

--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Hubert Kario
In reply to this post by Karthikeyan Bhargavan
On Friday 25 September 2015 12:42:14 Karthikeyan Bhargavan wrote:
> During renegotiation, app data should not appear between CCS and
> finished, but some implementations (e.g. NSS) do allow this. I would
> consider it a state machine bug, although finding a serious exploit
> is not so easy.

while it is not easy, patching it up before it is exploitable is a good
idea.

And besides, we already had enough issues with clients and servers
incorrectly attaching data to wrong authentication info.
Some implementations may think that stuff before Finished is from new
connection while others that it is from old connection.

I'll file that bug as soon as I have a reproducer for it (most likely
today)
--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Hubert Kario
In reply to this post by Hubert Kario
On Friday 25 September 2015 14:20:40 Hubert Kario wrote:

> On Friday 25 September 2015 11:40:27 Matt Caswell wrote:
> > On 25/09/15 11:25, Hubert Kario via RT wrote:
> > > On Friday 25 September 2015 10:47:42 Matt Caswell wrote:
> > >> However, I have some concerns with the wording of the RFC. It
> > >> seems
> > >> to place no limits whatsoever on when it is valid to receive app
> > >> data in the handshake. By the wording in the RFC it would be
> > >> valid
> > >> for app data to be received *after* the ChangeCipherSpec has been
> > >> received but *before* the Finished has been processed. This seems
> > >> dangerous to me because it is not until the Finished is processed
> > >> that we verify the handshake data MAC - and yet we could already
> > >> have acted upon app data received. I assume the intent was to
> > >> allow the interleaved app data only up until the point that the
> > >> CCS is received. I have attached a patch for 1.0.2 that
> > >> implements
> > >> that logic.
> > >
> > > yes, I think the only place in which the handshake protocol and
> > > application data _can't_ be interleaved is between the CCS and
> > > Finished.
> >
> > It would be nice to have a test for that wouldn't it ;-)
>
> yeah, but it will be hard to do, you know, with it requiring an TLS
> implementation to misbehave ;)
>
> I'll make one as soon as I'll finish the test cases for record layer
> fragmentation of initial Client Hello (there are few bugs there too)
and done, in the same repo just run
scripts/test-interleaved-application-data-in-renegotiation.py
--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
In reply to this post by Rich Salz via RT
Matt Caswell wrote:
> I've been looking into this issue. The reason this fails is because at
> some point in the past there has been an explicit design decision to
> disallow it.

Thank you for your work!
I agree with your analysis.

> However, I have some concerns with the wording of the RFC. It seems to
> place no limits whatsoever on when it is valid to receive app data in
> the handshake. By the wording in the RFC it would be valid for app data
> to be received *after* the ChangeCipherSpec has been received but
> *before* the Finished has been processed. This seems dangerous to me
> because it is not until the Finished is processed that we verify the
> handshake data MAC - and yet we could already have acted upon app data
> received. I assume the intent was to allow the interleaved app data only
> up until the point that the CCS is received. I have attached a patch for
> 1.0.2 that implements that logic.

The RFC writes:

   Note: If a rehandshake occurs while data is flowing on a connection,
   the communicating parties may continue to send data using the old
   CipherSpec.  However, once the ChangeCipherSpec has been sent, the
   new CipherSpec MUST be used.  The first side to send the
   ChangeCipherSpec does not know that the other side has finished
   computing the new keying material (e.g., if it has to perform a
   time-consuming public key operation).  Thus, a small window of time,
   during which the recipient must buffer the data, MAY exist.  In
   practice, with modern machines this interval is likely to be fairly
   short.

Could that be interpreted to mean that the recepient should buffer
all incoming Application Data messages that are sent between
ChangeCipherSpec and Finished?

However that may be, I tested your patch with PostgreSQL 9.4.4 and
OpenJDK 1.7.0_85 and it solves my problem, so it seems like Java does not
try to send Application Data between ChangeCipherSpec and Finished.

If that patch gets applied, I expect it will make it into all active
branches, right?

If this bug gets closed, #2481 should probably get closed too.

Yours,
Laurenz Albe

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT


On 28/09/15 12:35, Albe Laurenz via RT wrote:

> Matt Caswell wrote:
>> I've been looking into this issue. The reason this fails is because at
>> some point in the past there has been an explicit design decision to
>> disallow it.
>
> Thank you for your work!
> I agree with your analysis.
>
>> However, I have some concerns with the wording of the RFC. It seems to
>> place no limits whatsoever on when it is valid to receive app data in
>> the handshake. By the wording in the RFC it would be valid for app data
>> to be received *after* the ChangeCipherSpec has been received but
>> *before* the Finished has been processed. This seems dangerous to me
>> because it is not until the Finished is processed that we verify the
>> handshake data MAC - and yet we could already have acted upon app data
>> received. I assume the intent was to allow the interleaved app data only
>> up until the point that the CCS is received. I have attached a patch for
>> 1.0.2 that implements that logic.
>
> The RFC writes:
>
>    Note: If a rehandshake occurs while data is flowing on a connection,
>    the communicating parties may continue to send data using the old
>    CipherSpec.  However, once the ChangeCipherSpec has been sent, the
>    new CipherSpec MUST be used.  The first side to send the
>    ChangeCipherSpec does not know that the other side has finished
>    computing the new keying material (e.g., if it has to perform a
>    time-consuming public key operation).  Thus, a small window of time,
>    during which the recipient must buffer the data, MAY exist.  In
>    practice, with modern machines this interval is likely to be fairly
>    short.
>
> Could that be interpreted to mean that the recepient should buffer
> all incoming Application Data messages that are sent between
> ChangeCipherSpec and Finished?

Thanks. I had missed that wording. I think this means that as soon as
the first party sends a CCS, they must not send any app data until they
have received a CCS back (they must buffer it until the CCS is seen). So
the second party should never expect to see app data between CCS and
Finished. It doesn't tell you anything about what the first party can
expect though, i.e. is the second party allowed to send app data between
the CCS and Finished?

>
> However that may be, I tested your patch with PostgreSQL 9.4.4 and
> OpenJDK 1.7.0_85 and it solves my problem, so it seems like Java does not
> try to send Application Data between ChangeCipherSpec and Finished.
>
> If that patch gets applied, I expect it will make it into all active
> branches, right?

Well, that depends what you mean be active. 1.0.0 and 0.9.8 are only
receiving security fixes at the moment so this patch would not be
applied to those branches. It should be applied to master, 1.0.2 and
1.0.1. The patch is currently awaiting internal review.

>
> If this bug gets closed, #2481 should probably get closed too.

I just closed it with a message pointing at this ticket. No point in
having both open.

Matt


_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Albe Laurenz
Matt Caswell wrote:

> On 28/09/15 12:35, Albe Laurenz via RT wrote:
>> Matt Caswell wrote:
>>> However, I have some concerns with the wording of the RFC. It seems to
>>> place no limits whatsoever on when it is valid to receive app data in
>>> the handshake. By the wording in the RFC it would be valid for app data
>>> to be received *after* the ChangeCipherSpec has been received but
>>> *before* the Finished has been processed. This seems dangerous to me
>>> because it is not until the Finished is processed that we verify the
>>> handshake data MAC - and yet we could already have acted upon app data
>>> received. I assume the intent was to allow the interleaved app data only
>>> up until the point that the CCS is received. I have attached a patch for
>>> 1.0.2 that implements that logic.

>> The RFC writes:
>>
>>    Note: If a rehandshake occurs while data is flowing on a connection,
>>    the communicating parties may continue to send data using the old
>>    CipherSpec.  However, once the ChangeCipherSpec has been sent, the
>>    new CipherSpec MUST be used.  The first side to send the
>>    ChangeCipherSpec does not know that the other side has finished
>>    computing the new keying material (e.g., if it has to perform a
>>    time-consuming public key operation).  Thus, a small window of time,
>>    during which the recipient must buffer the data, MAY exist.  In
>>    practice, with modern machines this interval is likely to be fairly
>>    short.
>>
>> Could that be interpreted to mean that the recepient should buffer
>> all incoming Application Data messages that are sent between
>> ChangeCipherSpec and Finished?

> Thanks. I had missed that wording. I think this means that as soon as
> the first party sends a CCS, they must not send any app data until they
> have received a CCS back (they must buffer it until the CCS is seen). So
> the second party should never expect to see app data between CCS and
> Finished. It doesn't tell you anything about what the first party can
> expect though, i.e. is the second party allowed to send app data between
> the CCS and Finished?

Interesting how we can read this so differently.
If anything, that confirms that the wording of the RFC is suboptimal.

It is probably both convenient and sensible to follow the following
sentence of the RFC, as you have done:

      A Finished message is always sent immediately after a change
      cipher spec message to verify that the key exchange and
      authentication processes were successful.

This may well be interpreted as "no Application Data records may
be sent between CCS and Finished".

Yours,
Laurenz Albe
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
Matt Caswell wrote:

> On 28/09/15 12:35, Albe Laurenz via RT wrote:
>> Matt Caswell wrote:
>>> However, I have some concerns with the wording of the RFC. It seems to
>>> place no limits whatsoever on when it is valid to receive app data in
>>> the handshake. By the wording in the RFC it would be valid for app data
>>> to be received *after* the ChangeCipherSpec has been received but
>>> *before* the Finished has been processed. This seems dangerous to me
>>> because it is not until the Finished is processed that we verify the
>>> handshake data MAC - and yet we could already have acted upon app data
>>> received. I assume the intent was to allow the interleaved app data only
>>> up until the point that the CCS is received. I have attached a patch for
>>> 1.0.2 that implements that logic.

>> The RFC writes:
>>
>>    Note: If a rehandshake occurs while data is flowing on a connection,
>>    the communicating parties may continue to send data using the old
>>    CipherSpec.  However, once the ChangeCipherSpec has been sent, the
>>    new CipherSpec MUST be used.  The first side to send the
>>    ChangeCipherSpec does not know that the other side has finished
>>    computing the new keying material (e.g., if it has to perform a
>>    time-consuming public key operation).  Thus, a small window of time,
>>    during which the recipient must buffer the data, MAY exist.  In
>>    practice, with modern machines this interval is likely to be fairly
>>    short.
>>
>> Could that be interpreted to mean that the recepient should buffer
>> all incoming Application Data messages that are sent between
>> ChangeCipherSpec and Finished?

> Thanks. I had missed that wording. I think this means that as soon as
> the first party sends a CCS, they must not send any app data until they
> have received a CCS back (they must buffer it until the CCS is seen). So
> the second party should never expect to see app data between CCS and
> Finished. It doesn't tell you anything about what the first party can
> expect though, i.e. is the second party allowed to send app data between
> the CCS and Finished?

Interesting how we can read this so differently.
If anything, that confirms that the wording of the RFC is suboptimal.

It is probably both convenient and sensible to follow the following
sentence of the RFC, as you have done:

      A Finished message is always sent immediately after a change
      cipher spec message to verify that the key exchange and
      authentication processes were successful.

This may well be interpreted as "no Application Data records may
be sent between CCS and Finished".

Yours,
Laurenz Albe

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
In reply to this post by Albe Laurenz
On Wednesday 30 September 2015 09:37:37 Albe Laurenz wrote:

> Matt Caswell wrote:
> > On 28/09/15 12:35, Albe Laurenz via RT wrote:
> >> Matt Caswell wrote:
> >>> However, I have some concerns with the wording of the RFC. It
> >>> seems to place no limits whatsoever on when it is valid to
> >>> receive app data in the handshake. By the wording in the RFC it
> >>> would be valid for app data to be received *after* the
> >>> ChangeCipherSpec has been received but *before* the Finished has
> >>> been processed. This seems dangerous to me because it is not
> >>> until the Finished is processed that we verify the handshake data
> >>> MAC - and yet we could already have acted upon app data received.
> >>> I assume the intent was to allow the interleaved app data only up
> >>> until the point that the CCS is received. I have attached a patch
> >>> for 1.0.2 that implements that logic.
> >>
> >> The RFC writes:
> >>    Note: If a rehandshake occurs while data is flowing on a
> >>    connection,
> >>    the communicating parties may continue to send data using the
> >>    old
> >>    CipherSpec.  However, once the ChangeCipherSpec has been sent,
> >>    the
> >>    new CipherSpec MUST be used.  The first side to send the
> >>    ChangeCipherSpec does not know that the other side has finished
> >>    computing the new keying material (e.g., if it has to perform a
> >>    time-consuming public key operation).  Thus, a small window of
> >>    time,
> >>    during which the recipient must buffer the data, MAY exist.  In
> >>    practice, with modern machines this interval is likely to be
> >>    fairly
> >>    short.
> >>
> >> Could that be interpreted to mean that the recepient should buffer
> >> all incoming Application Data messages that are sent between
> >> ChangeCipherSpec and Finished?
> >
> > Thanks. I had missed that wording. I think this means that as soon
> > as
> > the first party sends a CCS, they must not send any app data until
> > they have received a CCS back (they must buffer it until the CCS is
> > seen). So the second party should never expect to see app data
> > between CCS and Finished. It doesn't tell you anything about what
> > the first party can expect though, i.e. is the second party allowed
> > to send app data between the CCS and Finished?
>
> Interesting how we can read this so differently.
> If anything, that confirms that the wording of the RFC is suboptimal.
I'd interpret it as not talking about the client's ability to send data
but rather about latency observed by application layer. In other words
about such situation:

<snip>
      ClientKeyExchange
      [ChangeCipherSpec]
      Finished
      Application Data[1]          -------->
                                               [ChangeCipherSpec]
                                   <--------             Finished
      Application Data[2]          <------->     Application Data

and how the data [1] will be received by other side's application later
than if it wasn't sent during a handshake
--
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

signature.asc (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Karthikeyan Bhargavan
A simpler interpretation would be that application data should never be sent or
received with sequence number = 0; only finished messages may have this sequence number.
For connections with NPN enabled, we may need a slightly more complex rule.

In TLS we can also assume that encrypted fragments will not be accepted out of sequence. Perhaps DTLS violates this sequentiality? In which case, the interpretation of the CCS - Finished - AppData ordering becomes more difficult to enforce for DTLS.

-K.

I'd interpret it as not talking about the client's ability to send data 
but rather about latency observed by application layer. In other words 
about such situation:

<snip>
     ClientKeyExchange
     [ChangeCipherSpec]
     Finished
     Application Data[1]          -------->
                                              [ChangeCipherSpec]
                                  <--------             Finished
     Application Data[2]          <------->     Application Data

and how the data [1] will be received by other side's application later 
than if it wasn't sent during a handshake
-- 
Regards,
Hubert Kario
Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic
<signature.asc>_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

signature.asc (507 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [openssl.org #3712] TLS Renegotiation with Java is broken

Rich Salz via RT
A simpler interpretation would be that application data should never be sent or
received with sequence number = 0; only finished messages may have this sequence number.
For connections with NPN enabled, we may need a slightly more complex rule.

In TLS we can also assume that encrypted fragments will not be accepted out of sequence. Perhaps DTLS violates this sequentiality? In which case, the interpretation of the CCS - Finished - AppData ordering becomes more difficult to enforce for DTLS.

-K.

> I'd interpret it as not talking about the client's ability to send data
> but rather about latency observed by application layer. In other words
> about such situation:
>
> <snip>
>      ClientKeyExchange
>      [ChangeCipherSpec]
>      Finished
>      Application Data[1]          -------->
>                                               [ChangeCipherSpec]
>                                   <--------             Finished
>      Application Data[2]          <------->     Application Data
>
> and how the data [1] will be received by other side's application later
> than if it wasn't sent during a handshake
> --
> Regards,
> Hubert Kario
> Quality Engineer, QE BaseOS Security team
> Web: www.cz.redhat.com <http://www.cz.redhat.com/>
> Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic
> <signature.asc>_______________________________________________
> openssl-dev mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev <https://mta.openssl.org/mailman/listinfo/openssl-dev>

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

signature.asc (688 bytes) Download Attachment
1234