/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsslconfiguration.h"
#include "qdtls_openssl_p.h"
#include "qudpsocket.h"
#include "qdtls_p.h"
#include "qssl_p.h"
#include "qdtls.h"

#include "qglobal.h"

/*!
    \class QDtlsClientVerifier
    \brief This class implements server-side DTLS cookie generation and verification.
    \since 5.12

    \ingroup network
    \ingroup ssl
    \inmodule QtNetwork

    The QDtlsClientVerifier class implements server-side DTLS cookie generation
    and verification. Datagram security protocols are highly susceptible to a
    variety of Denial-of-Service attacks. According to \l {https://tools.ietf.org/html/rfc6347#section-4.2.1}{RFC 6347, section 4.2.1},
    these are two of the more common types of attack:

    \list
    \li An attacker transmits a series of handshake initiation requests, causing
    a server to allocate excessive resources and potentially perform expensive
    cryptographic operations.
    \li An attacker transmits a series of handshake initiation requests with
    a forged source of the victim, making the server act as an amplifier.
    Normally, the server would reply to the victim machine with a Certificate message,
    which can be quite large, thus flooding the victim machine with datagrams.
    \endlist

    As a countermeasure to these attacks, \l {https://tools.ietf.org/html/rfc6347#section-4.2.1}{RFC 6347, section 4.2.1}
    proposes a stateless cookie technique that a server may deploy:

    \list
    \li In response to the initial ClientHello message, the server sends a HelloVerifyRequest,
    which contains a cookie. This cookie is a cryptographic hash and is generated using the
    client's address, port number, and the server's secret (which is a cryptographically strong
    pseudo-random sequence of bytes).
    \li A reachable DTLS client is expected to reply with a new ClientHello message
    containing this cookie.
    \li When the server receives the ClientHello message with a cookie, it
    generates a new cookie as described above. This new cookie is compared to the
    one found in the ClientHello message.
    \li In the cookies are equal, the client is considered to be real, and the
    server can continue with a TLS handshake procedure.
    \endlist

    \note A DTLS server is not required to use DTLS cookies.

    QDtlsClientVerifier is designed to work in pair with QUdpSocket, as shown in
    the following code-excerpt:

    \snippet code/src_network_ssl_qdtlscookie.cpp 0

    QDtlsClientVerifier does not impose any restrictions on how the application uses
    QUdpSocket. For example, it is possible to have a server with a single QUdpSocket
    in state QAbstractSocket::BoundState, handling multiple DTLS clients
    simultaneously:

    \list
    \li Testing if new clients are real DTLS-capable clients.
    \li Completing TLS handshakes with the verified clients (see QDtls).
    \li Decrypting datagrams coming from the connected clients (see QDtls).
    \li Sending encrypted datagrams to the connected clients (see QDtls).
    \endlist

    This implies that QDtlsClientVerifier does not read directly from a socket,
    instead it expects the application to read an incoming datagram, extract the
    sender's address, and port, and then pass this data to verifyClient().
    To send a HelloVerifyRequest message, verifyClient() can write to the QUdpSocket.

    \note QDtlsClientVerifier does not take ownership of the QUdpSocket object.

    By default QDtlsClientVerifier obtains its secret from a cryptographically
    strong pseudorandom number generator.

    \note The default secret is shared by all objects of the classes QDtlsClientVerifier
    and QDtls. Since this can impose security risks, RFC 6347 recommends to change
    the server's secret frequently. Please see \l {https://tools.ietf.org/html/rfc6347}{RFC 6347, section 4.2.1}
    for hints about possible server implementations. Cookie generator parameters
    can be set using the class QDtlsClientVerifier::GeneratorParameters and
    setCookieGeneratorParameters():

    \snippet code/src_network_ssl_qdtlscookie.cpp 1

    The \l{secureudpserver}{DTLS server} example illustrates how to use
    QDtlsClientVerifier in a server application.

    \sa QUdpSocket, QAbstractSocket::BoundState, QDtls, verifyClient(),
    GeneratorParameters, setCookieGeneratorParameters(), cookieGeneratorParameters(),
    QDtls::setCookieGeneratorParameters(),
    QDtls::cookieGeneratorParameters(),
    QCryptographicHash::Algorithm,
    QDtlsError, dtlsError(), dtlsErrorString()
*/

