/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include <QtTest/QtTest>
#include <qsslkey.h>
#include <qsslsocket.h>
#include <QScopeGuard>

#include <QtNetwork/qhostaddress.h>
#include <QtNetwork/qnetworkproxy.h>

#ifdef QT_BUILD_INTERNAL
    #ifndef QT_NO_SSL
        #include "private/qsslkey_p.h"
        #define TEST_CRYPTO
    #endif
    #ifndef QT_NO_OPENSSL
        #include "private/qsslsocket_openssl_symbols_p.h"
    #endif
#endif

class tst_QSslKey : public QObject
{
    Q_OBJECT

    struct KeyInfo {
        QFileInfo fileInfo;
        QSsl::KeyAlgorithm algorithm;
        QSsl::KeyType type;
        int length;
        QSsl::EncodingFormat format;
        KeyInfo(
            const QFileInfo &fileInfo, QSsl::KeyAlgorithm algorithm, QSsl::KeyType type,
            int length, QSsl::EncodingFormat format)
            : fileInfo(fileInfo), algorithm(algorithm), type(type), length(length)
            , format(format) {}
    };

    QList<KeyInfo> keyInfoList;

    void createPlainTestRows(bool pemOnly = false);

public slots:
    void initTestCase();

#ifndef QT_NO_SSL

private slots:
    void emptyConstructor();
    void constructor_data();
    void constructor();
#ifndef QT_NO_OPENSSL
    void constructorHandle_data();
    void constructorHandle();
#endif
    void copyAndAssign_data();
    void copyAndAssign();
    void equalsOperator();
    void length_data();
    void length();
    void toPemOrDer_data();
    void toPemOrDer();
    void toEncryptedPemOrDer_data();
    void toEncryptedPemOrDer();

    void passphraseChecks_data();
    void passphraseChecks();
    void noPassphraseChecks();
#ifdef TEST_CRYPTO
    void encrypt_data();
    void encrypt();
#endif

#endif
private:
    QString testDataDir;
};

void tst_QSslKey::initTestCase()
{
    testDataDir = QFileInfo(QFINDTESTDATA("rsa-without-passphrase.pem")).absolutePath();
    if (testDataDir.isEmpty())
        testDataDir = QCoreApplication::applicationDirPath();
    if (!testDataDir.endsWith(QLatin1String("/")))
        testDataDir += QLatin1String("/");

    QDir dir(testDataDir + "keys");
    const QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable);
    QRegExp rx(QLatin1String("^(rsa|dsa|dh|ec)-(pub|pri)-(\\d+)-?[\\w-]*\\.(pem|der)$"));
    for (const QFileInfo &fileInfo : fileInfoList) {
        if (rx.indexIn(fileInfo.fileName()) >= 0) {
            keyInfoList << KeyInfo(
                fileInfo,
                rx.cap(1) == QLatin1String("rsa") ? QSsl::Rsa :
                rx.cap(1) == QLatin1String("dsa") ? QSsl::Dsa :
                rx.cap(1) == QLatin1String("dh") ? QSsl::Dh : QSsl::Ec,
                rx.cap(2) == QLatin1String("pub") ? QSsl::PublicKey : QSsl::PrivateKey,
                rx.cap(3).toInt(),
                rx.cap(4) == QLatin1String("pem") ? QSsl::Pem : QSsl::Der);
        }
    }
}

#ifndef QT_NO_SSL

static QByteArray readFile(const QString &absFilePath)
{
    QFile file(absFilePath);
    if (!file.open(QIODevice::ReadOnly)) {
        QWARN("failed to open file");
        return QByteArray();
    }
    return file.readAll();
}

void tst_QSslKey::emptyConstructor()
{
    if (!QSslSocket::supportsSsl())
        return;

    QSslKey key;
    QVERIFY(key.isNull());
    QVERIFY(key.length() < 0);

    QSslKey key2;
    QCOMPARE(key, key2);
}

