Commit graph

206 commits

Author SHA1 Message Date
Matt Caswell
de451856f0 Address WPACKET review comments
A few style tweaks here and there. The main change is that curr and
packet_len are now offsets into the buffer to account for the fact that
the pointers can change if the buffer grows. Also dropped support for the
WPACKET_set_packet_len() function. I thought that was going to be needed
but so far it hasn't been. It doesn't really work any more due to the
offsets change.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-09-13 09:41:21 +01:00
Matt Caswell
796a627e0a Ensure the WPACKET gets cleaned up in the event of an error
Otherwise a mem leak can occur.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-09-13 09:41:21 +01:00
Matt Caswell
fb790f1673 Add WPACKET_sub_memcpy() function
Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-09-13 09:41:21 +01:00
Matt Caswell
0217dd19c0 Move from explicit sub-packets to implicit ones
No need to declare an explicit sub-packet. Just start one.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-09-13 09:41:21 +01:00
Matt Caswell
ae2f7b37da Rename PACKETW to WPACKET
To avoid confusion with the read PACKET structure.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-09-13 09:41:21 +01:00
Matt Caswell
2c7b4dbc1a Convert tls_construct_client_hello() to use PACKETW
Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-09-13 09:41:21 +01:00
Matt Caswell
f046afb066 Ensure the CertStatus message adds a DTLS message header where needed
The function tls_construct_cert_status() is called by both TLS and DTLS
code. However it only ever constructed a TLS message header for the message
which obviously failed in DTLS.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-08-30 11:32:49 +01:00
Matt Caswell
2f3930bc0e Fix leak on error in tls_construct_cke_gost
Don't leak pke_ctx on error.

Reviewed-by: Tim Hudson <tjh@openssl.org>
2016-08-23 00:19:15 +01:00
Matt Caswell
f5c7f5dfba Fix DTLS buffered message DoS attack
DTLS can handle out of order record delivery. Additionally since
handshake messages can be bigger than will fit into a single packet, the
messages can be fragmented across multiple records (as with normal TLS).
That means that the messages can arrive mixed up, and we have to
reassemble them. We keep a queue of buffered messages that are "from the
future", i.e. messages we're not ready to deal with yet but have arrived
early. The messages held there may not be full yet - they could be one
or more fragments that are still in the process of being reassembled.

The code assumes that we will eventually complete the reassembly and
when that occurs the complete message is removed from the queue at the
point that we need to use it.

However, DTLS is also tolerant of packet loss. To get around that DTLS
messages can be retransmitted. If we receive a full (non-fragmented)
message from the peer after previously having received a fragment of
that message, then we ignore the message in the queue and just use the
non-fragmented version. At that point the queued message will never get
removed.

Additionally the peer could send "future" messages that we never get to
in order to complete the handshake. Each message has a sequence number
(starting from 0). We will accept a message fragment for the current
message sequence number, or for any sequence up to 10 into the future.
However if the Finished message has a sequence number of 2, anything
greater than that in the queue is just left there.

So, in those two ways we can end up with "orphaned" data in the queue
that will never get removed - except when the connection is closed. At
that point all the queues are flushed.

An attacker could seek to exploit this by filling up the queues with
lots of large messages that are never going to be used in order to
attempt a DoS by memory exhaustion.

I will assume that we are only concerned with servers here. It does not
seem reasonable to be concerned about a memory exhaustion attack on a
client. They are unlikely to process enough connections for this to be
an issue.

A "long" handshake with many messages might be 5 messages long (in the
incoming direction), e.g. ClientHello, Certificate, ClientKeyExchange,
CertificateVerify, Finished. So this would be message sequence numbers 0
to 4. Additionally we can buffer up to 10 messages in the future.
Therefore the maximum number of messages that an attacker could send
that could get orphaned would typically be 15.

The maximum size that a DTLS message is allowed to be is defined by
max_cert_list, which by default is 100k. Therefore the maximum amount of
"orphaned" memory per connection is 1500k.

Message sequence numbers get reset after the Finished message, so
renegotiation will not extend the maximum number of messages that can be
orphaned per connection.

As noted above, the queues do get cleared when the connection is closed.
Therefore in order to mount an effective attack, an attacker would have
to open many simultaneous connections.

Issue reported by Quan Luo.

CVE-2016-2179

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-08-22 10:53:55 +01:00
Emilia Kasper
a230b26e09 Indent ssl/
Run util/openssl-format-source on ssl/