/*!
    \class QDtlsClientVerifier::GeneratorParameters
    \brief This class defines parameters for DTLS cookie generator.
    \since 5.12

    \ingroup network
    \ingroup ssl
    \inmodule QtNetwork

    An object of this class provides the parameters that QDtlsClientVerifier
    will use to generate DTLS cookies. They include a cryptographic hash
    algorithm and a secret.

    \note An empty secret is considered to be invalid by
    QDtlsClientVerifier::setCookieGeneratorParameters().

    \sa QDtlsClientVerifier::setCookieGeneratorParameters(),
    QDtlsClientVerifier::cookieGeneratorParameters(),
    QDtls::setCookieGeneratorParameters(),
    QDtls::cookieGeneratorParameters(),
    QCryptographicHash::Algorithm
*/

/*!
    \enum QDtlsError
    \brief Describes errors that can be found by QDtls and QDtlsClientVerifier.
    \relates QDtls
    \since 5.12

    \ingroup network
    \ingroup ssl
    \inmodule QtNetwork

    This enum describes general and TLS-specific errors that can be encountered
    by objects of the classes QDtlsClientVerifier and QDtls.

    \value NoError No error occurred, the last operation was successful.
    \value InvalidInputParameters Input parameters provided by a caller were
           invalid.
    \value InvalidOperation An operation was attempted in a state that did not
           permit it.
    \value UnderlyingSocketError QUdpSocket::writeDatagram() failed, QUdpSocket::error()
           and QUdpSocket::errorString() can provide more specific information.
    \value RemoteClosedConnectionError TLS shutdown alert message was received.
    \value PeerVerificationError Peer's identity could not be verified during the
           TLS handshake.
    \value TlsInitializationError An error occurred while initializing an underlying
           TLS backend.
    \value TlsFatalError A fatal error occurred during TLS handshake, other
           than peer verification error or TLS initialization error.
    \value TlsNonFatalError A failure to encrypt or decrypt a datagram, non-fatal,
           meaning QDtls can continue working after this error.
*/

/*!
    \class QDtls
    \brief This class provides encryption for UDP sockets.
    \since 5.12

    \ingroup network
    \ingroup ssl
    \inmodule QtNetwork

    The QDtls class can be used to establish a secure connection with a network
    peer using User Datagram Protocol (UDP). DTLS connection over essentially
    connectionless UDP means that two peers first have to successfully complete
    a TLS handshake by calling doHandshake(). After the handshake has completed,
    encrypted datagrams can be sent to the peer using writeDatagramEncrypted().
    Encrypted datagrams coming from the peer can be decrypted by decryptDatagram().

    QDtls is designed to work with QUdpSocket. Since QUdpSocket can receive
    datagrams coming from different peers, an application must implement
    demultiplexing, forwarding datagrams coming from different peers to their
    corresponding instances of QDtls. An association between a network peer
    and its QDtls object can be established using the peer's address and port
    number. Before starting a handshake, the application must set the peer's
    address and port number using setPeer().

    QDtls does not read datagrams from QUdpSocket, this is expected to be done by
    the application, for example, in a slot attached to the QUdpSocket::readyRead()
    signal. Then, these datagrams must be processed by QDtls.

    \note QDtls does \e not take ownership of the QUdpSocket object.

    Normally, several datagrams are to be received and sent by both peers during
    the handshake phase. Upon reading datagrams, server and client must pass these
    datagrams to doHandshake() until some error is found or handshakeState()
    returns HandshakeComplete:

    \snippet code/src_network_ssl_qdtls.cpp 0

    For a server, the first call to doHandshake() requires a non-empty datagram
    containing a ClientHello message. If the server also deploys QDtlsClientVerifier,
    the first ClientHello message is expected to be the one verified by QDtlsClientVerifier.

    In case the peer's identity cannot be validated during the handshake, the application
    must inspect errors returned by peerVerificationErrors() and then either
    ignore errors by calling ignoreVerificationErrors() or abort the handshake
    by calling abortHandshake(). If errors were ignored, the handshake can be
    resumed by calling resumeHandshake().

    After the handshake has been completed, datagrams can be sent to and received
    from the network peer securely:

    \snippet code/src_network_ssl_qdtls.cpp 2

    A DTLS connection may be closed using shutdown().

    \snippet code/src_network_ssl_qdtls.cpp 3

    \warning It's recommended to call shutdown() before destroying the client's QDtls
    object if you are planning to re-use the same port number to connect to the
    server later. Otherwise, the server may drop incoming ClientHello messages,
    see \l{https://tools.ietf.org/html/rfc6347#page-25}{RFC 6347, section 4.2.8}
    for more details and implementation hints.

    If the server does not use QDtlsClientVerifier, it \e must configure its
    QDtls objects to disable the cookie verification procedure:

    \snippet code/src_network_ssl_qdtls.cpp 4

    A server that uses cookie verification with non-default generator parameters
    \e must set the same parameters for its QDtls object before starting the handshake.

    \note The DTLS protocol leaves Path Maximum Transmission Unit (PMTU) discovery
    to the application. The application may provide QDtls with the MTU using
    setMtuHint(). This hint affects only the handshake phase, since only handshake
    messages can be fragmented and reassembled by the DTLS. All other messages sent
    by the application must fit into a single datagram.
    \note DTLS-specific headers add some overhead to application data further
    reducing the possible message size.
    \warning A server configured to reply with HelloVerifyRequest will drop
    all fragmented ClientHello messages, never starting a handshake.

    The \l{secureudpserver}{DTLS server} and \l{secureudpclient}{DTLS client}
    examples illustrate how to use QDtls in applications.

    \sa QUdpSocket, QDtlsClientVerifier, HandshakeState, QDtlsError, QSslConfiguration
*/