Q_DECLARE_METATYPE(QSsl::KeyAlgorithm)
Q_DECLARE_METATYPE(QSsl::KeyType)
Q_DECLARE_METATYPE(QSsl::EncodingFormat)

void tst_QSslKey::createPlainTestRows(bool pemOnly)
{
    QTest::addColumn<QString>("absFilePath");
    QTest::addColumn<QSsl::KeyAlgorithm>("algorithm");
    QTest::addColumn<QSsl::KeyType>("type");
    QTest::addColumn<int>("length");
    QTest::addColumn<QSsl::EncodingFormat>("format");
    foreach (KeyInfo keyInfo, keyInfoList) {
        if (pemOnly && keyInfo.format != QSsl::EncodingFormat::Pem)
            continue;
#if defined(Q_OS_WINRT) || QT_CONFIG(schannel)
        if (keyInfo.fileInfo.fileName().contains("RC2-64"))
            continue; // WinRT/Schannel treats RC2 as 128 bit
#endif
#if !defined(QT_NO_SSL) && defined(QT_NO_OPENSSL) // generic backend
        if (keyInfo.fileInfo.fileName().contains(QRegularExpression("-aes\\d\\d\\d-")))
            continue; // No AES support in the generic back-end
        if (keyInfo.fileInfo.fileName().contains("pkcs8-pkcs12"))
            continue; // The generic back-end doesn't support PKCS#12 algorithms
#endif

        QTest::newRow(keyInfo.fileInfo.fileName().toLatin1())
            << keyInfo.fileInfo.absoluteFilePath() << keyInfo.algorithm << keyInfo.type
            << keyInfo.length << keyInfo.format;
    }
}

void tst_QSslKey::constructor_data()
{
    createPlainTestRows();
}

void tst_QSslKey::constructor()
{
    if (!QSslSocket::supportsSsl())
        return;

    QFETCH(QString, absFilePath);
    QFETCH(QSsl::KeyAlgorithm, algorithm);
    QFETCH(QSsl::KeyType, type);
    QFETCH(QSsl::EncodingFormat, format);

    QByteArray encoded = readFile(absFilePath);
    QByteArray passphrase;
    if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-"))
        passphrase = QByteArray("1234");
    QSslKey key(encoded, algorithm, format, type, passphrase);
    QVERIFY(!key.isNull());
}

#ifndef QT_NO_OPENSSL

void tst_QSslKey::constructorHandle_data()
{
    createPlainTestRows(true);
}

void tst_QSslKey::constructorHandle()
{
#ifndef QT_BUILD_INTERNAL
    QSKIP("This test requires -developer-build.");
#else
    if (!QSslSocket::supportsSsl())
        return;

    QFETCH(QString, absFilePath);
    QFETCH(QSsl::KeyAlgorithm, algorithm);
    QFETCH(QSsl::KeyType, type);
    QFETCH(int, length);

    QByteArray pem = readFile(absFilePath);
    auto func = (type == QSsl::KeyType::PublicKey
                 ? q_PEM_read_bio_PUBKEY
                 : q_PEM_read_bio_PrivateKey);

    QByteArray passphrase;
    if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-"))
        passphrase = "1234";

    BIO* bio = q_BIO_new(q_BIO_s_mem());
    q_BIO_write(bio, pem.constData(), pem.length());
    EVP_PKEY *origin = func(bio, nullptr, nullptr, static_cast<void *>(passphrase.data()));
#if QT_CONFIG(opensslv11)
    q_EVP_PKEY_up_ref(origin);
#endif
    QSslKey key(origin, type);
#if !QT_CONFIG(opensslv11)
    q_BIO_write(bio, pem.constData(), pem.length());
    origin = func(bio, nullptr, nullptr, static_cast<void *>(passphrase.data()));
#endif
    q_BIO_free(bio);

    EVP_PKEY *handle = q_EVP_PKEY_new();
    switch (algorithm) {
    case QSsl::Rsa:
        q_EVP_PKEY_set1_RSA(handle, static_cast<RSA *>(key.handle()));
        break;
    case QSsl::Dsa:
        q_EVP_PKEY_set1_DSA(handle, static_cast<DSA *>(key.handle()));
        break;
    case QSsl::Dh:
        q_EVP_PKEY_set1_DH(handle, static_cast<DH *>(key.handle()));
        break;
#ifndef OPENSSL_NO_EC
    case QSsl::Ec:
        q_EVP_PKEY_set1_EC_KEY(handle, static_cast<EC_KEY *>(key.handle()));
        break;
#endif
    default:
        break;
    }

    auto cleanup = qScopeGuard([origin, handle] {
        q_EVP_PKEY_free(origin);
        q_EVP_PKEY_free(handle);
    });

    QVERIFY(!key.isNull());
    QCOMPARE(key.algorithm(), algorithm);
    QCOMPARE(key.type(), type);
    QCOMPARE(key.length(), length);
    QCOMPARE(q_EVP_PKEY_cmp(origin, handle), 1);
#endif
}

