164 lines
8.2 KiB
HTML
164 lines
8.2 KiB
HTML
|
<?xml version="1.0" ?>
|
||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
<head>
|
||
|
<title>DTLSv1_listen</title>
|
||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||
|
<link rev="made" href="mailto:root@localhost" />
|
||
|
</head>
|
||
|
|
||
|
<body style="background-color: white">
|
||
|
|
||
|
|
||
|
<!-- INDEX BEGIN -->
|
||
|
<div name="index">
|
||
|
<p><a name="__index__"></a></p>
|
||
|
|
||
|
<ul>
|
||
|
|
||
|
<li><a href="#name">NAME</a></li>
|
||
|
<li><a href="#synopsis">SYNOPSIS</a></li>
|
||
|
<li><a href="#description">DESCRIPTION</a></li>
|
||
|
<li><a href="#notes">NOTES</a></li>
|
||
|
<li><a href="#return_values">RETURN VALUES</a></li>
|
||
|
<li><a href="#see_also">SEE ALSO</a></li>
|
||
|
<li><a href="#history">HISTORY</a></li>
|
||
|
<li><a href="#copyright">COPYRIGHT</a></li>
|
||
|
</ul>
|
||
|
|
||
|
<hr name="index" />
|
||
|
</div>
|
||
|
<!-- INDEX END -->
|
||
|
|
||
|
<p>
|
||
|
</p>
|
||
|
<hr />
|
||
|
<h1><a name="name">NAME</a></h1>
|
||
|
<p>SSL_stateless,
|
||
|
DTLSv1_listen
|
||
|
- Statelessly listen for incoming connections</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<hr />
|
||
|
<h1><a name="synopsis">SYNOPSIS</a></h1>
|
||
|
<pre>
|
||
|
#include <openssl/ssl.h></pre>
|
||
|
<pre>
|
||
|
int SSL_stateless(SSL *s);
|
||
|
int DTLSv1_listen(SSL *ssl, BIO_ADDR *peer);</pre>
|
||
|
<p>
|
||
|
</p>
|
||
|
<hr />
|
||
|
<h1><a name="description">DESCRIPTION</a></h1>
|
||
|
<p><code>SSL_stateless()</code> statelessly listens for new incoming TLSv1.3 connections.
|
||
|
DTLSv1_listen() statelessly listens for new incoming DTLS connections. If a
|
||
|
ClientHello is received that does not contain a cookie, then they respond with a
|
||
|
request for a new ClientHello that does contain a cookie. If a ClientHello is
|
||
|
received with a cookie that is verified then the function returns in order to
|
||
|
enable the handshake to be completed (for example by using SSL_accept()).</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<hr />
|
||
|
<h1><a name="notes">NOTES</a></h1>
|
||
|
<p>Some transport protocols (such as UDP) can be susceptible to amplification
|
||
|
attacks. Unlike TCP there is no initial connection setup in UDP that
|
||
|
validates that the client can actually receive messages on its advertised source
|
||
|
address. An attacker could forge its source IP address and then send handshake
|
||
|
initiation messages to the server. The server would then send its response to
|
||
|
the forged source IP. If the response messages are larger than the original
|
||
|
message then the amplification attack has succeeded.</p>
|
||
|
<p>If DTLS is used over UDP (or any datagram based protocol that does not validate
|
||
|
the source IP) then it is susceptible to this type of attack. TLSv1.3 is
|
||
|
designed to operate over a stream-based transport protocol (such as TCP).
|
||
|
If TCP is being used then there is no need to use <code>SSL_stateless()</code>. However some
|
||
|
stream-based transport protocols (e.g. QUIC) may not validate the source
|
||
|
address. In this case a TLSv1.3 application would be susceptible to this attack.</p>
|
||
|
<p>As a countermeasure to this issue TLSv1.3 and DTLS include a stateless cookie
|
||
|
mechanism. The idea is that when a client attempts to connect to a server it
|
||
|
sends a ClientHello message. The server responds with a HelloRetryRequest (in
|
||
|
TLSv1.3) or a HelloVerifyRequest (in DTLS) which contains a unique cookie. The
|
||
|
client then resends the ClientHello, but this time includes the cookie in the
|
||
|
message thus proving that the client is capable of receiving messages sent to
|
||
|
that address. All of this can be done by the server without allocating any
|
||
|
state, and thus without consuming expensive resources.</p>
|
||
|
<p>OpenSSL implements this capability via the <code>SSL_stateless()</code> and DTLSv1_listen()
|
||
|
functions. The <strong>ssl</strong> parameter should be a newly allocated SSL object with its
|
||
|
read and write BIOs set, in the same way as might be done for a call to
|
||
|
<code>SSL_accept()</code>. Typically, for DTLS, the read BIO will be in an "unconnected"
|
||
|
state and thus capable of receiving messages from any peer.</p>
|
||
|
<p>When a ClientHello is received that contains a cookie that has been verified,
|
||
|
then these functions will return with the <strong>ssl</strong> parameter updated into a state
|
||
|
where the handshake can be continued by a call to (for example) <code>SSL_accept()</code>.
|
||
|
Additionally, for DTLSv1_listen(), the <strong>BIO_ADDR</strong> pointed to by <strong>peer</strong> will be
|
||
|
filled in with details of the peer that sent the ClientHello. If the underlying
|
||
|
BIO is unable to obtain the <strong>BIO_ADDR</strong> of the peer (for example because the BIO
|
||
|
does not support this), then <strong>*peer</strong> 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.</p>
|
||
|
<p>Prior to calling DTLSv1_listen() user code must ensure that cookie generation
|
||
|
and verification callbacks have been set up using
|
||
|
<em>SSL_CTX_set_cookie_generate_cb(3)</em> and <em>SSL_CTX_set_cookie_verify_cb(3)</em>
|
||
|
respectively. For <code>SSL_stateless()</code>, <em>SSL_CTX_set_stateless_cookie_generate_cb(3)</em>
|
||
|
and <em>SSL_CTX_set_stateless_cookie_verify_cb(3)</em> must be used instead.</p>
|
||
|
<p>Since DTLSv1_listen() operates entirely statelessly whilst processing incoming
|
||
|
ClientHellos it is unable to process fragmented messages (since this would
|
||
|
require the allocation of state). An implication of this is that DTLSv1_listen()
|
||
|
<strong>only</strong> supports ClientHellos that fit inside a single datagram.</p>
|
||
|
<p>For <code>SSL_stateless()</code> if an entire ClientHello message cannot be read without the
|
||
|
"read" BIO becoming empty then the <code>SSL_stateless()</code> call will fail. It is the
|
||
|
application's responsibility to ensure that data read from the "read" BIO during
|
||
|
a single <code>SSL_stateless()</code> call is all from the same peer.</p>
|
||
|
<p><code>SSL_stateless()</code> will fail (with a 0 return value) if some TLS version less than
|
||
|
TLSv1.3 is used.</p>
|
||
|
<p>Both <code>SSL_stateless()</code> and DTLSv1_listen() will clear the error queue when they
|
||
|
start.</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<hr />
|
||
|
<h1><a name="return_values">RETURN VALUES</a></h1>
|
||
|
<p>For <code>SSL_stateless()</code> a return value of 1 indicates success and the <strong>ssl</strong> object
|
||
|
will be set up ready to continue the handshake. A return value of 0 or -1
|
||
|
indicates failure. If the value is 0 then a HelloRetryRequest was sent. A value
|
||
|
of -1 indicates any other error. User code may retry the <code>SSL_stateless()</code> call.</p>
|
||
|
<p>For DTLSv1_listen() a return value of >= 1 indicates success. The <strong>ssl</strong> object
|
||
|
will be set up ready to continue the handshake. the <strong>peer</strong> value will also be
|
||
|
filled in.</p>
|
||
|
<p>A return value of 0 indicates a non-fatal error. This could (for
|
||
|
example) be because of non-blocking IO, or some invalid message having been
|
||
|
received from a peer. Errors may be placed on the OpenSSL error queue with
|
||
|
further information if appropriate. Typically user code is expected to retry the
|
||
|
call to DTLSv1_listen() in the event of a non-fatal error.</p>
|
||
|
<p>A return value of <0 indicates a fatal error. This could (for example) be
|
||
|
because of a failure to allocate sufficient memory for the operation.</p>
|
||
|
<p>For DTLSv1_listen(), prior to OpenSSL 1.1.0, fatal and non-fatal errors both
|
||
|
produce return codes <= 0 (in typical implementations user code treats all
|
||
|
errors as non-fatal), whilst return codes >0 indicate success.</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<hr />
|
||
|
<h1><a name="see_also">SEE ALSO</a></h1>
|
||
|
<p><em>SSL_CTX_set_cookie_generate_cb(3)</em>, <em>SSL_CTX_set_cookie_verify_cb(3)</em>,
|
||
|
<em>SSL_CTX_set_stateless_cookie_generate_cb(3)</em>,
|
||
|
<em>SSL_CTX_set_stateless_cookie_verify_cb(3)</em>, <em>SSL_get_error(3)</em>,
|
||
|
<em>SSL_accept(3)</em>, <em>ssl(7)</em>, <em>bio(7)</em></p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<hr />
|
||
|
<h1><a name="history">HISTORY</a></h1>
|
||
|
<p>The <code>SSL_stateless()</code> function was added in OpenSSL 1.1.1.</p>
|
||
|
<p>The DTLSv1_listen() return codes were clarified in OpenSSL 1.1.0.
|
||
|
The type of "peer" also changed in OpenSSL 1.1.0.</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<hr />
|
||
|
<h1><a name="copyright">COPYRIGHT</a></h1>
|
||
|
<p>Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.</p>
|
||
|
<p>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
|
||
|
<a href="https://www.openssl.org/source/license.html">https://www.openssl.org/source/license.html</a>.</p>
|
||
|
|
||
|
</body>
|
||
|
|
||
|
</html>
|