BIO_s_dgram: add documentation and hazard warnings
authorHugo Landau <hlandau@openssl.org>
Wed, 30 Nov 2022 19:24:15 +0000 (19:24 +0000)
committerHugo Landau <hlandau@openssl.org>
Thu, 15 Dec 2022 06:32:45 +0000 (06:32 +0000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19795)

doc/build.info
doc/man3/BIO_s_datagram.pod [new file with mode: 0644]
doc/man3/DTLSv1_listen.pod
util/missingcrypto.txt
util/missingmacro.txt
util/other.syms

index a2db40e21870a5637ac40e18834278733b21ebb6..4ffbcb843db65cd56680244d6215a85293cff479 100644 (file)
@@ -651,6 +651,10 @@ DEPEND[html/man3/BIO_s_core.html]=man3/BIO_s_core.pod
 GENERATE[html/man3/BIO_s_core.html]=man3/BIO_s_core.pod
 DEPEND[man/man3/BIO_s_core.3]=man3/BIO_s_core.pod
 GENERATE[man/man3/BIO_s_core.3]=man3/BIO_s_core.pod
+DEPEND[html/man3/BIO_s_datagram.html]=man3/BIO_s_datagram.pod
+GENERATE[html/man3/BIO_s_datagram.html]=man3/BIO_s_datagram.pod
+DEPEND[man/man3/BIO_s_datagram.3]=man3/BIO_s_datagram.pod
+GENERATE[man/man3/BIO_s_datagram.3]=man3/BIO_s_datagram.pod
 DEPEND[html/man3/BIO_s_dgram_pair.html]=man3/BIO_s_dgram_pair.pod
 GENERATE[html/man3/BIO_s_dgram_pair.html]=man3/BIO_s_dgram_pair.pod
 DEPEND[man/man3/BIO_s_dgram_pair.3]=man3/BIO_s_dgram_pair.pod
@@ -2958,6 +2962,7 @@ html/man3/BIO_s_accept.html \
 html/man3/BIO_s_bio.html \
 html/man3/BIO_s_connect.html \
 html/man3/BIO_s_core.html \
+html/man3/BIO_s_datagram.html \
 html/man3/BIO_s_dgram_pair.html \
 html/man3/BIO_s_fd.html \
 html/man3/BIO_s_file.html \
@@ -3569,6 +3574,7 @@ man/man3/BIO_s_accept.3 \
 man/man3/BIO_s_bio.3 \
 man/man3/BIO_s_connect.3 \
 man/man3/BIO_s_core.3 \
+man/man3/BIO_s_datagram.3 \
 man/man3/BIO_s_dgram_pair.3 \
 man/man3/BIO_s_fd.3 \
 man/man3/BIO_s_file.3 \