#endif

void tst_QSslKey::copyAndAssign_data()
{
    createPlainTestRows();
}

void tst_QSslKey::copyAndAssign()
{
    if (!QSslSocket::supportsSsl())
        return;

    QFETCH(QString, absFilePath);
    QFETCH(QSsl::KeyAlgorithm, algorithm);
    QFETCH(QSsl::KeyType, type);
    QFETCH(QSsl::EncodingFormat, format);

    QByteArray encoded = readFile(absFilePath);
    QByteArray passphrase;
    if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-"))
        passphrase = QByteArray("1234");
    QSslKey key(encoded, algorithm, format, type, passphrase);

    QSslKey copied(key);
    QCOMPARE(key, copied);
    QCOMPARE(key.algorithm(), copied.algorithm());
    QCOMPARE(key.type(), copied.type());
    QCOMPARE(key.length(), copied.length());
    QCOMPARE(key.toPem(), copied.toPem());
    QCOMPARE(key.toDer(), copied.toDer());

    QSslKey assigned = key;
    QCOMPARE(key, assigned);
    QCOMPARE(key.algorithm(), assigned.algorithm());
    QCOMPARE(key.type(), assigned.type());
    QCOMPARE(key.length(), assigned.length());
    QCOMPARE(key.toPem(), assigned.toPem());
    QCOMPARE(key.toDer(), assigned.toDer());
}

void tst_QSslKey::equalsOperator()
{
    // ### unimplemented
}

void tst_QSslKey::length_data()
{
    createPlainTestRows();
}

void tst_QSslKey::length()
{
    if (!QSslSocket::supportsSsl())
        return;

    QFETCH(QString, absFilePath);
    QFETCH(QSsl::KeyAlgorithm, algorithm);
    QFETCH(QSsl::KeyType, type);
    QFETCH(int, length);
    QFETCH(QSsl::EncodingFormat, format);

    QByteArray encoded = readFile(absFilePath);
    QByteArray passphrase;
    if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-"))
        passphrase = QByteArray("1234");
    QSslKey key(encoded, algorithm, format, type, passphrase);
    QVERIFY(!key.isNull());
    QCOMPARE(key.length(), length);
}

void tst_QSslKey::toPemOrDer_data()
{
    createPlainTestRows();
}

void tst_QSslKey::toPemOrDer()
{
    if (!QSslSocket::supportsSsl())
        return;

    QFETCH(QString, absFilePath);
    QFETCH(QSsl::KeyAlgorithm, algorithm);
    QFETCH(QSsl::KeyType, type);
    QFETCH(QSsl::EncodingFormat, format);

    QByteArray dataTag = QByteArray(QTest::currentDataTag());
    if (dataTag.contains("-pkcs8-")) // these are encrypted
        QSKIP("Encrypted PKCS#8 keys gets decrypted when loaded. So we can't compare it to the encrypted version.");
#ifndef QT_NO_OPENSSL
    if (dataTag.contains("pkcs8"))
        QSKIP("OpenSSL converts PKCS#8 keys to other formats, invalidating comparisons.");
#else // !openssl
    if (dataTag.contains("pkcs8") && dataTag.contains("rsa"))
        QSKIP("PKCS#8 RSA keys are changed into a different format in the generic back-end, meaning the comparison fails.");
#endif // openssl

    QByteArray encoded = readFile(absFilePath);
    QSslKey key(encoded, algorithm, format, type);
    QVERIFY(!key.isNull());
    if (format == QSsl::Pem)
        encoded.replace('\r', "");
    QCOMPARE(format == QSsl::Pem ? key.toPem() : key.toDer(), encoded);
}