/*!
    \typedef QDtls::GeneratorParameters

    This is a synonym for QDtlsClientVerifier::GeneratorParameters.
*/

/*!
    \fn void QDtls::handshakeTimeout()

    Packet loss can result in timeouts during the handshake phase. In this case
    QDtls emits a handshakeTimeout() signal. Call handleTimeout() to retransmit
    the handshake messages:

    \snippet code/src_network_ssl_qdtls.cpp 1

    \sa handleTimeout()
*/

/*!
    \fn void QDtls::pskRequired(QSslPreSharedKeyAuthenticator *authenticator)

    QDtls emits this signal when it negotiates a PSK ciphersuite, and therefore
    a PSK authentication is then required.

    When using PSK, the client must send to the server a valid identity and a
    valid pre shared key, in order for the TLS handshake to continue.
    Applications can provide this information in a slot connected to this
    signal, by filling in the passed \a authenticator object according to their
    needs.

    \note Ignoring this signal, or failing to provide the required credentials,
    will cause the handshake to fail, and therefore the connection to be aborted.

    \note The \a authenticator object is owned by QDtls and must not be deleted
    by the application.

    \sa QSslPreSharedKeyAuthenticator
*/

/*!
    \enum QDtls::HandshakeState
    \brief Describes the current state of DTLS handshake.
    \since 5.12

    \ingroup network
    \ingroup ssl
    \inmodule QtNetwork

    This enum describes the current state of DTLS handshake for a QDtls
    connection.

    \value HandshakeNotStarted Nothing done yet.
    \value HandshakeInProgress Handshake was initiated and no errors were found so far.
    \value PeerVerificationFailed The identity of the peer can't be established.
    \value HandshakeComplete Handshake completed successfully and encrypted connection
           was established.

    \sa QDtls::doHandshake(), QDtls::handshakeState()
*/


QT_BEGIN_NAMESPACE

QSslConfiguration QDtlsBasePrivate::configuration() const
{
    auto copyPrivate = new QSslConfigurationPrivate(dtlsConfiguration);
    copyPrivate->ref.storeRelaxed(0); // the QSslConfiguration constructor refs up
    QSslConfiguration copy(copyPrivate);
    copyPrivate->sessionCipher = sessionCipher;
    copyPrivate->sessionProtocol = sessionProtocol;

    return copy;
}

void QDtlsBasePrivate::setConfiguration(const QSslConfiguration &configuration)
{
    dtlsConfiguration.localCertificateChain = configuration.localCertificateChain();
    dtlsConfiguration.privateKey = configuration.privateKey();
    dtlsConfiguration.ciphers = configuration.ciphers();
    dtlsConfiguration.ellipticCurves = configuration.ellipticCurves();
    dtlsConfiguration.preSharedKeyIdentityHint = configuration.preSharedKeyIdentityHint();
    dtlsConfiguration.dhParams = configuration.diffieHellmanParameters();
    dtlsConfiguration.caCertificates = configuration.caCertificates();
    dtlsConfiguration.peerVerifyDepth = configuration.peerVerifyDepth();
    dtlsConfiguration.peerVerifyMode = configuration.peerVerifyMode();
    dtlsConfiguration.protocol = configuration.protocol();
    dtlsConfiguration.sslOptions = configuration.d->sslOptions;
    dtlsConfiguration.sslSession = configuration.sessionTicket();
    dtlsConfiguration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
    dtlsConfiguration.nextAllowedProtocols = configuration.allowedNextProtocols();
    dtlsConfiguration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
    dtlsConfiguration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
    dtlsConfiguration.dtlsCookieEnabled = configuration.dtlsCookieVerificationEnabled();
    dtlsConfiguration.allowRootCertOnDemandLoading = configuration.d->allowRootCertOnDemandLoading;
    dtlsConfiguration.backendConfig = configuration.backendConfiguration();

    clearDtlsError();
}