diff --git a/doc/man3/BIO_s_datagram.pod b/doc/man3/BIO_s_datagram.pod
new file mode 100644 (file)
index 0000000..3ff24cc
--- /dev/null
@@ -0,0 +1,255 @@
+=pod
+
+=head1 NAME
+
+BIO_s_datagram, BIO_new_dgram,
+BIO_ctrl_dgram_connect,
+BIO_ctrl_set_connected,
+BIO_dgram_recv_timedout,
+BIO_dgram_send_timedout,
+BIO_dgram_get_peer,
+BIO_dgram_set_peer,
+BIO_dgram_get_mtu_overhead - Network BIO with datagram semantics
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *BIO_s_datagram(void);
+ BIO *BIO_new_dgram(int fd, int close_flag);
+
+ int BIO_ctrl_dgram_connect(BIO *bio, const BIO_ADDR *peer);
+ int BIO_ctrl_set_connected(BIO *bio, const BIO_ADDR *peer);
+ int BIO_dgram_recv_timedout(BIO *bio);
+ int BIO_dgram_send_timedout(BIO *bio);
+ int BIO_dgram_get_peer(BIO *bio, BIO_ADDR *peer);
+ int BIO_dgram_set_peer(BIO *bio, const BIO_ADDR *peer);
+ int BIO_dgram_get_mtu_overhead(BIO *bio);
+
+=head1 DESCRIPTION
+
+BIO_s_datagram() is a BIO implementation designed for use with network sockets
+which provide datagram semantics, such as UDP sockets. It is suitable for use
+with DTLSv1 or QUIC.
+
+Because BIO_s_datagram() has datagram semantics, a single BIO_write() call sends
+a single datagram and a single BIO_read() call receives a single datagram. If
+the size of the buffer passed to BIO_read() is inadequate, the datagram is
+silently truncated.
+
+For a memory-based BIO which provides datagram semantics identical to those of
+BIO_s_datagram(), see L<BIO_s_dgram_pair(3)>.
+
+This BIO supports the L<BIO_sendmmsg(3)> and L<BIO_recvmmsg(3)> functions.
+
+When using BIO_s_datagram(), it is important to note that:
+
+=over 4
+
+=item
+
+This BIO can be used with either a connected or unconnected network socket. A
+connected socket is a network socket which has had L<BIO_connect(3)> or a
+similar OS-specific function called on it. Such a socket can only receive
+datagrams from the specified peer. Any other socket is an unconnected socket and
+can receive datagrams from any host.
+
+=item
+
+Despite their naming,
+neither BIO_ctrl_dgram_connect() nor BIO_ctrl_set_connected() cause a socket
+to become connected. These controls are provided to indicate to the BIO how
+the underlying socket is configured and how it is to be used; see below.
+
+=item
+
+Use of BIO_s_datagram() with an unconnected network socket is hazardous hecause
+any successful call to BIO_read() results in the peer address used for any
+subsequent call to BIO_write() being set to the source address of the datagram
+received by that call to BIO_read(). Thus, unless the caller calls
+BIO_dgram_set_peer() immediately prior to every call to BIO_write(), or never
+calls BIO_read(), any host on the network may cause future datagrams written to
+be redirected to that host. Therefore, it is recommended that users either use
+BIO_s_dgram() only with a connected socket, or, if using BIO_s_dgram() with an
+unconnected socket, to use the L<BIO_sendmmsg(3)> and L<BIO_recvmmsg(3)> methods
+only and forego use of L<BIO_read(3)> and L<BIO_write(3)>. An exception is where
+L<DTLSv1_listen(3)> must be used; see L<DTLSv1_listen(3)> for further
+discussion.
+
+=item
+
+Unlike L<BIO_read(3)> and L<BIO_write(3)>, the L<BIO_sendmmsg(3)> and
+L<BIO_recvmmsg(3)> methods are stateless and do not cause the internal state of
+the BIO_s_datagram() to change.
+
+=back
+
+Various controls are available for configuring the BIO_s_datagram() using
+L<BIO_ctrl(3)>:
+
+=over 4
+
+=item BIO_ctrl_dgram_connect (BIO_CTRL_DGRAM_CONNECT)
+
+This is equivalent to calling L<BIO_dgram_set_peer(3)>.
+
+Despite its name, this function does not cause the underlying socket to become
+connected.
+
+=item BIO_ctrl_set_connected (BIO_CTRL_SET_CONNECTED)
+
+This informs the BIO_s_datagram() whether the underlying socket has been
+connected, and therefore how the BIO_s_datagram() should attempt to use the
+socket.
+
+If the I<peer> argument is non-NULL, BIO_s_datagram() assumes that the
+underlying socket has been connected and will attempt to use the socket using OS
+APIs which do not specify peer addresses (for example, send(3) and recv(3) or
+similar). The I<peer> argument should specify the peer address to which the socket
+is connected.
+
+If the I<peer> argument is NULL, BIO_s_datagram() assumes that the underlying
+socket is not connected and will attempt to use the socket using an OS APIs
+which specify peer addresses (for example, sendto(3) and recvfrom(3)).
+
+This control does not affect the operation of L<BIO_sendmmsg(3)> or
+L<BIO_recvmmsg(3)>.
+
+=item BIO_dgram_get_peer (BIO_CTRL_DGRAM_GET_PEER)
+
+This outputs a B<BIO_ADDR> which specifies one of the following values,
+whichever happened most recently:
+
+=over 4
+
+=item
+
+The peer address last passed to BIO_dgram_set_peer(), BIO_ctrl_dgram_connect()
+or BIO_ctrl_set_connected().
+
+=item
+
+The peer address of the datagram last received by a call to BIO_read().
+
+=back
+
+=item BIO_dgram_set_peer (BIO_CTRL_DGRAM_SET_PEER)
+
+Sets the peer address to be used for subsequent writes to this BIO.
+
+Warning: When used with an unconnected network socket, the value set may be
+modified by future calls to L<BIO_read(3)>, making use of BIO_s_datagram()
+hazardous when used with unconnected network sockets; see above.
+
+This does not affect the operation of L<BIO_sendmmsg(3)>.
+L<BIO_recvmmsg(3)> does not affect the value set by BIO_dgram_set_peer().
+
+=item BIO_dgram_recv_timeout (BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP)
+
+Returns 1 if the last I/O operation performed on the BIO (for example, via a
+call to L<BIO_read(3)>) may have been caused by a receive timeout.
+
+=item BIO_dgram_send_timedout (BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP)
+
+Returns 1 if the last I/O operation performed on the BIO (for example, via a
+call to L<BIO_write(3)>) may have been caused by a send timeout.
+
+=item BIO_dgram_get_mtu_overhead (BIO_CTRL_DGRAM_GET_MTU_OVERHEAD)
+
+Returns a quantity in bytes which is a rough estimate of the number of bytes of
+overhead which should typically be added to a datagram payload size in order to
+estimate the final size of the Layer 3 (e.g. IP) packet which will contain the
+datagram. In most cases, the maximum datagram payload size which can be
+transmitted can be determined by determining the link MTU in bytes and
+subtracting the value returned by this call.
+
+The value returned by this call depends on the network layer protocol being
+used.
+
+The value returned is not fully reliable because datagram overheads can be
+higher in atypical network configurations, for example where IPv6 extension
+headers or IPv4 options are used.
+
+=item BIO_CTRL_DGRAM_SET_DONT_FRAG
+
+If I<num> is nonzero, configures the underlying network socket to enable Don't
+Fragment mode, in which datagrams will be set with the IP Don't Fragment (DF)
+bit set. If I<num> is zero, Don't Fragment mode is disabled.
+
+=item BIO_CTRL_DGRAM_QUERY_MTU
+
+Queries the OS for its assessment of the Path MTU for the destination to which
+the underlying network socket, and returns that Path MTU in bytes. This control
+can only be used with a connected socket.
+
+This is not supported on all platforms and depends on OS support being
+available. Returns 0 on failure.
+
+=item BIO_CTRL_DGRAM_MTU_DISCOVER
+
+This control requests that Path MTU discovery be enabled on the underlying
+network socket.
+
+=item BIO_CTRL_DGRAM_GET_FALLBACK_MTU
+
+Returns the estimated minimum size of datagram payload which should always be
+supported on the BIO. This size is determined by the minimum MTU required to be
+supported by the applicable underlying network layer. Use of datagrams of this
+size may lead to suboptimal performance, but should be routable in all
+circumstances. The value returned is the datagram payload size in bytes and does
+not include the size of layer 3 or layer 4 protocol headers.
+
+=item BIO_CTRL_DGRAM_MTU_EXCEEDED
+
+Returns 1 if the last attempted write to the BIO failed due to the size of the
+attempted write exceeding the applicable MTU.
+
+=item BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
+
+Accepts a pointer to a B<struct timeval>. If the time specified is zero,
+disables receive timeouts. Otherwise, configures the specified time interval as
+the receive timeout for the socket for the purposes of future L<BIO_read(3)>
+calls.
+
+=item BIO_CTRL_DGRAM_SET_PEEK_MODE
+
+If B<num> is nonzero, enables peek mode; otherwise, disables peek mode. Where
+peek mode is enabled, calls to L<BIO_read(3)> read datagrams from the underlying
+network socket in peek mode, meaning that a future call to L<BIO_read(3)> will
+yield the same datagram until peek mode is disabled.
+
+L<BIO_recvmmsg(3)> is not affected by this control.
+
+=back
+
+BIO_new_dgram() is a helper function which instantiates a BIO_s_datagram() and
+sets the BIO to use the socket given in I<fd> by calling BIO_set_fd().
+
+=head1 RETURN VALUES
+
+BIO_s_datagram() returns a BIO method.
+
+BIO_new_dgram() returns a BIO on success and NULL on failure.
+
+BIO_ctrl_dgram_connect(), BIO_ctrl_set_connected(),
+BIO_dgram_get_peer(), BIO_dgram_set_peer() return 1 on success and 0 on failure.
+
+BIO_dgram_recv_timedout() and BIO_dgram_send_timedout() return 0 or 1 depending
+on the circumstance; see discussion above.
+
+BIO_dgram_get_mtu_overhead() returns a value in bytes.
+
+=head1 SEE ALSO
+
+L<BIO_sendmmsg(3)>, L<BIO_s_dgram_pair(3)>, L<DTLSv1_listen(3)>, L<bio(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index 13f6f1ff14575f0e15fe65eed64807015d5597bc..b16a82de9a8e9eaa4881699609375fd26fe311a8 100644 (file)
@@ -64,6 +64,23 @@ does not support this), then B<*peer> will be cleared and the family set to
 AF_UNSPEC. Typically user code is expected to "connect" the underlying socket to
 the peer and continue the handshake in a connected state.
 