void tst_QSslKey::toEncryptedPemOrDer_data()
{
    QTest::addColumn<QString>("absFilePath");
    QTest::addColumn<QSsl::KeyAlgorithm>("algorithm");
    QTest::addColumn<QSsl::KeyType>("type");
    QTest::addColumn<QSsl::EncodingFormat>("format");
    QTest::addColumn<QString>("password");

    QStringList passwords;
    passwords << " " << "foobar" << "foo bar"
              << "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?"; // ### add more (?)
    foreach (KeyInfo keyInfo, keyInfoList) {
        if (keyInfo.fileInfo.fileName().contains("pkcs8"))
            continue; // pkcs8 keys are encrypted in a different way than the other keys
        foreach (QString password, passwords) {
            const QByteArray testName = keyInfo.fileInfo.fileName().toLatin1()
            + '-' + (keyInfo.algorithm == QSsl::Rsa ? "RSA" :
                                                      (keyInfo.algorithm == QSsl::Dsa ? "DSA" : "EC"))
            + '-' + (keyInfo.type == QSsl::PrivateKey ? "PrivateKey" : "PublicKey")
            + '-' + (keyInfo.format == QSsl::Pem ? "PEM" : "DER")
            + password.toLatin1();
            QTest::newRow(testName.constData())
                << keyInfo.fileInfo.absoluteFilePath() << keyInfo.algorithm << keyInfo.type
                << keyInfo.format << password;
        }
    }
}

void tst_QSslKey::toEncryptedPemOrDer()
{
    if (!QSslSocket::supportsSsl())
        return;

    QFETCH(QString, absFilePath);
    QFETCH(QSsl::KeyAlgorithm, algorithm);
    QFETCH(QSsl::KeyType, type);
    QFETCH(QSsl::EncodingFormat, format);
    QFETCH(QString, password);

    QByteArray plain = readFile(absFilePath);
    QSslKey key(plain, algorithm, format, type);
    QVERIFY(!key.isNull());

    QByteArray pwBytes(password.toLatin1());

    if (type == QSsl::PrivateKey) {
        QByteArray encryptedPem = key.toPem(pwBytes);
        QVERIFY(!encryptedPem.isEmpty());
        QSslKey keyPem(encryptedPem, algorithm, QSsl::Pem, type, pwBytes);
        QVERIFY(!keyPem.isNull());
        QCOMPARE(keyPem, key);
        QCOMPARE(keyPem.toPem(), key.toPem());
    } else {
        // verify that public keys are never encrypted by toPem()
        QByteArray encryptedPem = key.toPem(pwBytes);
        QVERIFY(!encryptedPem.isEmpty());
        QByteArray plainPem = key.toPem();
        QVERIFY(!plainPem.isEmpty());
        QCOMPARE(encryptedPem, plainPem);
    }

    if (type == QSsl::PrivateKey) {
        // verify that private keys are never "encrypted" by toDer() and
        // instead an empty string is returned, see QTBUG-41038.
        QByteArray encryptedDer = key.toDer(pwBytes);
        QVERIFY(encryptedDer.isEmpty());
    } else {
        // verify that public keys are never encrypted by toDer()
        QByteArray encryptedDer = key.toDer(pwBytes);
        QVERIFY(!encryptedDer.isEmpty());
        QByteArray plainDer = key.toDer();
        QVERIFY(!plainDer.isEmpty());
        QCOMPARE(encryptedDer, plainDer);
    }

    // ### add a test to verify that public keys are _decrypted_ correctly (by the ctor)
}