bool QDtlsBasePrivate::setCookieGeneratorParameters(QCryptographicHash::Algorithm alg,
                                                    const QByteArray &key)
{
    if (!key.size()) {
        setDtlsError(QDtlsError::InvalidInputParameters,
                     QDtls::tr("Invalid (empty) secret"));
        return false;
    }

    clearDtlsError();

    hashAlgorithm = alg;
    secret = key;

    return true;
}

bool QDtlsBasePrivate::isDtlsProtocol(QSsl::SslProtocol protocol)
{
    switch (protocol) {
    case QSsl::DtlsV1_0:
    case QSsl::DtlsV1_0OrLater:
    case QSsl::DtlsV1_2:
    case QSsl::DtlsV1_2OrLater:
        return true;
    default:
        return false;
    }
}

static QString msgUnsupportedMulticastAddress()
{
    return QDtls::tr("Multicast and broadcast addresses are not supported");
}

/*!
    Default constructs GeneratorParameters object with QCryptographicHash::Sha1
    as its algorithm and an empty secret.

    \sa QDtlsClientVerifier::setCookieGeneratorParameters(),
    QDtlsClientVerifier::cookieGeneratorParameters(),
    QDtls::setCookieGeneratorParameters(),
    QDtls::cookieGeneratorParameters()
 */
QDtlsClientVerifier::GeneratorParameters::GeneratorParameters()
{
}

/*!
    Constructs GeneratorParameters object from \a algorithm and \a secret.

    \sa QDtlsClientVerifier::setCookieGeneratorParameters(),
    QDtlsClientVerifier::cookieGeneratorParameters(),
    QDtls::setCookieGeneratorParameters(),
    QDtls::cookieGeneratorParameters()
 */
QDtlsClientVerifier::GeneratorParameters::GeneratorParameters(QCryptographicHash::Algorithm algorithm, const QByteArray &secret)
    : hash(algorithm), secret(secret)
{
}

/*!
    Constructs a QDtlsClientVerifier object, \a parent is passed to QObject's
    constructor.
*/
QDtlsClientVerifier::QDtlsClientVerifier(QObject *parent)
    : QObject(*new QDtlsClientVerifierOpenSSL, parent)
{
    Q_D(QDtlsClientVerifier);

    d->mode = QSslSocket::SslServerMode;
    // The default configuration suffices: verifier never does a full
    // handshake and upon verifying a cookie in a client hello message,
    // it reports success.
    auto conf = QSslConfiguration::defaultDtlsConfiguration();
    conf.setPeerVerifyMode(QSslSocket::VerifyNone);
    d->setConfiguration(conf);
}

/*!
    Destroys the QDtlsClientVerifier object.
*/
QDtlsClientVerifier::~QDtlsClientVerifier()
{
}

/*!
    Sets the secret and the cryptographic hash algorithm from \a params. This
    QDtlsClientVerifier will use these to generate cookies. If the new secret
    has size zero, this function returns \c false and does not change the
    cookie generator parameters.

    \note The secret is supposed to be a cryptographically secure sequence of bytes.

    \sa QDtlsClientVerifier::GeneratorParameters, cookieGeneratorParameters(),
    QCryptographicHash::Algorithm
*/
bool QDtlsClientVerifier::setCookieGeneratorParameters(const GeneratorParameters &params)
{
    Q_D(QDtlsClientVerifier);

    return d->setCookieGeneratorParameters(params.hash, params.secret);
}