+Warning: It is essential that the calling code connects the underlying socket to
+the peer after making use of DTLSv1_listen(). In the typical case where
+L<BIO_s_datagram(3)> is used, the peer address is updated when receiving a
+datagram on an unconnected socket. If the socket is not connected, it can
+receive datagrams from any host on the network, which will cause subsequent
+outgoing datagrams transmitted by DTLS to be transmitted to that host. In other
+words, failing to call BIO_connect() or a similar OS-specific function on a
+socket means that any host on the network can cause outgoing DTLS traffic to be
+redirected to it by sending a datagram to the socket in question. This does not
+break the cryptographic protections of DTLS but may facilitate a
+denial-of-service attack or allow unencrypted information in the DTLS handshake
+to be learned by an attacker. This is due to the historical design of
+L<BIO_s_datagram(3)>; see L<BIO_s_datagram(3)> for details on this issue.
+
+Once a socket has been connected, L<BIO_ctrl_set_connected(3)> should be used to
+inform the BIO that the socket is to be used in connected mode.
+
 Prior to calling DTLSv1_listen() user code must ensure that cookie generation
 and verification callbacks have been set up using
 L<SSL_CTX_set_cookie_generate_cb(3)> and L<SSL_CTX_set_cookie_verify_cb(3)>
index a70861fb1f1ca968bed46cd0960d5659b51f04f4..a603ff7545e691d8d70057da14efc0da956b2385 100644 (file)
@@ -201,7 +201,6 @@ BIO_indent(3)
 BIO_method_name(3)
 BIO_new_NDEF(3)
 BIO_new_PKCS7(3)