void tst_QSslKey::passphraseChecks_data()
{
    QTest::addColumn<QString>("fileName");
    QTest::addColumn<QByteArray>("passphrase");

    const QByteArray pass("123");
    const QByteArray aesPass("1234");

    QTest::newRow("DES") << QString(testDataDir + "rsa-with-passphrase-des.pem") << pass;
    QTest::newRow("3DES") << QString(testDataDir + "rsa-with-passphrase-3des.pem") << pass;
    QTest::newRow("RC2") << QString(testDataDir + "rsa-with-passphrase-rc2.pem") << pass;
#if (!defined(QT_NO_OPENSSL) && !defined(OPENSSL_NO_AES)) || (defined(QT_NO_OPENSSL) && QT_CONFIG(ssl))
    QTest::newRow("AES128") << QString(testDataDir + "rsa-with-passphrase-aes128.pem") << aesPass;
    QTest::newRow("AES192") << QString(testDataDir + "rsa-with-passphrase-aes192.pem") << aesPass;
    QTest::newRow("AES256") << QString(testDataDir + "rsa-with-passphrase-aes256.pem") << aesPass;
#endif // (OpenSSL && AES) || generic backend
}

void tst_QSslKey::passphraseChecks()
{
    QFETCH(QString, fileName);
    QFETCH(QByteArray, passphrase);

    QFile keyFile(fileName);
    QVERIFY(keyFile.exists());
    {
        if (!keyFile.isOpen())
            keyFile.open(QIODevice::ReadOnly);
        else
            keyFile.reset();
        QSslKey key(&keyFile,QSsl::Rsa,QSsl::Pem, QSsl::PrivateKey);
        QVERIFY(key.isNull()); // null passphrase => should not be able to decode key
    }
    {
        if (!keyFile.isOpen())
            keyFile.open(QIODevice::ReadOnly);
        else
            keyFile.reset();
        QSslKey key(&keyFile,QSsl::Rsa,QSsl::Pem, QSsl::PrivateKey, "");
        QVERIFY(key.isNull()); // empty passphrase => should not be able to decode key
    }
    {
        if (!keyFile.isOpen())
            keyFile.open(QIODevice::ReadOnly);
        else
            keyFile.reset();
        QSslKey key(&keyFile,QSsl::Rsa,QSsl::Pem, QSsl::PrivateKey, "WRONG!");
        QVERIFY(key.isNull()); // wrong passphrase => should not be able to decode key
    }
    {
        if (!keyFile.isOpen())
            keyFile.open(QIODevice::ReadOnly);
        else
            keyFile.reset();
        QSslKey key(&keyFile,QSsl::Rsa,QSsl::Pem, QSsl::PrivateKey, passphrase);
        QVERIFY(!key.isNull()); // correct passphrase
    }
}

void tst_QSslKey::noPassphraseChecks()
{
    // be sure and check a key without passphrase too
    QString fileName(testDataDir + "rsa-without-passphrase.pem");
    QFile keyFile(fileName);
    {
        if (!keyFile.isOpen())
            keyFile.open(QIODevice::ReadOnly);
        else
            keyFile.reset();
        QSslKey key(&keyFile,QSsl::Rsa,QSsl::Pem, QSsl::PrivateKey);
        QVERIFY(!key.isNull()); // null passphrase => should be able to decode key
    }
    {
        if (!keyFile.isOpen())
            keyFile.open(QIODevice::ReadOnly);
        else
            keyFile.reset();
        QSslKey key(&keyFile,QSsl::Rsa,QSsl::Pem, QSsl::PrivateKey, "");
        QVERIFY(!key.isNull()); // empty passphrase => should be able to decode key
    }
    {
        if (!keyFile.isOpen())
            keyFile.open(QIODevice::ReadOnly);
        else
            keyFile.reset();
        QSslKey key(&keyFile,QSsl::Rsa,QSsl::Pem, QSsl::PrivateKey, "xxx");
        QVERIFY(!key.isNull()); // passphrase given but key is not encrypted anyway => should work
    }
}