/*!
    Returns the current secret and hash algorithm used to generate cookies.
    The default hash algorithm is QCryptographicHash::Sha256 if Qt was configured
    to support it, QCryptographicHash::Sha1 otherwise. The default secret is
    obtained from the backend-specific cryptographically strong pseudorandom
    number generator.

    \sa QCryptographicHash::Algorithm, QDtlsClientVerifier::GeneratorParameters,
    setCookieGeneratorParameters()
*/
QDtlsClientVerifier::GeneratorParameters QDtlsClientVerifier::cookieGeneratorParameters() const
{
    Q_D(const QDtlsClientVerifier);

    return {d->hashAlgorithm, d->secret};
}

/*!
    \a socket must be a valid pointer, \a dgram must be a non-empty
    datagram, \a address cannot be null, broadcast, or multicast.
    \a port is the remote peer's port. This function returns \c true
    if \a dgram contains a ClientHello message with a valid cookie.
    If no matching cookie is found, verifyClient() will send a
    HelloVerifyRequest message using \a socket and return \c false.

    The following snippet shows how a server application may check for errors:

    \snippet code/src_network_ssl_qdtlscookie.cpp 2

    \sa QHostAddress::isNull(), QHostAddress::isBroadcast(), QHostAddress::isMulticast(),
    setCookieGeneratorParameters(), cookieGeneratorParameters()
*/
bool QDtlsClientVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgram,
                                       const QHostAddress &address, quint16 port)
{
    Q_D(QDtlsClientVerifier);

    if (!socket || address.isNull() || !dgram.size()) {
        d->setDtlsError(QDtlsError::InvalidInputParameters,
                        tr("A valid UDP socket, non-empty datagram, valid address/port were expected"));
        return false;
    }

    if (address.isBroadcast() || address.isMulticast()) {
        d->setDtlsError(QDtlsError::InvalidInputParameters,
                        msgUnsupportedMulticastAddress());
        return false;
    }

    return d->verifyClient(socket, dgram, address, port);
}

/*!
    Convenience function. Returns the last ClientHello message that was successfully
    verified, or an empty QByteArray if no verification has completed.

    \sa verifyClient()
*/
QByteArray QDtlsClientVerifier::verifiedHello() const
{
    Q_D(const QDtlsClientVerifier);

    return d->verifiedClientHello;
}

/*!
    Returns the last error that occurred or QDtlsError::NoError.

    \sa QDtlsError, dtlsErrorString()
*/
QDtlsError QDtlsClientVerifier::dtlsError() const
{
    Q_D(const QDtlsClientVerifier);

    return d->errorCode;
}

/*!
    Returns a textual description of the last error, or an empty string.

    \sa dtlsError()
 */
QString QDtlsClientVerifier::dtlsErrorString() const
{
    Q_D(const QDtlsBase);

    return d->errorDescription;
}

/*!
    Creates a QDtls object, \a parent is passed to the QObject constructor.
    \a mode is QSslSocket::SslServerMode for a server-side DTLS connection or
    QSslSocket::SslClientMode for a client.

    \sa sslMode(), QSslSocket::SslMode
*/
QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent)
    : QObject(*new QDtlsPrivateOpenSSL, parent)
{
    Q_D(QDtls);

    d->mode = mode;
    setDtlsConfiguration(QSslConfiguration::defaultDtlsConfiguration());
}

/*!
    Destroys the QDtls object.
*/
QDtls::~QDtls()
{
}

/*!
    Sets the peer's address, \a port, and host name and returns \c true
    if successful. \a address must not be null, multicast, or broadcast.
    \a verificationName is the host name used for the certificate validation.

    \sa peerAddress(), peerPort(), peerVerificationName()
 */
bool QDtls::setPeer(const QHostAddress &address, quint16 port,
                    const QString &verificationName)
{
    Q_D(QDtls);

    if (d->handshakeState != HandshakeNotStarted) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot set peer after handshake started"));
        return false;
    }

    if (address.isNull()) {
        d->setDtlsError(QDtlsError::InvalidInputParameters,
                        tr("Invalid address"));
        return false;
    }

    if (address.isBroadcast() || address.isMulticast()) {
        d->setDtlsError(QDtlsError::InvalidInputParameters,
                        msgUnsupportedMulticastAddress());
        return false;
    }

    d->clearDtlsError();

    d->remoteAddress = address;
    d->remotePort = port;
    d->peerVerificationName = verificationName;

    return true;
}

/*!
    Sets the host \a name that will be used for the certificate validation
    and returns \c true if successful.

    \note This function must be called before the handshake starts.

    \sa peerVerificationName(), setPeer()
*/
bool QDtls::setPeerVerificationName(const QString &name)
{
    Q_D(QDtls);

    if (d->handshakeState != HandshakeNotStarted) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot set verification name after handshake started"));
        return false;
    }

    d->clearDtlsError();
    d->peerVerificationName = name;

    return true;
}