-BIO_new_dgram(3)
 BIO_new_dgram_sctp(3)
 BIO_nread(3)
 BIO_nread0(3)
@@ -209,7 +208,6 @@ BIO_number_read(3)
 BIO_number_written(3)
 BIO_nwrite(3)
 BIO_nwrite0(3)
-BIO_s_datagram(3)
 BIO_s_datagram_sctp(3)
 BIO_s_log(3)
 BIO_set_flags(3)
index ad03758ba3f56edcb994f1584dc4e0f0d92f91fd..50b4b17b15c9902f870dd92ed278b44d017e816d 100644 (file)
@@ -12,13 +12,6 @@ BIO_cb_post(3)
 BIO_dup_state(3)
 BIO_buffer_get_num_lines(3)
 BIO_buffer_peek(3)
-BIO_ctrl_dgram_connect(3)
-BIO_ctrl_set_connected(3)
-BIO_dgram_recv_timedout(3)
-BIO_dgram_send_timedout(3)
-BIO_dgram_get_peer(3)
-BIO_dgram_set_peer(3)
-BIO_dgram_get_mtu_overhead(3)
 BIO_sock_cleanup(3)
 ossl_bio__attr__(3)
 BN_prime_checks_for_size(3)
index 94bc79e9eec99fc529bace7b8f8fa39f640b534d..267c0ff39c17eb1f64c8424890168745a4dfd4e4 100644 (file)
@@ -161,6 +161,13 @@ BIO_dgram_set_caps                      define
 BIO_dgram_get_effective_caps            define
 BIO_dgram_get_mtu                       define
 BIO_dgram_set_mtu                       define
+BIO_ctrl_dgram_connect                  define
+BIO_ctrl_set_connected                  define
+BIO_dgram_get_mtu_overhead              define
+BIO_dgram_get_peer                      define
+BIO_dgram_set_peer                      define
+BIO_dgram_recv_timedout                 define
+BIO_dgram_send_timedout                 define
 BIO_do_accept                           define
 BIO_do_connect                          define
 BIO_do_handshake                        define