#ifdef TEST_CRYPTO
Q_DECLARE_METATYPE(QSslKeyPrivate::Cipher)

void tst_QSslKey::encrypt_data()
{
    QTest::addColumn<QSslKeyPrivate::Cipher>("cipher");
    QTest::addColumn<QByteArray>("key");
    QTest::addColumn<QByteArray>("plainText");
    QTest::addColumn<QByteArray>("cipherText");
    QTest::addColumn<QByteArray>("iv");

    QByteArray iv("abcdefgh");
    QTest::newRow("DES-CBC, length 0")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray()
        << QByteArray::fromHex("956585228BAF9B1F")
        << iv;
    QTest::newRow("DES-CBC, length 1")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray(1, 'a')
        << QByteArray::fromHex("E6880AF202BA3C12")
        << iv;
    QTest::newRow("DES-CBC, length 2")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray(2, 'a')
        << QByteArray::fromHex("A82492386EED6026")
        << iv;
    QTest::newRow("DES-CBC, length 3")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray(3, 'a')
        << QByteArray::fromHex("90B76D5B79519CBA")
        << iv;
    QTest::newRow("DES-CBC, length 4")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray(4, 'a')
        << QByteArray::fromHex("63E3DD6FED87052A")
        << iv;
    QTest::newRow("DES-CBC, length 5")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray(5, 'a')
        << QByteArray::fromHex("03ACDB0EACBDFA94")
        << iv;
    QTest::newRow("DES-CBC, length 6")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray(6, 'a')
        << QByteArray::fromHex("7D95024E42A3A88A")
        << iv;
    QTest::newRow("DES-CBC, length 7")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray(7, 'a')
        << QByteArray::fromHex("5003436B8A8E42E9")
        << iv;
    QTest::newRow("DES-CBC, length 8")
        << QSslKeyPrivate::DesCbc << QByteArray("01234567")
        << QByteArray(8, 'a')
        << QByteArray::fromHex("E4C1F054BF5521C0A4A0FD4A2BC6C1B1")
        << iv;

    QTest::newRow("DES-EDE3-CBC, length 0")
        << QSslKeyPrivate::DesEde3Cbc << QByteArray("0123456789abcdefghijklmn")
        << QByteArray()
        << QByteArray::fromHex("3B2B4CD0B0FD495F")
        << iv;
    QTest::newRow("DES-EDE3-CBC, length 8")
        << QSslKeyPrivate::DesEde3Cbc << QByteArray("0123456789abcdefghijklmn")
        << QByteArray(8, 'a')
        << QByteArray::fromHex("F2A5A87763C54A72A3224103D90CDB03")
        << iv;

    QTest::newRow("RC2-40-CBC, length 0")
        << QSslKeyPrivate::Rc2Cbc << QByteArray("01234")
        << QByteArray()
        << QByteArray::fromHex("6D05D52392FF6E7A")
        << iv;
    QTest::newRow("RC2-40-CBC, length 8")
        << QSslKeyPrivate::Rc2Cbc << QByteArray("01234")
        << QByteArray(8, 'a')
        << QByteArray::fromHex("75768E64C5749072A5D168F3AFEB0005")
        << iv;

    QTest::newRow("RC2-64-CBC, length 0")
        << QSslKeyPrivate::Rc2Cbc << QByteArray("01234567")
        << QByteArray()
        << QByteArray::fromHex("ADAE6BF70F420130")
        << iv;
    QTest::newRow("RC2-64-CBC, length 8")
        << QSslKeyPrivate::Rc2Cbc << QByteArray("01234567")
        << QByteArray(8, 'a')
        << QByteArray::fromHex("C7BF5C80AFBE9FBEFBBB9FD935F6D0DF")
        << iv;

    QTest::newRow("RC2-128-CBC, length 0")
        << QSslKeyPrivate::Rc2Cbc << QByteArray("012345679abcdefg")
        << QByteArray()
        << QByteArray::fromHex("1E965D483A13C8FB")
        << iv;
    QTest::newRow("RC2-128-CBC, length 8")
        << QSslKeyPrivate::Rc2Cbc << QByteArray("012345679abcdefg")
        << QByteArray(8, 'a')
        << QByteArray::fromHex("5AEC1A5B295660B02613454232F7DECE")
        << iv;

#if (!defined(QT_NO_OPENSSL) && !defined(OPENSSL_NO_AES)) || (defined(QT_NO_OPENSSL) && QT_CONFIG(ssl))
    // AES needs a longer IV
    iv = QByteArray("abcdefghijklmnop");
    QTest::newRow("AES-128-CBC, length 0")
        << QSslKeyPrivate::Aes128Cbc << QByteArray("012345679abcdefg")
        << QByteArray()
        << QByteArray::fromHex("28DE1A9AA26601C30DD2527407121D1A")
        << iv;
    QTest::newRow("AES-128-CBC, length 8")
        << QSslKeyPrivate::Aes128Cbc << QByteArray("012345679abcdefg")
        << QByteArray(8, 'a')
        << QByteArray::fromHex("08E880B1BA916F061C1E801D7F44D0EC")
        << iv;

    QTest::newRow("AES-192-CBC, length 0")
        << QSslKeyPrivate::Aes192Cbc << QByteArray("0123456789abcdefghijklmn")
        << QByteArray()
        << QByteArray::fromHex("E169E0E205CDC2BA895B7CF6097673B1")
        << iv;
    QTest::newRow("AES-192-CBC, length 8")
        << QSslKeyPrivate::Aes192Cbc << QByteArray("0123456789abcdefghijklmn")
        << QByteArray(8, 'a')
        << QByteArray::fromHex("3A227D6A3A13237316D30AA17FF9B0A7")
        << iv;

    QTest::newRow("AES-256-CBC, length 0")
        << QSslKeyPrivate::Aes256Cbc << QByteArray("0123456789abcdefghijklmnopqrstuv")
        << QByteArray()
        << QByteArray::fromHex("4BAACAA0D22199C97DE206C465B7B14A")
        << iv;
    QTest::newRow("AES-256-CBC, length 8")
        << QSslKeyPrivate::Aes256Cbc << QByteArray("0123456789abcdefghijklmnopqrstuv")
        << QByteArray(8, 'a')
        << QByteArray::fromHex("879C8C25EC135CDF0B14490A0A7C2F67")
        << iv;
#endif // (OpenSSL && AES) || generic backend
}