/*!
    Returns the peer's address, set by setPeer(), or QHostAddress::Null.

    \sa setPeer()
*/
QHostAddress QDtls::peerAddress() const
{
    Q_D(const QDtls);

    return d->remoteAddress;
}

/*!
    Returns the peer's port number, set by setPeer(), or 0.

    \sa setPeer()
*/
quint16 QDtls::peerPort() const
{
    Q_D(const QDtlsBase);

    return d->remotePort;
}

/*!
    Returns the host name set by setPeer() or setPeerVerificationName().
    The default value is an empty string.

    \sa setPeerVerificationName(), setPeer()
*/
QString QDtls::peerVerificationName() const
{
    Q_D(const QDtls);

    return d->peerVerificationName;
}

/*!
    Returns QSslSocket::SslServerMode for a server-side connection and
    QSslSocket::SslClientMode for a client.

    \sa QDtls(), QSslSocket::SslMode
*/
QSslSocket::SslMode QDtls::sslMode() const
{
    Q_D(const QDtls);

    return d->mode;
}

/*!
    \a mtuHint is the maximum transmission unit (MTU), either discovered or guessed
    by the application. The application is not required to set this value.

    \sa mtuHint(), QAbstractSocket::PathMtuSocketOption
 */
void QDtls::setMtuHint(quint16 mtuHint)
{
    Q_D(QDtls);

    d->mtuHint = mtuHint;
}

/*!
    Returns the value previously set by setMtuHint(). The default value is 0.

    \sa setMtuHint()
 */
quint16 QDtls::mtuHint() const
{
    Q_D(const QDtls);

    return d->mtuHint;
}

/*!
    Sets the cryptographic hash algorithm and the secret from \a params.
    This function is only needed for a server-side QDtls connection.
    Returns \c true if successful.

    \note This function must be called before the handshake starts.

    \sa cookieGeneratorParameters(), doHandshake(), QDtlsClientVerifier,
    QDtlsClientVerifier::cookieGeneratorParameters()
*/
bool QDtls::setCookieGeneratorParameters(const GeneratorParameters &params)
{
    Q_D(QDtls);

    return d->setCookieGeneratorParameters(params.hash, params.secret);
}

/*!
    Returns the current hash algorithm and secret, either default ones or previously
    set by a call to setCookieGeneratorParameters().

    The default hash algorithm is QCryptographicHash::Sha256 if Qt was
    configured to support it, QCryptographicHash::Sha1 otherwise. The default
    secret is obtained from the backend-specific cryptographically strong
    pseudorandom number generator.

    \sa QDtlsClientVerifier, cookieGeneratorParameters()
*/
QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const
{
    Q_D(const QDtls);

    return {d->hashAlgorithm, d->secret};
}

/*!
    Sets the connection's TLS configuration from \a configuration
    and returns \c true if successful.

    \note This function must be called before the handshake starts.

    \sa dtlsConfiguration(), doHandshake()
*/
bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)
{
    Q_D(QDtls);

    if (d->handshakeState != HandshakeNotStarted) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot set configuration after handshake started"));
        return false;
    }

    d->setConfiguration(configuration);
    return true;
}

/*!
    Returns either the default DTLS configuration or the configuration set by an
    earlier call to setDtlsConfiguration().

    \sa setDtlsConfiguration(), QSslConfiguration::defaultDtlsConfiguration()
*/
QSslConfiguration QDtls::dtlsConfiguration() const
{
    Q_D(const QDtls);

    return d->configuration();
}

/*!
    Returns the current handshake state for this QDtls.

    \sa doHandshake(), QDtls::HandshakeState
 */
QDtls::HandshakeState QDtls::handshakeState()const
{
    Q_D(const QDtls);

    return d->handshakeState;
}

