/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Copyright (C) 2014 Governikus GmbH & Co. KG.
** 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 <QtNetwork/qsslsocket.h>

#include "private/qssl_p.h"
#include "private/qsslcontext_openssl_p.h"
#include "private/qsslsocket_openssl_p.h"
#include "private/qsslsocket_openssl_symbols_p.h"

QT_BEGIN_NAMESPACE

static inline QString msgErrorSettingBackendConfig(const QString &why)
{
    return QSslSocket::tr("Error when setting the OpenSSL configuration (%1)").arg(why);
}

QSslContext::QSslContext()
    : ctx(nullptr),
    pkey(nullptr),
    session(nullptr),
    m_sessionTicketLifeTimeHint(-1)
{
}

QSslContext::~QSslContext()
{
    if (ctx)
        // This will decrement the reference count by 1 and free the context eventually when possible
        q_SSL_CTX_free(ctx);

    if (pkey)
        q_EVP_PKEY_free(pkey);

    if (session)
        q_SSL_SESSION_free(session);
}

QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
{
    QSslContext *sslContext = new QSslContext();
    initSslContext(sslContext, mode, configuration, allowRootCertOnDemandLoading);
    return sslContext;
}

QSharedPointer<QSslContext> QSslContext::sharedFromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
{
    QSharedPointer<QSslContext> sslContext = QSharedPointer<QSslContext>::create();
    initSslContext(sslContext.data(), mode, configuration, allowRootCertOnDemandLoading);
    return sslContext;
}

#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)

static int next_proto_cb(SSL *, unsigned char **out, unsigned char *outlen,
                         const unsigned char *in, unsigned int inlen, void *arg)
{
    QSslContext::NPNContext *ctx = reinterpret_cast<QSslContext::NPNContext *>(arg);

    // comment out to debug:
//    QList<QByteArray> supportedVersions;
//    for (unsigned int i = 0; i < inlen; ) {
//        QByteArray version(reinterpret_cast<const char *>(&in[i+1]), in[i]);
//        supportedVersions << version;
//        i += in[i] + 1;
//    }

    int proto = q_SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
    switch (proto) {
    case OPENSSL_NPN_UNSUPPORTED:
        ctx->status = QSslConfiguration::NextProtocolNegotiationNone;
        break;
    case OPENSSL_NPN_NEGOTIATED:
        ctx->status = QSslConfiguration::NextProtocolNegotiationNegotiated;
        break;
    case OPENSSL_NPN_NO_OVERLAP:
        ctx->status = QSslConfiguration::NextProtocolNegotiationUnsupported;
        break;
    default:
        qCWarning(lcSsl, "OpenSSL sent unknown NPN status");
    }

    return SSL_TLSEXT_ERR_OK;
}

QSslContext::NPNContext QSslContext::npnContext() const
{
    return m_npnContext;
}
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...

// Needs to be deleted by caller
SSL* QSslContext::createSsl()
{
    SSL* ssl = q_SSL_new(ctx);
    q_SSL_clear(ssl);

    if (!session && !sessionASN1().isEmpty()
            && !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
        const unsigned char *data = reinterpret_cast<const unsigned char *>(m_sessionASN1.constData());
        session = q_d2i_SSL_SESSION(
            nullptr, &data, m_sessionASN1.size()); // refcount is 1 already, set by function above
    }

    if (session) {
        // Try to resume the last session we cached
        if (!q_SSL_set_session(ssl, session)) {
            qCWarning(lcSsl, "could not set SSL session");
            q_SSL_SESSION_free(session);
            session = nullptr;
        }
    }

#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
    QList<QByteArray> protocols = sslConfiguration.d->nextAllowedProtocols;
    if (!protocols.isEmpty()) {
        m_supportedNPNVersions.clear();
        for (int a = 0; a < protocols.count(); ++a) {
            if (protocols.at(a).size() > 255) {
                qCWarning(lcSsl) << "TLS NPN extension" << protocols.at(a)
                                 << "is too long and will be ignored.";
                continue;
            } else if (protocols.at(a).isEmpty()) {
                continue;
            }
            m_supportedNPNVersions.append(protocols.at(a).size()).append(protocols.at(a));
        }
        if (m_supportedNPNVersions.size()) {
            m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data());
            m_npnContext.len = m_supportedNPNVersions.count();
            m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
            if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
                // Callback's type has a parameter 'const unsigned char ** out'
                // since it was introduced in 1.0.2. Internally, OpenSSL's own code
                // (tests/examples) cast it to unsigned char * (since it's 'out').
                // We just re-use our NPN callback and cast here:
                typedef int (*alpn_callback_t) (SSL *, const unsigned char **, unsigned char *,
                                                const unsigned char *, unsigned int, void *);
                // With ALPN callback is for a server side only, for a client m_npnContext.status
                // will stay in NextProtocolNegotiationNone.
                q_SSL_CTX_set_alpn_select_cb(ctx, alpn_callback_t(next_proto_cb), &m_npnContext);
                // Client:
                q_SSL_set_alpn_protos(ssl, m_npnContext.data, m_npnContext.len);
            }
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...

            // And in case our peer does not support ALPN, but supports NPN:
            q_SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &m_npnContext);
        }
    }
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...

    return ssl;
}