void tst_QSslKey::encrypt()
{
    QFETCH(QSslKeyPrivate::Cipher, cipher);
    QFETCH(QByteArray, key);
    QFETCH(QByteArray, plainText);
    QFETCH(QByteArray, cipherText);
    QFETCH(QByteArray, iv);

#if defined(Q_OS_WINRT) || QT_CONFIG(schannel)
    QEXPECT_FAIL("RC2-40-CBC, length 0", "WinRT/Schannel treats RC2 as 128-bit", Abort);
    QEXPECT_FAIL("RC2-40-CBC, length 8", "WinRT/Schannel treats RC2 as 128-bit", Abort);
    QEXPECT_FAIL("RC2-64-CBC, length 0", "WinRT/Schannel treats RC2 as 128-bit", Abort);
    QEXPECT_FAIL("RC2-64-CBC, length 8", "WinRT/Schannel treats RC2 as 128-bit", Abort);
#endif
    QByteArray encrypted = QSslKeyPrivate::encrypt(cipher, plainText, key, iv);
    QCOMPARE(encrypted, cipherText);

    QByteArray decrypted = QSslKeyPrivate::decrypt(cipher, cipherText, key, iv);
    QCOMPARE(decrypted, plainText);
}
#endif

#endif

QTEST_MAIN(tst_QSslKey)
#include "tst_qsslkey.moc"