/*!
    Starts or continues a DTLS handshake. \a socket must be a valid pointer.
    When starting a server-side DTLS handshake, \a dgram must contain the initial
    ClientHello message read from QUdpSocket. This function returns \c true if
    no error was found. Handshake state can be tested using handshakeState().
    \c false return means some error occurred, use dtlsError() for more
    detailed information.

    \note If the identity of the peer can't be established, the error is set to
    QDtlsError::PeerVerificationError. If you want to ignore verification errors
    and continue connecting, you must call ignoreVerificationErrors() and then
    resumeHandshake(). If the errors cannot be ignored, you must call
    abortHandshake().

    \snippet code/src_network_ssl_qdtls.cpp 5

    \sa handshakeState(), dtlsError(), ignoreVerificationErrors(), resumeHandshake(),
    abortHandshake()
*/
bool QDtls::doHandshake(QUdpSocket *socket, const QByteArray &dgram)
{
    Q_D(QDtls);

    if (d->handshakeState == HandshakeNotStarted)
        return startHandshake(socket, dgram);
    else if (d->handshakeState == HandshakeInProgress)
        return continueHandshake(socket, dgram);

    d->setDtlsError(QDtlsError::InvalidOperation,
                    tr("Cannot start/continue handshake, invalid handshake state"));
    return false;
}

/*!
    \internal
*/
bool QDtls::startHandshake(QUdpSocket *socket, const QByteArray &datagram)
{
    Q_D(QDtls);

    if (!socket) {
        d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
        return false;
    }

    if (d->remoteAddress.isNull()) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("To start a handshake you must set peer's address and port first"));
        return false;
    }

    if (sslMode() == QSslSocket::SslServerMode && !datagram.size()) {
        d->setDtlsError(QDtlsError::InvalidInputParameters,
                        tr("To start a handshake, DTLS server requires non-empty datagram (client hello)"));
        return false;
    }

    if (d->handshakeState != HandshakeNotStarted) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot start handshake, already done/in progress"));
        return false;
    }

    return d->startHandshake(socket, datagram);
}

/*!
    If a timeout occures during the handshake, the handshakeTimeout() signal
    is emitted. The application must call handleTimeout() to retransmit handshake
    messages; handleTimeout() returns \c true if a timeout has occurred, false
    otherwise. \a socket must be a valid pointer.

    \sa handshakeTimeout()
*/
bool QDtls::handleTimeout(QUdpSocket *socket)
{
    Q_D(QDtls);

    if (!socket) {
        d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
        return false;
    }

    return d->handleTimeout(socket);
}

/*!
    \internal
*/
bool QDtls::continueHandshake(QUdpSocket *socket, const QByteArray &datagram)
{
    Q_D(QDtls);

    if (!socket || !datagram.size()) {
        d->setDtlsError(QDtlsError::InvalidInputParameters,
                        tr("A valid QUdpSocket and non-empty datagram are needed to continue the handshake"));
        return false;
    }

    if (d->handshakeState != HandshakeInProgress) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot continue handshake, not in InProgress state"));
        return false;
    }

    return d->continueHandshake(socket, datagram);
}

/*!
    If peer verification errors were ignored during the handshake,
    resumeHandshake() resumes and completes the handshake and returns
    \c true. \a socket must be a valid pointer. Returns \c false if
    the handshake could not be resumed.

    \sa doHandshake(), abortHandshake() peerVerificationErrors(), ignoreVerificationErrors()
*/
bool QDtls::resumeHandshake(QUdpSocket *socket)
{
    Q_D(QDtls);

    if (!socket) {
        d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
        return false;
    }

    if (d->handshakeState != PeerVerificationFailed) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot resume, not in VerificationError state"));
        return false;
    }

    return d->resumeHandshake(socket);
}

/*!
    Aborts the ongoing handshake. Returns true if one was on-going on \a socket;
    otherwise, sets a suitable error and returns false.

    \sa doHandshake(), resumeHandshake()
 */
bool QDtls::abortHandshake(QUdpSocket *socket)
{
    Q_D(QDtls);

    if (!socket) {
        d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
        return false;
    }

    if (d->handshakeState != PeerVerificationFailed && d->handshakeState != HandshakeInProgress) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("No handshake in progress, nothing to abort"));
        return false;
    }

    d->abortHandshake(socket);
    return true;
}

/*!
    Sends an encrypted shutdown alert message and closes the DTLS connection.
    Handshake state changes to QDtls::HandshakeNotStarted. \a socket must be a
    valid pointer. This function returns \c true on success.

    \sa doHandshake()
 */
bool QDtls::shutdown(QUdpSocket *socket)
{
    Q_D(QDtls);

    if (!socket) {
        d->setDtlsError(QDtlsError::InvalidInputParameters,
                        tr("Invalid (nullptr) socket"));
        return false;
    }

    if (!d->connectionEncrypted) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot send shutdown alert, not encrypted"));
        return false;
    }

    d->sendShutdownAlert(socket);
    return true;
}

