PR #3783 introduce coded to reset the server side SNI state in
SSL_do_handshake() to ensure any erroneous config time SNI changes are
cleared. Unfortunately SSL_do_handshake() can be called mid-handshake
multiple times so this is the wrong place to do this and can mean that
any SNI data is cleared later on in the handshake too.
Therefore move the code to a more appropriate place.
Fixes#7014
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/7149)
Commit 1c4aa31d79 modified the state machine
to clean up stale ext.hostname values from SSL objects in the case when
SNI was not negotiated for the current handshake. This is natural from
the TLS perspective, since this information is an extension that the client
offered but we ignored, and since we ignored it we do not need to keep it
around for anything else.
However, as documented in https://github.com/openssl/openssl/issues/7014 ,
there appear to be some deployed code that relies on retrieving such an
ignored SNI value from the client, after the handshake has completed.
Because the 1.1.1 release is on a stable branch and should preserve the
published ABI, restore the historical behavior by retaining the ext.hostname
value sent by the client, in the SSL structure, for subsequent retrieval.
[extended tests]
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7115)
The is_tls13_capable() function should not return 0 if no certificates
are configured directly because a certificate callback is present.
Fixes#7140
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7141)
If we've sent a close_notify then we are restricted about what we can do
in response to handshake messages that we receive. However we can sensibly
process NewSessionTicket messages. We can also process a KeyUpdate message
as long as we also ignore any request for us to update our sending keys.
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7114)
Treat a connection using an external PSK like we would a resumption and
send a single NewSessionTicket afterwards.
Fixes#6941
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7097)
If a client sends data to a server and then immediately closes without
waiting to read the NewSessionTickets then the server can receive EPIPE
when trying to write the tickets and never gets the opportunity to read
the data that was sent. Therefore we ignore EPIPE when writing out the
tickets in TLSv1.3
Fixes#6904
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6944)
We need to ensure that the min-max version range we use when constructing
the ClientHello is the same range we use when we validate the version
selected by the ServerHello. Otherwise this may appear as a fallback or
downgrade.
Fixes#6964
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7013)
Having post handshake auth automatically switched on breaks some
applications written for TLSv1.2. This changes things so that an explicit
function call is required for a client to indicate support for
post-handshake auth.
Fixes#6933.
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6938)
A client that has fallen back could detect an inappropriate fallback if
the TLSv1.3 downgrade protection sentinels are present.
Fixes#6756
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6894)
At certain points in the handshake we could receive either a plaintext or
an encrypted alert from the client. We should tolerate both where
appropriate.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6887)
If we sent early_data and then received back an HRR, the enc_write_ctx
was stale resulting in errors if an alert needed to be sent.
Thanks to Quarkslab for reporting this.
In any case it makes little sense to encrypt alerts using the
client_early_traffic_secret, so we add special handling for alerts sent
after early_data. All such alerts are sent in plaintext.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6887)
Under certain error conditions a call to SSLfatal could accidently be
missed.
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
Reviewed-by: Andy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6872)
In some scenarios the connection could fail without an alert being sent.
This causes a later assertion failure.
Thanks to Quarkslab for reporting this.
Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/6852)
In particular, adhere to the rule that we must not modify any
property of an SSL_SESSION object once it is (or might be) in
a session cache. Such modifications are thread-unsafe and have
been observed to cause crashes at runtime.
To effect this change, standardize on the property that
SSL_SESSION->ext.hostname is set only when that SNI value
has been negotiated by both parties for use with that session.
For session resumption this is trivially the case, so only new
handshakes are affected.
On the client, the new semantics are that the SSL->ext.hostname is
for storing the value configured by the caller, and this value is
used when constructing the ClientHello. On the server, SSL->ext.hostname
is used to hold the value received from the client. Only if the
SNI negotiation is successful will the hostname be stored into the
session object; the server can do this after it sends the ServerHello,
and the client after it has received and processed the ServerHello.
This obviates the need to remove the hostname from the session object
in case of failed negotiation (a change that was introduced in commit
9fb6cb810b in order to allow TLS 1.3
early data when SNI was present in the ClientHello but not the session
being resumed), which was modifying cached sessions in certain cases.
(In TLS 1.3 we always produce a new SSL_SESSION object for new
connections, even in the case of resumption, so no TLS 1.3 handshakes
were affected.)
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6378)
These tiny functions only read from the input SSL, and we are
about to use them from functions that only have a const SSL* available,
so propagate const a bit further.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6378)
The spec says that a client MUST set legacy_version to TLSv1.2, and
requires servers to verify that it isn't SSLv3.
Fixes#6600
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6747)
If we issue new tickets due to post-handshake authentication there is no
reason to remove previous tickets from the cache. The code that did that
only removed the last session anyway - so if more than one ticket got
issued then those other tickets are still valid.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6722)
Check that we are either configured for PSK, or that we have a TLSv1.3
capable certificate type. DSA certs can't be used in TLSv1.3 and we
don't (currently) allow GOST ones either (owing to the lack of standard
sig algs).
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6650)
In TLSv1.2 and below we should remove an old session from the client
session cache in the event that we receive a new session ticket from the
server.
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/6601)
During anti-replay we cache the ticket anyway, so there is no point in
using a full stateless ticket.
Fixes#6391
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6563)
Implement support for stateful TLSv1.3 tickets, and use them if
SSL_OP_NO_TICKET is set.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6563)
Separate out as a new function the code to write out data which is specific
to a stateless ticket.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6563)
Sessions should be immutable once they are in the cache because they could
be shared with other threads. If you change them then this can cause
corruptions and races
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6561)
TLSv1.3 ignores the alert level, so we should suppress sending of
warning only alerts.
Fixes#6211
Reviewed-by: Andy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6370)
We generate the secrets based on the nonce immediately so there is no
need to keep the nonce.
Reviewed-by: Andy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6415)
All tickets on a connection need to have a unique nonce. When this was
originally implemented we only ever sent one ticket on the conneciton so
this didn't matter. We were just using the value 0. Now we can get multiple
tickets to we need to start doing the ticket nonce properly.
Fixes#6387
Reviewed-by: Andy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6415)
We send a session ticket automatically in TLSv1.3 at the end of the
handshake. This commit provides the ability to set how many tickets should
be sent. By default this is one.
Fixes#4978
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5227)
In DTLS if we have buffered a fragment for a zero length message (e.g.
ServerHelloDone) then, when we unbuffered the fragment, we were attempting
to memcpy the contents of the fragment which is zero length and a NULL
pointer. This is undefined behaviour. We should check first whether we
have a zero length fragment.
Fixes a travis issue.
[extended tests]
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6223)
Don't call the decrypt ticket callback if we've already encountered a
fatal error. Do call it if we have an empty ticket present.
Change the return code to have 5 distinct returns codes and separate it
from the input status value.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6198)
The return value from the ticket_key callback was not properly handled in
TLSv1.3, so that a ticket was *always* renewed even if the callback
requested that it should not be.
Also the ticket decrypt callback was not being called at all in TLSv1.3.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6198)
During a full handshake the server is the last one to "speak". The timer
should continue to run until we know that the client has received our last
flight (e.g. because we receive some application data).
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6170)