Return to main page

OpenSSL Bugfix and Feature patches

The files have to be applied from the source folder of OpenSSL with:

patch -p0 < /path/to/patchfile.patch

Attention OpenSSL 0.9.8 users:

Patches will no longer be backported for OpenSSL 0.9.8. The differences between the lastest stable release and the current development versions have become too many to create patches with an acceptable effort. If you still want to use 0.9.8, please use the development version available via CVS, which always includes the latest modifications:

cvs -d anonymous@cvs.openssl.org:/openssl-cvs co -r OpenSSL_0_9_8-stable openssl

We recommend switching to OpenSSL 1.0.0 as soon as possible though.

The following categories are available:



DTLS Bugfixes

Patch OpenSSL 1.0.0 beta 5 OpenSSL 0.9.8l Description
Plain text Tarball Plain text Tarball
Cumulative Bugfix Download Download not available not available This is one patch that includes all of bugfixes but no features. Don't apply the single patches too.
SessionTicket Extension (#2160) Download Download not available not available The Sessionticket extension doesn't work with DTLS. The NewSessionTicket message of the server is truncated because of a wrong calculation of the length and the server is also unable to parse the ticket attached to a ClientHello because DTLS is considered as an unknown protocol version.
DTLS Extensions (#2121) included since
beta 5
included since
beta 5
not available not available Adds the renegotiation (now mandatory for security reasons), servername and session ticket extensions to DTLS.
IPv6 issues (#2110 & #2114) included since
beta 5
included since
beta 5
not needed not needed Changes IPv6 integration to a more elegant solution and fixes some sockaddr size issues when using IPv4.
MTU Fragment (#2089) included since
beta 4
included since
beta 4
Download Download DTLS fragmentation doesn't consider the additional data required with using encryption, so the packet size then exceeds the MTU when fragmentation is performed. This patch subtracts the size of the mac and the additional encryption bytes of the maximum possible length for a fragment, if necessary.

Thanks to Daniel Mentz for finding this bug!

IPv6 (#2069) included since
beta 4
included since
beta 4
requires previous patches, use cumulative patch requires previous patches, use cumulative patch This patch adds IPv6 compatibility for DTLS and the s_server/s_client test applications.
Handling of ENOTCONN and EMSGSIZE for dgram bios (#2050) included since
beta 4
included since
beta 4
Download Download This patch fixes the handling of error cases: For dgram bios use always BIO_dgram_should_retry() instead of BIO_scok_should_retry(). ENOTCONN is a fatal error. EMSGSIZE is a fatal error, not related to path MTU.

Thanks to Daniel Mentz, who pointed out the incorrect error handling when testing with the DTLS/SCTP implementation.

Listen (#2033 & #2039) included since
beta 4
included since
beta 4
requires previous patches, use cumulative patch requires previous patches, use cumulative patch This patch adds the function dtls1_listen(SSL *s, struct sockaddr *client), as well as the user accessible macro DTLSv1_listen(). It is intended to be called with an SSL object with a listening socket. Every ClientHello arriving will be answered with a HelloVerifyRequest without allocating any memory. When a ClientHello is repeated with a valid cookie attached, dtls1_listen() returns after entering the peer's address into the given sockaddr structure. The application can then create an UDP socket connected to that peer, assign it to the SSL object and continue the connection (with a SSL_accept() to complete the handshake, since the dtls1_listen returns before sending the ServerHello) in a new thread. Then a new SSL object has to be created and the listening socket has to be assigned to it, so that following connections can be handled.
Cookie Management (#2028) included since
beta 4
included since
beta 4
Download Download This patch fixes several issues with DTLS cookies. At first the maximum cookie length was defined as 32 bytes, while the specification states 256 bytes. Then there was code in the wrong order which prevented the use of cookies larger than 0 bytes in ssl3_get_client_hello(), it was tried to process extensions before the cookie. The present implementation always expects a ClientHello, sends a HelloVerifyRequest and then expects a ClientHello with a cookie attached. Everything else is considered as an error, which is not correct because the first ClientHello could be repeated. Now every ClientHello is answered with a HelloVerifyRequest until a ClientHello with cookie appears. Then the cookie is verified and an error returned if the verification failed. If SSL_OP_COOKIE_EXCHANGE is set, in dtls1_send_hello_verify_request() the cookie is sent. It was assumed that the cookie was specified "somehow" else if the user did not register a callback function for cookie generation. This doesn't make any sense because if the user doesn't use the designated function to generate cookies, how else should they be generated? The result is a cookie with length 0, which is almost as bad as no HelloVerifyRequest at all. Now an internal error occurs if the user requests cookie exchange but did not register the required callback functions. The application s_server activated cookies but didn't supply any generation or verification functions. They are added now and use a 16 byte random number as a secret to calculate an HMAC over the peer's address and port as suggested in the DTLS specification.
Record Header Length (#2022) included since
beta 4
included since
beta 4
Download Download This patch fixes the size of the read and write buffers which are 8 bytes too small for DTLS. The function ssl3_setup_buffers() is called to allocate the necessary memory for the read and write buffers. This is done in two subfunctions, ssl3_setup_read_buffer() and ssl3_setup_write_buffer(). Unfortuanately there is no difference between TLS and DTLS, although both use different record headers with different lengths.
Fragmentation (#2006) included since
beta 4
included since
beta 4
Download Download Fixes a bug where a single user message was fragmented and distributed over multiple DTLS records if its size exceeds the MTU.
Timeout Handling (#1997) included since
beta 4
included since
beta 4
requires previous patches, use cumulative patch requires previous patches, use cumulative patch This patch fixes the timeout handling. The method dtls1_get_timeout() was intended to determine the next handshake message timeout when using select() calls, to set their timeout. This method is now avaiable as DTLSv1_get_timeout(), to fit the common naming scheme. Additionally, the timeout handling is moved to the method dtls1_handle_timeout(), which can be called by the user as DTLSv1_handle_timeout() when a select() timer expires. Until now expired timers were handled not until a SSL_read() is called. This is a problem when using select() on the reading socket, because no call of SSL_read() is done before data from the peer arrived. The test programs s_server and s_client are also modified to make use of the new timeout handling to fully support timeouts.
Cookie Renegotiation (#1993) included since
beta 4
included since
beta 4
Download Download In d1_clnt.c the variables s->d1->send_cookie and s->hit aren't reset when initiating a new renegotiation handshake. This is ok if a new session is created, that is everything will be reset anyway, but with an abbreviated handshake without a new session this causes the handshake to fail. Additionally a typo in d1_pkt.c in OpenSSL 1.0.0 is fixed.
s_server msg (#1991) included since
beta 4
included since
beta 4
Download Download When using s_client and s_server with DTLS and the -msg arg, the message types are not printed. This fixes adds support in the corresponding callback for printing DTLS message types.
Socket Timeout (#1990) included since
beta 4
included since
beta 4
not needed not needed When the socket timeout has to be adjusted because of a handshake timeout expiring earlier, the user set value is saved and reset afterwards. This patch adds a missing if-clause in dgram_reset_rcv_timeout() to prevent the reset of the socket timeout when no timer is active. Since no adjustment has been done then, no previous socket timeout has been saved and the socket timeout will be always set to 0.
Record Header (#1981) included since
beta 3
included since
beta 3
Download Download This patch changes the behavior of DTLS regarding erroneous record headers. The current implementation reports an error if the version or length entries of the record layer are unexpected and closes the connection. This is probably takes over from TLS but doesn't make sense with DTLS, since an attacker can easily send random data to close the connection. In fact every packet not containing the correct version and length terminates the connection. With this patch such packets are just silently discarded to keep the connection alive.
ECDH Renegotiation Bug (#1952) included since
beta 3
included since
beta 3
Download Download The variable s->s3->tmp.ecdh is set in ssl3_send_server_key_exchange() or dtls1_send_server_key_exchange(), after checking if it points to NULL. Later it is read only once in ssl3_get_client_key_exchange(), but then not freed and set to NULL again. When a renegotiation with a full handshake is performed to compute new key material, the procedure is the same and s->s3->tmp.ecdh should be set in the send_server_key_exchange() functions. This fails because it has not been set to NULL in advance, so no renegotiation is possible, even worse, this causes the connection to fail. This patch adds two lines to free the variable right after it has been used, to allow it to be set again during following renegotiations.
Fragment Retransmission Bug (#1950) included since
beta 3
included since
beta 3
Download Download When handshake messages can't be reassembled because a fragment got lost, the ChangeCipherSpec included in the same flight was still processed. The new mastersecret has not been calculated yet, so random memory is used causing the connection to fail. This patch drops every ChangeCipherSpec which arrives before all previous messages are processed. It doesn't have to be buffered because always the entire flight is repeated, so it will be sent again anyway. This patch also fixes wrong socket timing causing retransmissions to be sent later than necessary. Finally this patch also fixes a problem with stale retransmits of Finished messages of a previous handshake when a new one is initiated. It will be dropped instead of buffered and processed after the ChangeCipherSpec if it arrives before the ServerHello, when it obviously can't belong to the current handshake. Otherwise the connection fails with unexpected message.

Thanks to Daniel Mentz for providing hints!

Record buffer limitation Bug (#1930) included since
beta 3
included since
beta 3
Download Download Records are buffered if they arrive with a future epoch to be processed after finishing the corresponding handshake. There is currently no limitation to this buffer allowing an attacker to perform a DOS attack with sending records with future epochs until there is no memory left. This patch adds the pqueue_size() function to detemine the size of a buffer and limits the record buffer to 100 entries.

Thanks to Daniel Mentz for finding this bug!

MTU Bug (#1929) included since
beta 3
included since
beta 3
Download Download The PMTU discovery was Linux specific but not enclosed with defines if Linux is actually used. This caused problems on other platforms. If the MTU was discovered or set by the user, it was not considered that the IP and UDP header have to be subtracted to get the size available for DTLS. Hence, messages could be up to 28 byte larger than the MTU which causes IP fragmentation or packet loss.

Thanks to Daniel Mentz for finding this bug!

Fragment Memory Leak Bug (#1931) included since
beta 3
included since
beta 3
Download Download In dtls1_process_out_of_seq_message() the check if the current message is already buffered was missing. For every new message was memory allocated, allowing an attacker to perform an denial of service attack with sending out of seq handshake messages until there is no memory left. Additionally every future messege was buffered, even if the sequence number made no sense and would be part of another handshake. So only messages with sequence numbers less than 10 in advance will be buffered.

Thanks to Daniel Mentz for finding this bug!

Fragment Segmentation Fault Bug (#1923) included since
beta 3
included since
beta 3
Download Download In dtls1_retrieve_buffered_fragment() a fragment may be freed before returning its length. This causes a segmentation fault. This is fixed with storing the length in a different variable and returning this one instead of the fragment property which is not available anymore.

Thanks to Daniel Mentz for finding this bug!

Timer Bug (#1829 & #1922 & #1990) included since
beta 3
included since
beta 3
Download Download DTLS has to maintain timers to retransmit lost packets. Until now there is no timer, retransmissions are only performed, when the socket returns an EAGAIN. This also is a problem when using non-blocking sockets. This patch adds timer functionality to the DTLS implementation. A timer is started for every handshake message and this message is repeated if the timer expires. The timer is initialized with 1 second and doubled at each timeout up to 60 seconds, according to the RFC 4347. Whenever the BIO object is about to read from the socket, it is checked if there is a timer running for an expected handshake message. If so, the socket timeout is compared with the remaining time of the timer and adjusted if the message timer expires earlier. For OpenSSL 1.0.0 beta 2 this patch replaces the timer functionality added with #1829, because this was not cleanly implemented and not compatible with non-blocking sockets at all. This patch was updated for 0.9.8 to resolve the issue #1990 of OpenSSL 1.0.0 beta 3.

Thanks to Daniel Mentz for his suggestions!

Fragment Bug (#1838) included since
beta 3
included since
beta 3
Download Download Whenever a handshake message arrives with an unexpected sequence number, it is passed to the function dtls1_process_out_of_seq_message(). This function discards the data if the sequence number is lower than the expected value and buffers it, if is a future message. When discarding, the message fragment length remains 0 which indicates that nothing has to be buffered. Due to a misplaced if condition to check the length, sometimes fragments with no data but with the length of the dropped message are buffered. This causes a bus error when processing later.
Retransmission Bug (#1828) included since
beta 3
included since
beta 3
Download Download This patch solves four issues. At first the index of the retransmission queue is the message sequence number bitwise ORed with the current epoch. The epoch cannot be used to retrieve the buffered messages because it could have changed until a retransmission has to be done and is therefor not necessarily known. Since there can only be one handshake at a time, every message can only be once in the queue so the epoch can be removed. The message sequence number alone is not sufficient, because the ChangeCipherSpec doesn't have one, so it will have the same index as the Finished. A solution is using the message sequence number multiplied by 2 and if the message is a ChangeCipherSpec 1 is subtraced. This has the advantage that the index of the CCS is always one less than the Finished, so the order of the indices is preserved, which is important in a priority queue and the unsigned short sequence number variable can be kept. more...
Application Data in Handshake Bug (#1827) included since
beta 2
included since
beta 2
Download Download The current DTLS implementation always generates an SSL_R_UNEXPECTED_RECORD error if application data is received while handshaking. This is ok for the first handshake, but not necessary for renegotiations. Furthermore it's likely that the connection fails just because of unordered UDP packets. The DTLS specification does not mention this issue, but there is no reason not to accept belated application data while renegotiating, as long as the key material has not changed yet. With this patch the implementation will leave the handshake routine, return the application data and generate the error SSL_ERROR_WANT_READ, so that the application reads again to continue handshaking.
Client Random Bug (#1826) included since
beta 2
included since
beta 2
Download Download Everytime a new handshake is initialized the value s->s3->client_random gets filled with random numbers for the ClientHello. The value has to be reused if the ClientHello has to be repeated because the server sent a HelloVerifyRequest. In the function dtls1_client_hello() is checked if client_random is still zero or already set to decide whether new random numbers have to be generated. In the state SSL3_ST_CW_FINISHED_A the client_random is overwritten with zeros to indicate that the next time a ClientHello is sent new random values have to be generated. This is not only redundant with the memset call at the beginning of the handshake in state SSL_ST_CONNECT, it also prevents to use the value after the handshake is done. So the redundant memset call should be removed. This is important for the TLS key material extractor feature which relies on the client_random value.
Renegotiation Bug (#1647) included since
beta 2
included since
beta 2
Download Download As described in bug report #1647 both server and client are hanging when calling SSL_renegotiate() with DTLS. The client sends the ClientHello to the server, but the message sequence number has not been reset to 0 after the first handshake. So the server drops it (out of sync) and continues waiting for the ClientHello while the client is waiting for the server's response. This patch resets the message sequence number to 0 after finishing a handshake.




Features

Patch OpenSSL 1.0.0 beta 5 OpenSSL 0.9.8l Description
Plain text Tarball Plain text Tarball
Abbreviated Renegotiations (#1833) Download Download not available not available Whenever a handshake is initiated, the variable s->new_session is set to indicate that a handshake is being performed. This is not the correct context because a handshake can also be abbreviated and will not create a new session then. This variable is also used in the right context to determine whether or not the current Session ID is sent with a ClientHello. The result is that renegotiations always create a new session because the handshake state has to be set. There is no possibility to perform an abbreviated handshake for renegotiation conform to the TLS specification. This patch adds the variable s->renegotiate to indicate handshakes, so that s->new_session only indicates if a new session should be created, that is a full handshake should be performed. The patch also adds the function SSL_renegotiate_abbreviated(SSL* ssl) which can be used to trigger an abbreviated handshake. The functionality of SSL_renegotiate(SSL* ssl) remains the same and always performs a full handshake.
TLS Key Material Extractor (#1830) Download Download not available not available Adds the TLS key material extractor described in RFC 5705. This feature is mandatory for DTLS for SCTP to extract key material for SCTP-AUTH.
SCTP-aware DTLS Download Download not available not available Adds SCTP support for DTLS as described in draft-ietf-tsvwg-dtls-for-sctp-02.

This patch requires every bugfix and feature patch above in advance! Otherwise it won't work!

The new configure option 'sctp' will be added. To compile OpenSSL with SCTP support use './config sctp'.

DTLS Heartbeat Extension Download Download not available not available Adds the DTLS Heartbeat Extension described in draft-seggelmann-tls-dtls-heartbeat-01.




Generic Bugfixes

Patch OpenSSL 1.0.0 beta 5 OpenSSL 0.9.8l Description
Plain text Tarball Plain text Tarball
FreeBSD Compatibility Patch (#1900) included since
beta 2
included since
beta 2
Download Download In ssl/kssl.c the constant _XOPEN_SOURCE is defined which results in using an old POSIX version and compilation problems on recent FreeBSD systems when adding SCTP support (necessary for SCTP-aware DTLS). With _XOPEN_SOURCE defined to 500, in sys/cdefs.h the constant _POSIX_C_SOURCE will get the value 199506 instead of 200112. The constant __POSIX_VISIBLE then gets the same value, so an old POSIX version will be assumed. This is not only needless, it also is a problem when including netinet/sctp.h to use SCTP. In this header file the structure sin6 is needed, which is defined in netinet/in6.h that gets included by netinet/in.h, but only when #if __POSIX_VISIBLE >= 200112 is true. Hence, defining _XOPEN_SOURCE to 500 makes it impossible to use SCTP, even if the constant is undefined afterwards. Since there is no use of any funtion of time.h, the corresponding code should just be removed.


If you have any comments please contact seggelmann@fh-muenster.de.