[openssl-commits] [openssl] master update
Kurt Roeckx
kurt at openssl.org
Mon Jul 16 22:01:29 UTC 2018
The branch master has been updated
via 57fd517066418472b3280a975823405fb8f2f43d (commit)
via 07fc8d5207febe53c8203a8a89fb7ba006871a1b (commit)
from 01ad66f85d22fd001582b5f2e6e18db8b820c550 (commit)
- Log -----------------------------------------------------------------
commit 57fd517066418472b3280a975823405fb8f2f43d
Author: Kurt Roeckx <kurt at roeckx.be>
Date: Sun May 13 11:24:11 2018 +0200
Improve documentation about reading and writing
Reviewed-by: Matt Caswell <matt at openssl.org>
GH: #6240
commit 07fc8d5207febe53c8203a8a89fb7ba006871a1b
Author: Kurt Roeckx <kurt at roeckx.be>
Date: Sun Jul 15 13:49:53 2018 +0200
Enable all protocols and ciphers in the fuzzer
The config file can override it.
In case of the server, it needs to be set on the ctx or some of the
other functions on the ctx might file.
Reviewed-by: Rich Salz <rsalz at openssl.org>
DH: #6718
-----------------------------------------------------------------------
Summary of changes:
doc/man3/BIO_should_retry.pod | 10 ++++---
doc/man3/SSL_CTX_set_mode.pod | 38 ++++++++++++++++++++------
doc/man3/SSL_CTX_set_read_ahead.pod | 18 +++++++++++--
doc/man3/SSL_get_error.pod | 41 +++++++++++++++++++++-------
doc/man3/SSL_read.pod | 53 ++++++++++++++++++++++---------------
doc/man3/SSL_write.pod | 17 +++++++-----
fuzz/client.c | 1 +
fuzz/server.c | 7 +++--
8 files changed, 133 insertions(+), 52 deletions(-)
diff --git a/doc/man3/BIO_should_retry.pod b/doc/man3/BIO_should_retry.pod
index 60d8139..7a9ce8c 100644
--- a/doc/man3/BIO_should_retry.pod
+++ b/doc/man3/BIO_should_retry.pod
@@ -32,11 +32,13 @@ should then be retried at a later time.
If BIO_should_retry() is false then the cause is an error condition.
-BIO_should_read() is true if the cause of the condition is that a BIO
-needs to read data.
+BIO_should_read() is true if the cause of the condition is that the BIO
+has insufficient data to return. Check for readability and/or retry the
+last operation.
-BIO_should_write() is true if the cause of the condition is that a BIO
-needs to read data.
+BIO_should_write() is true if the cause of the condition is that the BIO
+has pending data to write. Check for writability and/or retry the
+last operation.
BIO_should_io_special() is true if some "special" condition, that is a
reason other than reading or writing is the cause of the condition.
diff --git a/doc/man3/SSL_CTX_set_mode.pod b/doc/man3/SSL_CTX_set_mode.pod
index e83b591..e6de166 100644
--- a/doc/man3/SSL_CTX_set_mode.pod
+++ b/doc/man3/SSL_CTX_set_mode.pod
@@ -2,14 +2,16 @@
=head1 NAME
-SSL_CTX_set_mode, SSL_set_mode, SSL_CTX_get_mode, SSL_get_mode - manipulate SSL engine mode
+SSL_CTX_set_mode, SSL_CTX_clear_mode, SSL_set_mode, SSL_clear_mode, SSL_CTX_get_mode, SSL_get_mode - manipulate SSL engine mode
=head1 SYNOPSIS
#include <openssl/ssl.h>
long SSL_CTX_set_mode(SSL_CTX *ctx, long mode);
+ long SSL_CTX_clear_mode(SSL_CTX *ctx, long mode);
long SSL_set_mode(SSL *ssl, long mode);
+ long SSL_clear_mode(SSL *ssl, long mode);
long SSL_CTX_get_mode(SSL_CTX *ctx);
long SSL_get_mode(SSL *ssl);
@@ -18,9 +20,11 @@ SSL_CTX_set_mode, SSL_set_mode, SSL_CTX_get_mode, SSL_get_mode - manipulate SSL
SSL_CTX_set_mode() adds the mode set via bitmask in B<mode> to B<ctx>.
Options already set before are not cleared.
+SSL_CTX_clear_mode() removes the mode set via bitmask in B<mode> from B<ctx>.
SSL_set_mode() adds the mode set via bitmask in B<mode> to B<ssl>.
Options already set before are not cleared.
+SSL_clear_mode() removes the mode set via bitmask in B<mode> from B<ssl>.
SSL_CTX_get_mode() returns the mode set for B<ctx>.
@@ -51,16 +55,31 @@ non-blocking write().
=item SSL_MODE_AUTO_RETRY
-Never bother the application with retries if the transport is blocking.
-If a renegotiation take place during normal operation, a
-L<SSL_read_ex(3)>, L<SSL_read(3)>, L<SSL_write_ex(3)> or L<SSL_write(3)> would
-return with a failure and indicate the need to retry with SSL_ERROR_WANT_READ.
+During normal operations, non-application data records might need to be sent or
+received that the application is not aware of.
+If a non-application data record was processed,
+L<SSL_read_ex(3)> and L<SSL_read(3)> can return with a failure and indicate the
+need to retry with B<SSL_ERROR_WANT_READ>.
+If such a non-application data record was processed, the flag
+B<SSL_MODE_AUTO_RETRY> causes it to try to process the next record instead of
+returning.
+
In a non-blocking environment applications must be prepared to handle
incomplete read/write operations.
+Setting B<SSL_MODE_AUTO_RETRY> for a non-blocking B<BIO> will process
+non-application data records until either no more data is available or
+an application data record has been processed.
+
In a blocking environment, applications are not always prepared to
-deal with read/write operations returning without success report. The
-flag SSL_MODE_AUTO_RETRY will cause read/write operations to only
-return after the handshake and successful completion.
+deal with the functions returning intermediate reports such as retry
+requests, and setting the B<SSL_MODE_AUTO_RETRY> flag will cause the functions
+to only return after successfully processing an application data record or a
+failure.
+
+Turning off B<SSL_MODE_AUTO_RETRY> can be useful with blocking B<BIO>s in case
+they are used in combination with something like select() or poll().
+Otherwise the call to SSL_read() or SSL_read_ex() might hang when a
+non-application record was sent and no application data was sent.
=item SSL_MODE_RELEASE_BUFFERS
@@ -88,6 +107,9 @@ used to perform cryptographic operations. See L<SSL_get_error(3)>.
=back
+All modes are off by default except for SSL_MODE_AUTO_RETRY which is on by
+default since 1.1.1.
+
=head1 RETURN VALUES
SSL_CTX_set_mode() and SSL_set_mode() return the new mode bitmask
diff --git a/doc/man3/SSL_CTX_set_read_ahead.pod b/doc/man3/SSL_CTX_set_read_ahead.pod
index 3a96ce3..f2731a0 100644
--- a/doc/man3/SSL_CTX_set_read_ahead.pod
+++ b/doc/man3/SSL_CTX_set_read_ahead.pod
@@ -25,12 +25,14 @@ many input bytes as possible (for non-blocking reads) or not. For example if
B<x> bytes are currently required by OpenSSL, but B<y> bytes are available from
the underlying BIO (where B<y> > B<x>), then OpenSSL will read all B<y> bytes
into its buffer (providing that the buffer is large enough) if reading ahead is
-on, or B<x> bytes otherwise. The parameter B<yes> or B<m> should be 0 to ensure
-reading ahead is off, or non zero otherwise.
+on, or B<x> bytes otherwise.
+Setting the parameter B<yes> to 0 turns reading ahead is off, other values turn
+it on.
SSL_CTX_set_default_read_ahead() is identical to SSL_CTX_set_read_ahead().
SSL_CTX_get_read_ahead() and SSL_get_read_ahead() indicate whether reading
ahead has been set or not.
+SSL_CTX_get_default_read_ahead() is identical to SSL_CTX_get_read_ahead().
=head1 NOTES
@@ -39,6 +41,18 @@ SSL_CTX_get_read_head() and SSL_get_read_ahead() are undefined for DTLS. Setting
B<read_ahead> can impact the behaviour of the SSL_pending() function
(see L<SSL_pending(3)>).
+Since SSL_read() can return B<SSL_ERROR_WANT_READ> for non-application data
+records, and SSL_has_pending() can't tell the difference between processed and
+unprocessed data, it's recommended that if read ahead is turned on that
+B<SSL_MODE_AUTO_RETRY> is not turned off using SSL_CTX_clear_mode().
+That will prevent getting B<SSL_ERROR_WANT_READ> when there is still a complete
+record availale that hasn't been processed.
+
+If the application wants to continue to use the underlying transport (e.g. TCP
+connection) after the SSL connection is finished using SSL_shutdown() reading
+ahead should be turned off.
+Otherwise the SSL structure might read data that it shouldn't.
+
=head1 RETURN VALUES
SSL_get_read_ahead() and SSL_CTX_get_read_ahead() return 0 if reading ahead is off,
diff --git a/doc/man3/SSL_get_error.pod b/doc/man3/SSL_get_error.pod
index f1050b0..01446a2 100644
--- a/doc/man3/SSL_get_error.pod
+++ b/doc/man3/SSL_get_error.pod
@@ -46,25 +46,45 @@ indicate that the underlying transport has been closed.
=item SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE
-The operation did not complete; the same TLS/SSL I/O function should be
-called again later. If, by then, the underlying B<BIO> has data
-available for reading (if the result code is B<SSL_ERROR_WANT_READ>)
-or allows writing data (B<SSL_ERROR_WANT_WRITE>), then some TLS/SSL
-protocol progress will take place, i.e. at least part of an TLS/SSL
-record will be read or written. Note that the retry may again lead to
-a B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE> condition.
+The operation did not complete and can be retried later.
+
+B<SSL_ERROR_WANT_READ> is returned when the last operation was a read
+operation from a non-blocking B<BIO>.
+It means that not enough data was available at this time to complete the
+operation.
+If at a later time the underlying B<BIO> has data available for reading the same
+function can be called again.
+
+SSL_read() and SSL_read_ex() can also set B<SSL_ERROR_WANT_READ> when there is
+still unprocessed data available at either the B<SSL> or the B<BIO> layer, even
+for a blocking B<BIO>.
+See L<SSL_read(3)> for more information.
+
+B<SSL_ERROR_WANT_WRITE> is returned when the last operation was a write
+to a non-blocking B<BIO> and it was unable to sent all data to the B<BIO>.
+When the B<BIO> is writeable again, the same function can be called again.
+
+Note that the retry may again lead to an B<SSL_ERROR_WANT_READ> or
+B<SSL_ERROR_WANT_WRITE> condition.
There is no fixed upper limit for the number of iterations that
may be necessary until progress becomes visible at application
protocol level.
+It is safe to call SSL_read() or SSL_read_ex() when more data is available
+even when the call that set this error was an SSL_write() or SSL_write_ex().
+However if the call was an SSL_write() or SSL_write_ex(), it should be called
+again to continue sending the application data.
+
For socket B<BIO>s (e.g. when SSL_set_fd() was used), select() or
poll() on the underlying socket can be used to find out when the
TLS/SSL I/O function should be retried.
Caveat: Any TLS/SSL I/O function can lead to either of
-B<SSL_ERROR_WANT_READ> and B<SSL_ERROR_WANT_WRITE>. In particular,
+B<SSL_ERROR_WANT_READ> and B<SSL_ERROR_WANT_WRITE>.
+In particular,
SSL_read_ex(), SSL_read(), SSL_peek_ex(), or SSL_peek() may want to write data
-and SSL_write() or SSL_write_ex() may want to read data. This is mainly because
+and SSL_write() or SSL_write_ex() may want to read data.
+This is mainly because
TLS/SSL handshakes may occur at any time during the protocol (initiated by
either the client or the server); SSL_read_ex(), SSL_read(), SSL_peek_ex(),
SSL_peek(), SSL_write_ex(), and SSL_write() will handle any pending handshakes.
@@ -122,6 +142,9 @@ Some non-recoverable I/O error occurred.
The OpenSSL error queue may contain more information on the error.
For socket I/O on Unix systems, consult B<errno> for details.
+This value can also be returned for other errors, check the error queue for
+details.
+
=item SSL_ERROR_SSL
A failure in the SSL library occurred, usually a protocol error. The
diff --git a/doc/man3/SSL_read.pod b/doc/man3/SSL_read.pod
index 215d4c5..b1b2002 100644
--- a/doc/man3/SSL_read.pod
+++ b/doc/man3/SSL_read.pod
@@ -51,40 +51,47 @@ call. If B<num> is higher than the number of bytes buffered then the read
functions will return with the bytes buffered. If no more bytes are in the
buffer, the read functions will trigger the processing of the next record.
Only when the record has been received and processed completely will the read
-functions return reporting success. At most the contents of the record will
+functions return reporting success. At most the contents of one record will
be returned. As the size of an SSL/TLS record may exceed the maximum packet size
of the underlying transport (e.g. TCP), it may be necessary to read several
packets from the transport layer before the record is complete and the read call
can succeed.
+If B<SSL_MODE_AUTO_RETRY> has been switched off and a non-application data
+record has been processed, the read function can return and set the error to
+B<SSL_ERROR_WANT_READ>.
+In this case there might still be unprocessed data available in the B<BIO>.
+If read ahead was set using L<SSL_CTX_set_read_ahead(3)>, there might also still
+be unprocessed data available in the B<SSL>.
+This behaviour can be controlled using the L<SSL_CTX_set_mode(3)> call.
+
If the underlying BIO is B<blocking>, a read function will only return once the
read operation has been finished or an error occurred, except when a
-renegotiation takes place, in which case a SSL_ERROR_WANT_READ may occur. This
-behaviour can be controlled with the SSL_MODE_AUTO_RETRY flag of the
-L<SSL_CTX_set_mode(3)> call.
+non-application data record has been processed and B<SSL_MODE_AUTO_RETRY> is
+not set.
+Note that if B<SSL_MODE_AUTO_RETRY> is set and only non-application data is
+available the call will hang.
If the underlying BIO is B<non-blocking>, a read function will also return when
the underlying BIO could not satisfy the needs of the function to continue the
-operation. In this case a call to L<SSL_get_error(3)> with the
+operation.
+In this case a call to L<SSL_get_error(3)> with the
return value of the read function will yield B<SSL_ERROR_WANT_READ> or
-B<SSL_ERROR_WANT_WRITE>. As at any time a re-negotiation is possible, a
-a read function can also cause write operations! The calling process then must
-repeat the call after taking appropriate action to satisfy the needs of the read
-function. The action depends on the underlying BIO. When using a non-blocking
-socket, nothing is to be done, but select() can be used to check for the
-required condition. When using a buffering BIO, like a BIO pair, data must be
-written into or retrieved out of the BIO before being able to continue.
+B<SSL_ERROR_WANT_WRITE>.
+As at any time it's possible that non-application data needs to be sent,
+a read function can also cause write operations.
+The calling process then must repeat the call after taking appropriate action
+to satisfy the needs of the read function.
+The action depends on the underlying BIO.
+When using a non-blocking socket, nothing is to be done, but select() can be
+used to check for the required condition.
+When using a buffering BIO, like a BIO pair, data must be written into or
+retrieved out of the BIO before being able to continue.
L<SSL_pending(3)> can be used to find out whether there
-are buffered bytes available for immediate retrieval. In this case
-the read function can be called without blocking or actually receiving
-new data from the underlying socket.
-
-=head1 WARNING
-
-When a read function operation has to be repeated because L<SSL_get_error(3)>
-returned B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>, it must be repeated
-with the same arguments.
+are buffered bytes available for immediate retrieval.
+In this case the read function can be called without blocking or actually
+receiving new data from the underlying socket.
=head1 RETURN VALUES
@@ -119,6 +126,10 @@ You should instead call SSL_get_error() to find out if it's retryable.
=back
+=head1 HISTORY
+
+SSL_read_ex() and SSL_peek_ex() were added in OpenSSL 1.1.1.
+
=head1 SEE ALSO
L<SSL_get_error(3)>, L<SSL_write_ex(3)>,
diff --git a/doc/man3/SSL_write.pod b/doc/man3/SSL_write.pod
index 14b651a..d528442 100644
--- a/doc/man3/SSL_write.pod
+++ b/doc/man3/SSL_write.pod
@@ -34,10 +34,7 @@ L<SSL_set_connect_state(3)> or SSL_set_accept_state()
before the first call to a write function.
If the underlying BIO is B<blocking>, the write functions will only return, once
-the write operation has been finished or an error occurred, except when a
-renegotiation take place, in which case a SSL_ERROR_WANT_READ may occur.
-This behaviour can be controlled with the SSL_MODE_AUTO_RETRY flag of the
-L<SSL_CTX_set_mode(3)> call.
+the write operation has been finished or an error occurred.
If the underlying BIO is B<non-blocking> the write functions will also return
when the underlying BIO could not satisfy the needs of the function to continue
@@ -65,9 +62,13 @@ write is performed with the size of a message block, which is 16kB.
When a write function call has to be repeated because L<SSL_get_error(3)>
returned B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>, it must be repeated
with the same arguments.
+The data that was passed might have been partially processed.
+When B<SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER> was set using L<SSL_CTX_set_mode(3)>
+the pointer can be different, but the data and length should still be the same.
-When calling the write functions with num=0 bytes to be sent the behaviour is
-undefined.
+You should not call SSL_write() with num=0, it will return an error.
+SSL_write_ex() can be called with num=0, but will not send application data to
+the peer.
=head1 RETURN VALUES
@@ -103,6 +104,10 @@ You should instead call SSL_get_error() to find out if it's retryable.
=back
+=head1 HISTORY
+
+SSL_write_ex() was added in OpenSSL 1.1.1.
+
=head1 SEE ALSO
L<SSL_get_error(3)>, L<SSL_read_ex(3)>, L<SSL_read(3)>
diff --git a/fuzz/client.c b/fuzz/client.c
index ce6d8cc..bc01f62 100644
--- a/fuzz/client.c
+++ b/fuzz/client.c
@@ -73,6 +73,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
ctx = SSL_CTX_new(SSLv23_method());
client = SSL_new(ctx);
+ OPENSSL_assert(SSL_set_min_proto_version(client, 0) == 1);
OPENSSL_assert(SSL_set_cipher_list(client, "ALL:eNULL:@SECLEVEL=0") == 1);
SSL_set_tlsext_host_name(client, "localhost");
in = BIO_new(BIO_s_mem());
diff --git a/fuzz/server.c b/fuzz/server.c
index 2f7403e..7f9f9fa 100644
--- a/fuzz/server.c
+++ b/fuzz/server.c
@@ -534,6 +534,11 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
/* This only fuzzes the initial flow from the client so far. */
ctx = SSL_CTX_new(SSLv23_method());
+ ret = SSL_CTX_set_min_proto_version(ctx, 0);
+ OPENSSL_assert(ret == 1);
+ ret = SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:@SECLEVEL=0");
+ OPENSSL_assert(ret == 1);
+
/* RSA */
bufp = kRSAPrivateKeyDER;
privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER));
@@ -602,8 +607,6 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
/* TODO: Set up support for SRP and PSK */
server = SSL_new(ctx);
- ret = SSL_set_cipher_list(server, "ALL:eNULL:@SECLEVEL=0");
- OPENSSL_assert(ret == 1);
in = BIO_new(BIO_s_mem());
out = BIO_new(BIO_s_mem());
SSL_set_bio(server, in, out);
More information about the openssl-commits
mailing list