/*!
    Returns \c true if DTLS handshake completed successfully.

    \sa doHandshake(), handshakeState()
 */
bool QDtls::isConnectionEncrypted() const
{
    Q_D(const QDtls);

    return d->connectionEncrypted;
}

/*!
    Returns the cryptographic \l {QSslCipher} {cipher} used by this connection,
    or a null cipher if the connection isn't encrypted. The cipher for the
    session is selected during the handshake phase. The cipher is used to encrypt
    and decrypt data.

    QSslConfiguration provides functions for setting the ordered list of ciphers
    from which the handshake phase will eventually select the session cipher.
    This ordered list must be in place before the handshake phase begins.

    \sa QSslConfiguration, setDtlsConfiguration(), dtlsConfiguration()
*/
QSslCipher QDtls::sessionCipher() const
{
    Q_D(const QDtls);

    return d->sessionCipher;
}

/*!
    Returns the DTLS protocol version used by this connection, or UnknownProtocol
    if the connection isn't encrypted yet. The protocol for the connection is selected
    during the handshake phase.

    setDtlsConfiguration() can set the preferred version before the handshake starts.

    \sa setDtlsConfiguration(), QSslConfiguration, QSslConfiguration::defaultDtlsConfiguration(),
    QSslConfiguration::setProtocol()
*/
QSsl::SslProtocol QDtls::sessionProtocol() const
{
    Q_D(const QDtls);

    return d->sessionProtocol;
}

/*!
    Encrypts \a dgram and writes the encrypted data into \a socket. Returns the
    number of bytes written, or -1 in case of error. The handshake must be completed
    before writing encrypted data. \a socket must be a valid
    pointer.

    \sa doHandshake(), handshakeState(), isConnectionEncrypted(), dtlsError()
*/
qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)
{
    Q_D(QDtls);

    if (!socket) {
        d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
        return -1;
    }

    if (!isConnectionEncrypted()) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot write a datagram, not in encrypted state"));
        return -1;
    }

    return d->writeDatagramEncrypted(socket, dgram);
}

/*!
    Decrypts \a dgram and returns its contents as plain text. The handshake must
    be completed before datagrams can be decrypted. Depending on the type of the
    TLS message the connection may write into \a socket, which must be a valid
    pointer.
*/
QByteArray QDtls::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
{
    Q_D(QDtls);

    if (!socket) {
        d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
        return {};
    }

    if (!isConnectionEncrypted()) {
        d->setDtlsError(QDtlsError::InvalidOperation,
                        tr("Cannot read a datagram, not in encrypted state"));
        return {};
    }

    if (!dgram.size())
        return {};

    return d->decryptDatagram(socket, dgram);
}

/*!
    Returns the last error encountered by the connection or QDtlsError::NoError.

    \sa dtlsErrorString(), QDtlsError
*/
QDtlsError QDtls::dtlsError() const
{
    Q_D(const QDtls);

    return d->errorCode;
}

/*!
    Returns a textual description for the last error encountered by the connection
    or empty string.

    \sa dtlsError()
*/
QString QDtls::dtlsErrorString() const
{
    Q_D(const QDtls);

    return d->errorDescription;
}

/*!
    Returns errors found while establishing the identity of the peer.

    If you want to continue connecting despite the errors that have occurred,
    you must call ignoreVerificationErrors().
*/
QVector<QSslError> QDtls::peerVerificationErrors() const
{
    Q_D(const QDtls);

    return d->tlsErrors;
}

/*!
    This method tells QDtls to ignore only the errors given in \a errorsToIgnore.

    If, for instance, you want to connect to a server that uses a self-signed
    certificate, consider the following snippet:

    \snippet code/src_network_ssl_qdtls.cpp 6

    You can also call this function after doHandshake() encountered the
    QDtlsError::PeerVerificationError error, and then resume the handshake by
    calling resumeHandshake().

    Later calls to this function will replace the list of errors that were
    passed in previous calls. You can clear the list of errors you want to ignore
    by calling this function with an empty list.

    \sa doHandshake(), resumeHandshake(), QSslError
*/
void QDtls::ignoreVerificationErrors(const QVector<QSslError> &errorsToIgnore)
{
    Q_D(QDtls);

    d->tlsErrorsToIgnore = errorsToIgnore;
}

QT_END_NAMESPACE