Some comments and hand-formatted tables were fixed up
manually by disabling auto-formatting.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-08-18 14:02:29 +02:00
Dr. Stephen Henson
2e5ead831b Constify ssl_cert_type()
Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-08-17 15:49:44 +01:00
Dr. Stephen Henson
8900f3e398 Convert X509* functions to use const getters
Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-08-17 13:59:04 +01:00
Dr. Stephen Henson
0a699a0723 Fix no-ec
Fix no-ec builds by having separate functions to create keys based on
an existing EVP_PKEY and a curve id.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-08-15 14:07:33 +01:00
Dr. Stephen Henson
ec24630ae2 Modify TLS support for new X25519 API.
When handling ECDH check to see if the curve is "custom" (X25519 is
currently the only curve of this type) and instead of setting a curve
NID just allocate a key of appropriate type.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-08-13 14:11:05 +01:00
klemens
6025001707 spelling fixes, just comments and readme.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1413)
2016-08-05 19:07:30 -04:00
David Woodhouse
032924c4b4 Make DTLS1_BAD_VER work with DTLS_client_method()
DTLSv1_client_method() is deprecated, but it was the only way to obtain
DTLS1_BAD_VER support. The SSL_OP_CISCO_ANYCONNECT hack doesn't work with
DTLS_client_method(), and it's relatively non-trivial to make it work without
expanding the hack into lots of places.

So deprecate SSL_OP_CISCO_ANYCONNECT with DTLSv1_client_method(), and make
it work with SSL_CTX_set_{min,max}_proto_version(DTLS1_BAD_VER) instead.

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
2016-08-04 20:56:24 +01:00
David Woodhouse
e6027420b7 Fix ossl_statem_client_max_message_size() for DTLS1_BAD_VER
The Change Cipher Spec message in this ancient pre-standard version of DTLS
that Cisco are unfortunately still using in their products, is 3 bytes.

Allow it.

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
2016-08-04 20:56:23 +01:00
Ben Laurie
3260adf190 peer_tmp doesn't exist if no-ec no-dh.
Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-08-01 11:30:33 +01:00
russor
78a01b3f69 zero pad DHE public key in ServerKeyExchange message for interop
Some versions of the Microsoft TLS stack have problems when the DHE public key
is encoded with fewer bytes than the DHE prime.

There's some public acknowledgement of the bug at these links:

https://connect.microsoft.com/IE/feedback/details/1253526/tls-serverkeyexchange-with-1024-dhe-may-encode-dh-y-as-127-bytes-breaking-internet-explorer-11
https://connect.microsoft.com/IE/feedback/details/1104905/wininet-calculation-of-mac-in-tls-handshake-intermittently-fails-for-dhe-rsa-key-exchange

This encoding issue also causes the same errors with 2048-bit DHE, if the
public key is encoded in fewer than 256 bytes and includes the TLS stack on
Windows Phone 8.x.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1320)
2016-07-25 13:41:33 -04:00
Richard Levitte
8b9546c708 Correct misspelt OPENSSL_NO_SRP
RT#4619

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-07-23 10:47:52 +02:00
Dr. Stephen Henson
31a7d80d0d Send alert for bad DH CKE
RT#4511

Reviewed-by: Matt Caswell <matt@openssl.org>
2016-07-22 15:55:38 +01:00
Matt Caswell
2e7dc7cd68 Never expose ssl->bbio in the public API.
This is adapted from BoringSSL commit 2f87112b963.

This fixes a number of bugs where the existence of bbio was leaked in the
public API and broke things.

- SSL_get_wbio returned the bbio during the handshake. It must always return
  the BIO the consumer configured. In doing so, some internal accesses of
  SSL_get_wbio should be switched to ssl->wbio since those want to see bbio.