// We cache exactly one session here
bool QSslContext::cacheSession(SSL* ssl)
{
    // don't cache the same session again
    if (session && session == q_SSL_get_session(ssl))
        return true;

    // decrease refcount of currently stored session
    // (this might happen if there are several concurrent handshakes in flight)
    if (session)
        q_SSL_SESSION_free(session);

    // cache the session the caller gave us and increase reference count
    session = q_SSL_get1_session(ssl);

    if (session && !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
        int sessionSize = q_i2d_SSL_SESSION(session, nullptr);
        if (sessionSize > 0) {
            m_sessionASN1.resize(sessionSize);
            unsigned char *data = reinterpret_cast<unsigned char *>(m_sessionASN1.data());
            if (!q_i2d_SSL_SESSION(session, &data))
                qCWarning(lcSsl, "could not store persistent version of SSL session");
            m_sessionTicketLifeTimeHint = q_SSL_SESSION_get_ticket_lifetime_hint(session);
        }
    }

    return (session != nullptr);
}

QByteArray QSslContext::sessionASN1() const
{
    return m_sessionASN1;
}

void QSslContext::setSessionASN1(const QByteArray &session)
{
    m_sessionASN1 = session;
}

int QSslContext::sessionTicketLifeTimeHint() const
{
    return m_sessionTicketLifeTimeHint;
}

QSslError::SslError QSslContext::error() const
{
    return errorCode;
}

QString QSslContext::errorString() const
{
    return errorStr;
}

#if QT_CONFIG(ocsp)
extern "C" int qt_OCSP_status_server_callback(SSL *ssl, void *); // Defined in qsslsocket_openssl.cpp.
#endif // ocsp
// static
void QSslContext::applyBackendConfig(QSslContext *sslContext)
{
    const QMap<QByteArray, QVariant> &conf = sslContext->sslConfiguration.backendConfiguration();
    if (conf.isEmpty())
        return;

#if QT_CONFIG(ocsp)
    auto ocspResponsePos = conf.find("Qt-OCSP-response");
    if (ocspResponsePos != conf.end()) {
        // This is our private, undocumented configuration option, existing only for
        // the purpose of testing OCSP status responses. We don't even check this
        // callback was set. If no - the test must fail.
        q_SSL_CTX_set_tlsext_status_cb(sslContext->ctx, qt_OCSP_status_server_callback);
        if (conf.size() == 1)
            return;
    }
#endif // ocsp

#if OPENSSL_VERSION_NUMBER >= 0x10002000L
    if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
        QSharedPointer<SSL_CONF_CTX> cctx(q_SSL_CONF_CTX_new(), &q_SSL_CONF_CTX_free);
        if (cctx) {
            q_SSL_CONF_CTX_set_ssl_ctx(cctx.data(), sslContext->ctx);
            q_SSL_CONF_CTX_set_flags(cctx.data(), SSL_CONF_FLAG_FILE);

            for (auto i = conf.constBegin(); i != conf.constEnd(); ++i) {
                if (i.key() == "Qt-OCSP-response") // This never goes to SSL_CONF_cmd().
                    continue;

                if (!i.value().canConvert(QMetaType::QByteArray)) {
                    sslContext->errorCode = QSslError::UnspecifiedError;
                    sslContext->errorStr = msgErrorSettingBackendConfig(
                        QSslSocket::tr("Expecting QByteArray for %1").arg(
                            QString::fromUtf8(i.key())));
                    return;
                }

                const QByteArray &value = i.value().toByteArray();
                const int result = q_SSL_CONF_cmd(cctx.data(), i.key().constData(), value.constData());
                if (result == 2)
                    continue;

                sslContext->errorCode = QSslError::UnspecifiedError;
                switch (result) {
                case 0:
                    sslContext->errorStr = msgErrorSettingBackendConfig(
                        QSslSocket::tr("An error occurred attempting to set %1 to %2").arg(
                            QString::fromUtf8(i.key()), QString::fromUtf8(value)));
                    return;
                case 1:
                    sslContext->errorStr = msgErrorSettingBackendConfig(
                        QSslSocket::tr("Wrong value for %1 (%2)").arg(
                            QString::fromUtf8(i.key()), QString::fromUtf8(value)));
                    return;
                default:
                    sslContext->errorStr = msgErrorSettingBackendConfig(
                        QSslSocket::tr("Unrecognized command %1 = %2").arg(
                            QString::fromUtf8(i.key()), QString::fromUtf8(value)));
                    return;
                }
            }

            if (q_SSL_CONF_CTX_finish(cctx.data()) == 0) {
                sslContext->errorStr = msgErrorSettingBackendConfig(QSslSocket::tr("SSL_CONF_finish() failed"));
                sslContext->errorCode = QSslError::UnspecifiedError;
            }
       } else {
           sslContext->errorStr = msgErrorSettingBackendConfig(QSslSocket::tr("SSL_CONF_CTX_new() failed"));
           sslContext->errorCode = QSslError::UnspecifiedError;
       }
    } else
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
    {
        // specific algorithms requested, but not possible to set
        sslContext->errorCode = QSslError::UnspecifiedError;
        sslContext->errorStr = msgErrorSettingBackendConfig(
            QSslSocket::tr("OpenSSL version too old, need at least v1.0.2"));
    }
}

QT_END_NAMESPACE