- The logic in SSL_set_rfd, etc. (which I doubt is quite right since
  SSL_set_bio's lifetime is unclear) would get confused once wbio got
  wrapped. Those want to compare to SSL_get_wbio.

- If SSL_set_bio was called mid-handshake, bbio would get disconnected and
  lose state. It forgets to reattach the bbio afterwards. Unfortunately,
  Conscrypt does this a lot. It just never ended up calling it at a point
  where the bbio would cause problems.

- Make more explicit the invariant that any bbio's which exist are always
  attached. Simplify a few things as part of that.

RT#4572

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-20 13:08:08 +01:00
FdaSilvaYY
e8aa8b6c8f Fix a few if(, for(, while( inside code.
Fix some indentation at the same time

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1292)
2016-07-20 07:21:53 -04:00
Dr. Stephen Henson
fb9339827b Send alert on CKE error.
RT#4610

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-07-20 00:03:43 +01:00
Emilia Kasper
70c22888c1 Fix two bugs in clienthello processing
- Always process ALPN (previously there was an early return in the
  certificate status handling)
- Don't send a duplicate alert. Previously, both
  ssl_check_clienthello_tlsext_late and its caller would send an
  alert. Consolidate alert sending code in the caller.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-07-19 14:18:03 +02:00
Matt Caswell
4fa88861ee Update error codes following tls_process_key_exchange() refactor
Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:18:46 +01:00
Matt Caswell
e1e588acae Tidy up tls_process_key_exchange()
After the refactor of tls_process_key_exchange(), this commit tidies up
some loose ends.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:18:46 +01:00
Matt Caswell
ff74aeb1fa Split out ECDHE from tls_process_key_exchange()
Continuing from the previous commit. Refactor tls_process_key_exchange() to
split out into a separate function the ECDHE aspects.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:18:46 +01:00
Matt Caswell
e01a610db8 Split out DHE from tls_process_key_exchange()
Continuing from the previous commit. Refactor tls_process_key_exchange() to
split out into a separate function the DHE aspects.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:18:46 +01:00
Matt Caswell
25c6c10cd7 Split out SRP from tls_process_key_exchange()
Continuing from the previous commit. Refactor tls_process_key_exchange() to
split out into a separate function the SRP aspects.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:18:46 +01:00
Matt Caswell
7dc1c64774 Split out the PSK preamble from tls_process_key_exchange()
The tls_process_key_exchange() function is too long. This commit starts
the process of splitting it up by moving the PSK preamble code to a
separate function.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:18:46 +01:00
Matt Caswell
02a74590bb Move the PSK preamble for tls_process_key_exchange()
The function tls_process_key_exchange() is too long. This commit moves
the PSK preamble processing out to a separate function.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:18:46 +01:00
Matt Caswell
be8dba2c92 Narrow scope of locals vars in tls_process_key_exchange()
Narrow the scope of the local vars in preparation for split up this
function.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:18:46 +01:00
Matt Caswell
e4612d02c5 Remove sessions from external cache, even if internal cache not used.
If the SSL_SESS_CACHE_NO_INTERNAL_STORE cache mode is used then we weren't
removing sessions from the external cache, e.g. if an alert occurs the
session is supposed to be automatically removed.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-19 12:08:49 +01:00
Richard Levitte
340a282853 Fixup a few SSLerr calls in ssl/statem/
Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-07-19 11:50:31 +02:00
Matt Caswell
e3ea3afd6d Refactor Identity Hint handling
Don't call strncpy with strlen of the source as the length. Don't call
strlen multiple times. Eventually we will want to replace this with a proper
PACKET style handling (but for construction of PACKETs instead of just
reading them as it is now). For now though this is safe because
PSK_MAX_IDENTITY_LEN will always fit into the destination buffer.

This addresses an OCAP Audit issue.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:18:46 +01:00
Matt Caswell
05ec6a25f8 Fix up error codes after splitting up tls_construct_key_exchange()
Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:05:15 +01:00
Matt Caswell
a7a752285a Some tidy ups after the CKE construction refactor
Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:05:15 +01:00
Matt Caswell
840a2bf8ec Split out SRP CKE construction into a separate function
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the SRP
code.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:05:14 +01:00
Matt Caswell
e00e0b3d84 Split out GOST CKE construction into a separate function
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the GOST
code.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:05:14 +01:00
Matt Caswell
67ad5aabe6 Split out DHE CKE construction into a separate function
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the ECDHE
code.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:05:14 +01:00
Matt Caswell
a8c1c7040a Split out DHE CKE construction into a separate function
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the DHE
code.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:05:14 +01:00
Matt Caswell
13c0ec4ad4 Split out CKE construction PSK pre-amble and RSA into a separate function
The tls_construct_client_key_exchange() function is too long. This splits
out the construction of the PSK pre-amble into a separate function as well
as the RSA construction.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:05:14 +01:00
Matt Caswell
0bce0b02d8 Narrow the scope of local variables in tls_construct_client_key_exchange()
This is in preparation for splitting up this over long function.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 23:05:14 +01:00
Matt Caswell
c76a4aead2 Errors fix up following break up of CKE processing
Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 22:55:07 +01:00
Matt Caswell
9059eb711f Remove the f_err lable from tls_process_client_key_exchange()
The f_err label is no longer needed so it can be removed.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 22:55:07 +01:00
Matt Caswell
c437eef60a Split out GOST from process CKE code
Continuing from the previous commits, this splits out the GOST code into
a separate function from the process CKE code.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 22:55:07 +01:00
Matt Caswell
19ed1ec12e Split out ECDHE from process CKE code
Continuing from the previous commits, this splits out the ECDHE code into
a separate function from the process CKE code.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 22:55:07 +01:00
Matt Caswell
642360f9a3 Split out DHE from process CKE code
Continuing from the previous commit, this splits out the DHE code into
a separate function from the process CKE code.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 22:55:07 +01:00
Matt Caswell
0907d7105c Split out PSK preamble and RSA from process CKE code
The tls_process_client_key_exchange() function is far too long. This
splits out the PSK preamble processing, and the RSA processing into
separate functions.

Reviewed-by: Richard Levitte <levitte@openssl.org>
2016-07-18 22:55:07 +01:00