diff options
Diffstat (limited to 'tests/auto/network/ssl')
16 files changed, 771 insertions, 100 deletions
diff --git a/tests/auto/network/ssl/qasn1element/qasn1element.pro b/tests/auto/network/ssl/qasn1element/qasn1element.pro new file mode 100644 index 0000000000..524c772443 --- /dev/null +++ b/tests/auto/network/ssl/qasn1element/qasn1element.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +CONFIG += parallel_test + +SOURCES += tst_qasn1element.cpp +QT = core network network-private testlib + +TARGET = tst_qasn1element diff --git a/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp b/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp new file mode 100644 index 0000000000..92b603473b --- /dev/null +++ b/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jeremy Lainé <jeremy.laine@m4x.org> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include "private/qasn1element_p.h" + +class tst_QAsn1Element : public QObject +{ + Q_OBJECT + +private slots: + void emptyConstructor(); + void equals_data(); + void equals(); + void toBool_data(); + void toBool(); + void dateTime_data(); + void dateTime(); + void integer_data(); + void integer(); + void invalid_data(); + void invalid(); + void octetString_data(); + void octetString(); + void objectIdentifier_data(); + void objectIdentifier(); +}; + +void tst_QAsn1Element::emptyConstructor() +{ + QAsn1Element elem; + QCOMPARE(elem.type(), quint8(0)); + QCOMPARE(elem.value(), QByteArray()); +} + +Q_DECLARE_METATYPE(QAsn1Element) + +void tst_QAsn1Element::equals_data() +{ + QTest::addColumn<QAsn1Element>("a"); + QTest::addColumn<QAsn1Element>("b"); + QTest::addColumn<bool>("equals"); + + QTest::newRow("equal") + << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1)) + << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1)) + << true; + QTest::newRow("different type") + << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1)) + << QAsn1Element(QAsn1Element::IntegerType, QByteArray("\0", 1)) + << false; + QTest::newRow("different value") + << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1)) + << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\xff", 1)) + << false; +} + +void tst_QAsn1Element::equals() +{ + QFETCH(QAsn1Element, a); + QFETCH(QAsn1Element, b); + QFETCH(bool, equals); + QCOMPARE(a == b, equals); + QCOMPARE(a != b, !equals); +} + +void tst_QAsn1Element::toBool_data() +{ + QTest::addColumn<QByteArray>("encoded"); + QTest::addColumn<bool>("value"); + QTest::addColumn<bool>("valid"); + + QTest::newRow("bad type") << QByteArray::fromHex("0201ff") << false << false; + QTest::newRow("bad value") << QByteArray::fromHex("010102") << false << false; + QTest::newRow("false") << QByteArray::fromHex("010100") << false << true; + QTest::newRow("true") << QByteArray::fromHex("0101ff") << true << true; +} + +void tst_QAsn1Element::toBool() +{ + QFETCH(QByteArray, encoded); + QFETCH(bool, value); + QFETCH(bool, valid); + + bool ok; + QAsn1Element elem; + QVERIFY(elem.read(encoded)); + QCOMPARE(elem.toBool(&ok), value); + QCOMPARE(ok, valid); +} + +void tst_QAsn1Element::dateTime_data() +{ + QTest::addColumn<QByteArray>("encoded"); + QTest::addColumn<QDateTime>("value"); + + QTest::newRow("bad type") + << QByteArray::fromHex("020100") + << QDateTime(); + QTest::newRow("UTCTime - 070417074026Z") + << QByteArray::fromHex("170d3037303431373037343032365a") + << QDateTime(QDate(2007, 4, 17), QTime(7, 40, 26), Qt::UTC); + QTest::newRow("UTCTime - bad length") + << QByteArray::fromHex("170c30373034313730373430325a") + << QDateTime(); + QTest::newRow("UTCTime - no trailing Z") + << QByteArray::fromHex("170d30373034313730373430323659") + << QDateTime(); + QTest::newRow("GeneralizedTime - 20510829095341Z") + << QByteArray::fromHex("180f32303531303832393039353334315a") + << QDateTime(QDate(2051, 8, 29), QTime(9, 53, 41), Qt::UTC); + QTest::newRow("GeneralizedTime - bad length") + << QByteArray::fromHex("180e323035313038323930393533345a") + << QDateTime(); + QTest::newRow("GeneralizedTime - no trailing Z") + << QByteArray::fromHex("180f323035313038323930393533343159") + << QDateTime(); +} + +void tst_QAsn1Element::dateTime() +{ + QFETCH(QByteArray, encoded); + QFETCH(QDateTime, value); + + QAsn1Element elem; + QVERIFY(elem.read(encoded)); + QCOMPARE(elem.toDateTime(), value); +} + +void tst_QAsn1Element::integer_data() +{ + QTest::addColumn<QByteArray>("encoded"); + QTest::addColumn<int>("value"); + + QTest::newRow("0") << QByteArray::fromHex("020100") << 0; + QTest::newRow("127") << QByteArray::fromHex("02017F") << 127; + QTest::newRow("128") << QByteArray::fromHex("02020080") << 128; + QTest::newRow("256") << QByteArray::fromHex("02020100") << 256; +} + +void tst_QAsn1Element::integer() +{ + QFETCH(QByteArray, encoded); + QFETCH(int, value); + + // read + bool ok; + QAsn1Element elem; + QVERIFY(elem.read(encoded)); + QCOMPARE(elem.type(), quint8(QAsn1Element::IntegerType)); + QCOMPARE(elem.toInteger(&ok), value); + QVERIFY(ok); + + // write + QByteArray buffer; + QDataStream stream(&buffer, QIODevice::WriteOnly); + QAsn1Element::fromInteger(value).write(stream); + QCOMPARE(buffer, encoded); +} + +void tst_QAsn1Element::invalid_data() +{ + QTest::addColumn<QByteArray>("encoded"); + + QTest::newRow("empty") << QByteArray(); + QTest::newRow("bad type") << QByteArray::fromHex("000100"); + QTest::newRow("truncated value") << QByteArray::fromHex("0401"); +} + +void tst_QAsn1Element::invalid() +{ + QFETCH(QByteArray, encoded); + + QAsn1Element elem; + QVERIFY(!elem.read(encoded)); +} + +void tst_QAsn1Element::octetString_data() +{ + QTest::addColumn<QByteArray>("encoded"); + QTest::addColumn<QByteArray>("value"); + + QTest::newRow("0 byte") << QByteArray::fromHex("0400") << QByteArray(); + QTest::newRow("1 byte") << QByteArray::fromHex("040100") << QByteArray(1, '\0'); + QTest::newRow("127 bytes") << QByteArray::fromHex("047f") + QByteArray(127, '\0') << QByteArray(127, '\0'); + QTest::newRow("128 bytes") << QByteArray::fromHex("048180") + QByteArray(128, '\0') << QByteArray(128, '\0'); +} + +void tst_QAsn1Element::octetString() +{ + QFETCH(QByteArray, encoded); + QFETCH(QByteArray, value); + + // read + QAsn1Element elem; + QVERIFY(elem.read(encoded)); + QCOMPARE(elem.type(), quint8(QAsn1Element::OctetStringType)); + QCOMPARE(elem.value(), value); + + // write + QByteArray buffer; + QDataStream stream(&buffer, QIODevice::WriteOnly); + elem.write(stream); + QCOMPARE(buffer, encoded); +} + +void tst_QAsn1Element::objectIdentifier_data() +{ + QTest::addColumn<QByteArray>("encoded"); + QTest::addColumn<QByteArray>("oid"); + QTest::addColumn<QByteArray>("name"); + + QTest::newRow("1.2.3.4") + << QByteArray::fromHex("06032a0304") + << QByteArray("1.2.3.4") + << QByteArray("1.2.3.4"); + QTest::newRow("favouriteDrink") + << QByteArray::fromHex("060a0992268993f22c640105") + << QByteArray("0.9.2342.19200300.100.1.5") + << QByteArray("favouriteDrink"); +} + +void tst_QAsn1Element::objectIdentifier() +{ + QFETCH(QByteArray, encoded); + QFETCH(QByteArray, oid); + QFETCH(QByteArray, name); + + QAsn1Element elem; + QVERIFY(elem.read(encoded)); + QCOMPARE(elem.type(), quint8(QAsn1Element::ObjectIdentifierType)); + QCOMPARE(elem.toObjectId(), oid); + QCOMPARE(QAsn1Element::fromObjectId(oid).toObjectId(), oid); + QCOMPARE(elem.toObjectName(), name); +} + +QTEST_MAIN(tst_QAsn1Element) +#include "tst_qasn1element.moc" diff --git a/tests/auto/network/ssl/qsslcertificate/pkcs12/README b/tests/auto/network/ssl/qsslcertificate/pkcs12/README new file mode 100644 index 0000000000..1828d089c1 --- /dev/null +++ b/tests/auto/network/ssl/qsslcertificate/pkcs12/README @@ -0,0 +1,8 @@ +The PKCS#12 bundle was created by running the following on +in the qsslsocket/certs directory: + +openssl pkcs12 -export -in leaf.crt -inkey leaf.key \ + -out leaf.p12 \ + -certfile inter.crt -CAfile ca.crt + +No password was provided. diff --git a/tests/auto/network/ssl/qsslcertificate/pkcs12/inter.crt b/tests/auto/network/ssl/qsslcertificate/pkcs12/inter.crt new file mode 100644 index 0000000000..4e1d67c3e0 --- /dev/null +++ b/tests/auto/network/ssl/qsslcertificate/pkcs12/inter.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDvDCCAnSgAwIBAgIQO+uZxerYC10Ll11PBnVL4TANBgkqhkiG9w0BAQUFADA8 +MQswCQYDVQQGEwJHQjEZMBcGA1UEChMQV2VzdHBvaW50IENBIEtleTESMBAGA1UE +ChMJV2VzdHBvaW50MB4XDTEzMDIxNjE2NTMwOFoXDTIzMDIxNjE2NTMwOFowMjEL +MAkGA1UEBhMCR0IxIzAhBgNVBAoTGldlc3Rwb2ludCBJbnRlcm1lZGlhdGUgS2V5 +MIIBUjANBgkqhkiG9w0BAQEFAAOCAT8AMIIBOgKCATEAsR4tRskg2IFfQFMfGBJ1 +eqlrNejANw0oM6k5HlEB8uFA9qeyAzmflwQUPoJ55KRQ/gVHTOBdWrtgGgPMiekF +1Q36Ry1elwbAl4a+LZ6qsc9ASipvk8HirKpt1v5L9hG+aI4yDxyvjNztFtg5R4P5 +zqsh/WwhCgsYmEVfcSDbhUjqoqxGRLaZxPKO+IMCNFrjZqi0yxc8f6Un4G5SQzHA +4szi/ezcITnAFYWxHG2yaed4hawpxNS1WXabk2rzCi0pWeIcHuIczaCfZ7ElRcqV +VNNXbGTtUDlfIsh6FAVI5kTUDcPV27uf6BmHuFOu/R9Tjni25+vBFvohwQh7ZwCX +5COXnfkJLPkJQQEFVQv8nS27ht/vmyoKjERUeiuMd+hFcN5zl7bS5A2JCgi7erlP +ZQIDAQABo2QwYjAPBgNVHRMBAf8EBTADAQH/MA8GA1UdDwEB/wQFAwMHBgAwHQYD +VR0OBBYEFGn5shQ0SeTcc3x/cNu6TkoV0bPmMB8GA1UdIwQYMBaAFJQnOLW5hBTG +pvc2vfcs4sJpRRPJMA0GCSqGSIb3DQEBBQUAA4IBMQAVDS0enQQ1FL0d92xOFfwx +mjcNPz9oO7jMyEVxAs2eR2QD+xZ3Xj4gAiUEp40aGieDcLv+dg+cmuBFWF61IYSR +UyuoakVm08VDcLAwUzU+xtSvJiSSROb0GsAnVsYZj4TYlvKDplqfapOYaiIkwF+c +iE4n7G0hQW9fzqO+n3FGtBD8YUjghRqLggeRVJ2+8S3Bm8cfx8xPpRIO3ksA6opn +CORRGuzetDHihbks59mkoY3GqKFgBOyrC3kG07nv5wtKjdKDtmD/kS/SAc4fIXKy +Uruq2uXNf/1BUgF5gFGRyj22yB2D0763fJJpl5nqcLrL5RmnVObQKZGhE2VsRTV0 +untj+AmiJivhiAjjkHfw3XDf8tuL7D4pTmEkGgl5xl23fyeTIuygDCLT8fRD3ZqQ +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.crt b/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.crt new file mode 100644 index 0000000000..4a7dc40540 --- /dev/null +++ b/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID3zCCApegAwIBAgIQEKCtd1j2bq5Gk6ND+VmKnjANBgkqhkiG9w0BAQUFADAy +MQswCQYDVQQGEwJHQjEjMCEGA1UEChMaV2VzdHBvaW50IEludGVybWVkaWF0ZSBL +ZXkwHhcNMTMwMjE2MTY1MzA4WhcNMjMwMjE2MTY1MzA4WjA1MQswCQYDVQQGEwJH +QjESMBAGA1UEChMJV2VzdHBvaW50MRIwEAYDVQQDEwkxMjcuMC4wLjEwggFSMA0G +CSqGSIb3DQEBAQUAA4IBPwAwggE6AoIBMQC7EIWIzb7XCfmQQ1KFdZ5E9f49eNK/ +KvsXYfq/iV29K1cz2hUyvfdKgyU5F/+BOPQKQ5zdWn1CraZosFv/ibuO3mhRpMfB +SfNn3rfdrE7WtA0wgT2YNIN0L4aCe+C15j2ESdmyMaFLUaUIS47JS66UtaYxp5ia +mJFO1hSNaoI0pGHyPFTTtfOza9z/01qkBbHB4htzauqs/fX5ZrnyCDSrfpVipXke +zkPKg4MkkytEkjRKw6tSXLpWIgF3ee2N/jBdefqlw8YPW08K0wmwF5qGuX6PZ8vB +sOZeWeCfVr136BopkbfP3TkGWw2BrD8xSzOUez9HVc0v4SZ/7pe5w3L4V/mzYQLt +O+1AHevCjX8+M58HYGBaWCAjxYUPGcGKcj0LLtgZgL6wY88N7RtfeOY3AgMBAAGj +gY0wgYowFAYDVR0RBA0wC4IJMTI3LjAuMC4xMAwGA1UdEwEB/wQCMAAwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDwYDVR0PAQH/BAUDAwcoADAdBgNVHQ4EFgQUKKuyJSrT +Y+dnm1do7l0sVMX96SYwHwYDVR0jBBgwFoAUafmyFDRJ5NxzfH9w27pOShXRs+Yw +DQYJKoZIhvcNAQEFBQADggExAHELijlIFdcncP3B+vxEp0SGKl0arIaCXahivb2F +VxeM3WajN6O+oDRLFltzMeDKA9RVkao7fgITzXQgCGzeNhKv0vc9iDyvR9/67vuS +W8xEEJrYowtw3VK5H1y0ewqZaxJhvKUjm4TBRWe8FGKD3s64lEsfbjOaI5VPidVc +DXmdAlXsj0Hk+v4Ej8mshPQAnVSyJ3D0ZMgTjk8Di28N0qROFIYJaTObK1rCb1nQ +GaCcmbZU6JnkYvVZ+iUe5U0GXFbb+LRNTUT8/fw1zADeHnv/G+WWVrfND+sov5Oc +33fkNE6z+n6ayABVnGLuCYhbzD38sv0dnxeh8vbykNBPzYdzPg6nw3Czv2vlhKpJ +8Yj/maoXuAyTXVf30K1/fAWyU45noq57MjQpU6UxIX1D7qw= +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.key b/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.key new file mode 100644 index 0000000000..54327925d8 --- /dev/null +++ b/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.key @@ -0,0 +1,32 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIFfAIBAAKCATEAuxCFiM2+1wn5kENShXWeRPX+PXjSvyr7F2H6v4ldvStXM9oV +Mr33SoMlORf/gTj0CkOc3Vp9Qq2maLBb/4m7jt5oUaTHwUnzZ9633axO1rQNMIE9 +mDSDdC+GgnvgteY9hEnZsjGhS1GlCEuOyUuulLWmMaeYmpiRTtYUjWqCNKRh8jxU +07Xzs2vc/9NapAWxweIbc2rqrP31+Wa58gg0q36VYqV5Hs5DyoODJJMrRJI0SsOr +Uly6ViIBd3ntjf4wXXn6pcPGD1tPCtMJsBeahrl+j2fLwbDmXlngn1a9d+gaKZG3 +z905BlsNgaw/MUszlHs/R1XNL+Emf+6XucNy+Ff5s2EC7TvtQB3rwo1/PjOfB2Bg +WlggI8WFDxnBinI9Cy7YGYC+sGPPDe0bX3jmNwIDAQABAoIBMQCczBNyAStGqjjC +oHuKHHWmTh9mPWFBFfDTv6/jXmvxRWPZtaHxH2Qp09Wejqv/D9MWy2ev7spx2oZS +2Ai1ICjTbz83uAwryyW4Wen6aBTJSLCJiLstWk8ZU0DHHLjVH4FO4mwUPh95t5zC +YDr2JXbXdY8xrc5vPxUFZNJjWvR61ZK37bQYpTn5mZ7r3KfsNk2yOylRTDwa9XFo +ZZ+B82NKdrrz0UvGOnXZa5qd1ap7V+67FIAS2Mt8AMzSCG8TW0JXRUk89ISgAd8r +NQTPtX9XCnMZSbBzDKdznXfHS9ZlJcSrpsbQCPcvMVNrdBfCF0eNnsRJffJGdaXI +MsN6PvbcXWD08lXNGyeLjon03RdJnTAamNM3YQEIcjFmu5Y0o0CCJkZSCJPKJGMG +0d/1tN/5AoGZANOcOgQZ9Wiu0ej3YoQ3aSHu3y8ZBJH4B3ViX8i+2x/6UnG7KNaa +4Ygid1upnX6hk4CW5WZcoxGFacrFRpInKh5Ng8lEIHGp0VSzOBVDR0L5sAxutFuX +6N9C0CuH80vD101mOloNnfT5KHZMI5RXqP6sDGUFlwak2XybDL1qOAza3gZAy25H +vS/ll1BneBavikR5j+zxoTztAoGZAOJOJ5RyOrqpNuhiWZylah5LIFT9N1lCF4Hl +ZbFIjUZ4jcApJ7JxkMXNQ4RU/3AiKCC1xr5ib7dd/qyjKXhdMo4SnLoKhapx5R9G +3XOsQMahiCD/Zcymv9tmk8MxxzbLxhZYhEPzIP/NFkua3CHiX+d1e6fkzFLF/EiX +ZGQOgRcFKrlzUeBputRQRXAkKJH+kMClgAWvy28zAoGYKyaMXhG9DV+4xjzMBhIW +iijfsgbz+6AMRU+OIK1qmZa+ARsdNMXYf54noLVxvETOg0ZB+SGizwvZitO3lE4Q +NKWx3fTaeNMcMJ1rLkrN2UZ5M8/PT24muoAxWu8aGbURzmKuO3bTYwT7z0OvbayC +dYw36tG8/knXX6Vub6GdVGG9LKFB2nceiQnUVT0EK/wXwebYBoUvT/ECgZgF9qdG +Wyg/CPyAbS8NWLKOL86fTrjpqjsyWhgu7smCROT/XlZEdoepHrqbvx2oF85U5lVh +aPimrVxrsjUCjfoqEkV9BY/2KOAvzc9CIBTo5xLOQ8yr8uz1XCOiriogwIfsyNJb +dAm3k/D1dxQ79FowoEDs8LONrtfyFcM4e8VdFO7GSkqrDj41IBRkWx+SkVHBMdtI +yxQiTwKBmQCWym2iDCJg1ZZq4/lVwRudMhVmHoD0yoCAwADYHjjAi8QBplM0vfdd +CESKsnBhlcrPGB279BKVJyZHehKZG+/dfnFs+to14l6A3IqU2d6+pu3EyFNX34HS +xo+64QxMeF0akWnSaIPfUJfk36phjCvLBr4eLXN1i4jW3RdGFwF1THXt29VSSGmU +q/hM51H0bsQ13AIVUSdNHA== +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.p12 b/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.p12 Binary files differnew file mode 100644 index 0000000000..cb89aadb73 --- /dev/null +++ b/tests/auto/network/ssl/qsslcertificate/pkcs12/leaf.p12 diff --git a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro index 09cb22defe..69cd241f84 100644 --- a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro +++ b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro @@ -6,5 +6,6 @@ SOURCES += tst_qsslcertificate.cpp QT = core network testlib TARGET = tst_qsslcertificate +DEFINES += SRCDIR=\\\"$$PWD/\\\" -TESTDATA += certificates/* more-certificates/* verify-certs/* +TESTDATA += certificates/* more-certificates/* verify-certs/* pkcs12/* diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp index 4f62076870..229ce4abb5 100644 --- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp @@ -105,14 +105,17 @@ private slots: void largeSerialNumber(); void largeExpirationDate(); void blacklistedCertificates(); + void selfsignedCertificates(); void toText(); void multipleCommonNames(); void subjectAndIssuerAttributes(); void verify(); void extensions(); + void extensionsCritical(); void threadSafeConstMethods(); void version_data(); void version(); + void pkcs12(); // helper for verbose test failure messages QString toString(const QList<QSslError>&); @@ -890,6 +893,13 @@ void tst_QSslCertificate::blacklistedCertificates() } } +void tst_QSslCertificate::selfsignedCertificates() +{ + QVERIFY(QSslCertificate::fromPath(testDataDir + "/certificates/cert-ss.pem").first().isSelfSigned()); + QVERIFY(!QSslCertificate::fromPath(testDataDir + "/certificates/cert.pem").first().isSelfSigned()); + QVERIFY(!QSslCertificate().isSelfSigned()); +} + void tst_QSslCertificate::toText() { QList<QSslCertificate> certList = @@ -918,6 +928,9 @@ void tst_QSslCertificate::toText() QString txtcert = cert.toText(); +#ifdef QT_NO_OPENSSL + QEXPECT_FAIL("", "QTBUG-40884: QSslCertificate::toText is not implemented on WinRT", Continue); +#endif QVERIFY(QString::fromLatin1(txt098) == txtcert || QString::fromLatin1(txt100) == txtcert || QString::fromLatin1(txt101) == txtcert || @@ -963,6 +976,9 @@ void tst_QSslCertificate::verify() qPrintable(QString("errors: %1").arg(toString(errors))) \ ) +#ifdef QT_NO_OPENSSL + QEXPECT_FAIL("", "QTBUG-40884: WinRT API does not yet support verifying a chain", Abort); +#endif // Empty chain is unspecified error errors = QSslCertificate::verify(toVerify); VERIFY_VERBOSE(errors.count() == 1); @@ -1078,6 +1094,8 @@ void tst_QSslCertificate::extensions() QSslCertificateExtension unknown = extensions[unknown_idx]; QVERIFY(unknown.oid() == QStringLiteral("1.3.6.1.5.5.7.1.12")); QVERIFY(unknown.name() == QStringLiteral("1.3.6.1.5.5.7.1.12")); + QVERIFY(!unknown.isCritical()); + QVERIFY(!unknown.isSupported()); QByteArray unknownValue = QByteArray::fromHex( "3060A15EA05C305A305830561609696D6167652F6769663021301F300706052B0E03021A0414" \ @@ -1089,8 +1107,11 @@ void tst_QSslCertificate::extensions() QSslCertificateExtension aia = extensions[authority_info_idx]; QVERIFY(aia.oid() == QStringLiteral("1.3.6.1.5.5.7.1.1")); QVERIFY(aia.name() == QStringLiteral("authorityInfoAccess")); + QVERIFY(!aia.isCritical()); + QVERIFY(aia.isSupported()); QVariantMap aiaValue = aia.value().toMap(); + QCOMPARE(aiaValue.keys(), QList<QString>() << QStringLiteral("OCSP") << QStringLiteral("caIssuers")); QString ocsp = aiaValue[QStringLiteral("OCSP")].toString(); QString caIssuers = aiaValue[QStringLiteral("caIssuers")].toString(); @@ -1101,25 +1122,76 @@ void tst_QSslCertificate::extensions() QSslCertificateExtension basic = extensions[basic_constraints_idx]; QVERIFY(basic.oid() == QStringLiteral("2.5.29.19")); QVERIFY(basic.name() == QStringLiteral("basicConstraints")); + QVERIFY(!basic.isCritical()); + QVERIFY(basic.isSupported()); QVariantMap basicValue = basic.value().toMap(); + QCOMPARE(basicValue.keys(), QList<QString>() << QStringLiteral("ca")); QVERIFY(basicValue[QStringLiteral("ca")].toBool() == false); // Subject key identifier QSslCertificateExtension subjectKey = extensions[subject_key_idx]; QVERIFY(subjectKey.oid() == QStringLiteral("2.5.29.14")); QVERIFY(subjectKey.name() == QStringLiteral("subjectKeyIdentifier")); + QVERIFY(!subjectKey.isCritical()); + QVERIFY(subjectKey.isSupported()); QVERIFY(subjectKey.value().toString() == QStringLiteral("5F:90:23:CD:24:CA:52:C9:36:29:F0:7E:9D:B1:FE:08:E0:EE:69:F0")); // Authority key identifier QSslCertificateExtension authKey = extensions[auth_key_idx]; QVERIFY(authKey.oid() == QStringLiteral("2.5.29.35")); QVERIFY(authKey.name() == QStringLiteral("authorityKeyIdentifier")); + QVERIFY(!authKey.isCritical()); + QVERIFY(authKey.isSupported()); QVariantMap authValue = authKey.value().toMap(); + QCOMPARE(authValue.keys(), QList<QString>() << QStringLiteral("keyid")); QVERIFY(authValue[QStringLiteral("keyid")].toByteArray() == QByteArray("4e43c81d76ef37537a4ff2586f94f338e2d5bddf")); +} +void tst_QSslCertificate::extensionsCritical() +{ + QList<QSslCertificate> certList = + QSslCertificate::fromPath(testDataDir + "/verify-certs/test-addons-mozilla-org-cert.pem"); + QVERIFY2(certList.count() > 0, "Please run this test from the source directory"); + + QSslCertificate cert = certList[0]; + QList<QSslCertificateExtension> extensions = cert.extensions(); + QVERIFY(extensions.count() == 9); + + int basic_constraints_idx = -1; + int key_usage_idx = -1; + + for (int i=0; i < extensions.length(); ++i) { + QSslCertificateExtension ext = extensions[i]; + + if (ext.name() == QStringLiteral("basicConstraints")) + basic_constraints_idx = i; + if (ext.name() == QStringLiteral("keyUsage")) + key_usage_idx = i; + } + + QVERIFY(basic_constraints_idx != -1); + QVERIFY(key_usage_idx != -1); + + // Basic constraints + QSslCertificateExtension basic = extensions[basic_constraints_idx]; + QVERIFY(basic.oid() == QStringLiteral("2.5.29.19")); + QVERIFY(basic.name() == QStringLiteral("basicConstraints")); + QVERIFY(basic.isCritical()); + QVERIFY(basic.isSupported()); + + QVariantMap basicValue = basic.value().toMap(); + QCOMPARE(basicValue.keys(), QList<QString>() << QStringLiteral("ca")); + QVERIFY(basicValue[QStringLiteral("ca")].toBool() == false); + + // Key Usage + QSslCertificateExtension keyUsage = extensions[key_usage_idx]; + QVERIFY(keyUsage.oid() == QStringLiteral("2.5.29.15")); + QVERIFY(keyUsage.name() == QStringLiteral("keyUsage")); + QVERIFY(keyUsage.isCritical()); + QVERIFY(!keyUsage.isSupported()); } class TestThread : public QThread @@ -1221,6 +1293,51 @@ void tst_QSslCertificate::version() QCOMPARE(certificate.version(), result); } +void tst_QSslCertificate::pkcs12() +{ + if (!QSslSocket::supportsSsl()) { + qWarning("SSL not supported, skipping test"); + return; + } + + QFile f(QLatin1String(SRCDIR "pkcs12/leaf.p12")); + bool ok = f.open(QIODevice::ReadOnly); + QVERIFY(ok); + + QSslKey key; + QSslCertificate cert; + QList<QSslCertificate> caCerts; + +#ifdef QT_NO_OPENSSL + QEXPECT_FAIL("", "QTBUG-40884: WinRT API does not support pkcs12 imports", Abort); +#endif + ok = QSslCertificate::importPKCS12(&f, &key, &cert, &caCerts); + QVERIFY(ok); + f.close(); + + QList<QSslCertificate> leafCert = QSslCertificate::fromPath(QLatin1String( SRCDIR "pkcs12/leaf.crt")); + QVERIFY(!leafCert.isEmpty()); + + QCOMPARE(cert, leafCert.first()); + + QFile f2(QLatin1String(SRCDIR "pkcs12/leaf.key")); + ok = f2.open(QIODevice::ReadOnly); + QVERIFY(ok); + + QSslKey leafKey(&f2, QSsl::Rsa); + f2.close(); + + QVERIFY(!leafKey.isNull()); + QCOMPARE(key, leafKey); + + QList<QSslCertificate> caCert = QSslCertificate::fromPath(QLatin1String(SRCDIR "pkcs12/inter.crt")); + QVERIFY(!caCert.isEmpty()); + + QVERIFY(!caCerts.isEmpty()); + QCOMPARE(caCerts.first(), caCert.first()); + QCOMPARE(caCerts, caCert); +} + #endif // QT_NO_SSL QTEST_MAIN(tst_QSslCertificate) diff --git a/tests/auto/network/ssl/qsslkey/qsslkey.pro b/tests/auto/network/ssl/qsslkey/qsslkey.pro index 78cfb9ce92..4ec4f27e6f 100644 --- a/tests/auto/network/ssl/qsslkey/qsslkey.pro +++ b/tests/auto/network/ssl/qsslkey/qsslkey.pro @@ -4,6 +4,9 @@ CONFIG += parallel_test SOURCES += tst_qsslkey.cpp !wince*:win32:LIBS += -lws2_32 QT = core network testlib +contains(QT_CONFIG, private_tests) { + QT += core-private network-private +} TARGET = tst_qsslkey diff --git a/tests/auto/network/ssl/qsslkey/rsa-with-passphrase-3des.pem b/tests/auto/network/ssl/qsslkey/rsa-with-passphrase-3des.pem new file mode 100644 index 0000000000..6f04c0615a --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/rsa-with-passphrase-3des.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,8963B71DA5F406B2 + +95nMwjY/6wRlQU/F09WlGniwxkqct0Kr4/75stXAYJU/i56dyWHN22xJFB2SGaRO +Bi2g+hQnczyQ9qCpdxIzHvTo9Z1yRRdSZxtsdw57ZDYo9xtoRXQdNFCb1gbsSrlf +yZNRKueRCr/TFcxYcrZveUWwEssuZbztNW+deF/NSz35XJrI2C6MwTdm+lDTN6lS +AI/F7bGB0k+9nlIHNVgXPLnGOStIWhbTBbYtGryh0j/y913dtZX1djUHHmGCdEP6 +7WnfoD4v+5ux1YFb051xJJP+3lRE4evXJe0vzZAs5Lqy3qta/uwc3nV2oERursCM +roWkjZkP6TPAMFmkgQu1eHViL1u5CD+mYD/wDj2YwCIh8U2A5BN8KqM0N4bLEoPI +dcW2Pu60VEpMyeSKOSIyJsvT7F9M9/FpyNg5QW4BfrZNkVb/d7NROu/Lg5Oy4uf9 +a38tTgrQFQXcZFHbnTKD6VabCsZnVK0mFsEloUaTYalLTB6+C+jh7q3D08Re2OAB +g9yQshBx5DreOL4Y6rb1N6DqUqem4FqKbPP+x6URSf4SrXvH4jkBkk2AiQjc0oWl +5qvUt11LQOEMdvajlRicjlMm9KtV6+jRuSIeKgZqLpyja/4l+mX+G2X4pCbOiHFV +I5mRLLb3Cn7JEv6XlAZ1sjRZX7iS7sWFi3pzj6/i5JiH6RiQPHRmygrEUPdtD6J7 +d1W+fEh/osK+lB5Faa82oWrwxbdtgrNhKdQp1dkGezHe6WpBv8iMbTqXMBJHH/Pj +/hFc4FkZMYEZwKEVQ2Cyjq9kzKLnAS9s6x6PchagmNL20b5liB7V/w== +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/rsa-with-passphrase.pem b/tests/auto/network/ssl/qsslkey/rsa-with-passphrase-des.pem index cb29becc31..cb29becc31 100644 --- a/tests/auto/network/ssl/qsslkey/rsa-with-passphrase.pem +++ b/tests/auto/network/ssl/qsslkey/rsa-with-passphrase-des.pem diff --git a/tests/auto/network/ssl/qsslkey/rsa-with-passphrase-rc2.pem b/tests/auto/network/ssl/qsslkey/rsa-with-passphrase-rc2.pem new file mode 100644 index 0000000000..7a0722fb8d --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/rsa-with-passphrase-rc2.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: RC2-CBC,EAAF396E2CDD3680 + +G+kY27Vq0Bkw6dEGlpe4oyyXlilyKJgkX53NQHv0WtLsu+cfamGst9viSQbAluP0 +Pk2m78Z05IZHBkxcl20tZZR3G3hFTVqf7OemEucT5Kb/Vx6V++ZXY5eI54bh1oEJ +f8klr2DnscyTYdT33cmMuaxUm1sWjHeBBdQuQlMnW11XoCiGQMgMyf2fwbzd/og+ +vDPtORIMw+zedxaTsiOyNASLWB5ILDpUR9PTzz1tRIIOF5DnKttEe3SYPIqkLhxu +N7OtpVhor0QUulph8sS2uiilTVyaYVciOJK7Cqq2K015l9nlqGg/KI0GRIC9ty+k +wd+/Hdazp+YcLn3tL8jhekST/DAxK9VIb0DBvaboKr8UJw35nLOwA7smsij50l2S +kfpu9z/80gFbnSSQo7L8zD/kBzaPlup0H+h96rF3IjdCrnbveHlvJDo3GcPNxauw +rGUQXnnMzDVSTY179HfcgLZdsm3uOIBicEFaxXu2/L4Eof9yp8D/b6SeZeS41O7a +ICvLXxkiIfQHukHvqMLJ2SqKQ0J8zEXN0OBSLjaHUkBIOs3L4IFe2v8DMN798GrG +QzcxC0bmr9s6TvihlYFBbYkMZ3IYPT4SFZg92/pKTPlyD/Blc9oZm8QpQMGIMDKc +nWDLeqeCTXV6TL1mymqzwyzs9+4cXvEiM167FsLqk5tGRIyl4AR/dItELEtCWl3I +koIOUEk5rbJekOhTc85SFSQmCV0IebsUv0CpdWlmNeexNryLZu0r6kTUFWzpHcv/ +0yEaBQFLVx9QAfRSIiNt+yAgGnpMxxMxeHs6shVmuscZ0fV50GpOpA== +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index e735e463ee..1c16f47ad6 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -47,6 +47,11 @@ #include <QtNetwork/qhostaddress.h> #include <QtNetwork/qnetworkproxy.h> +#if !defined(QT_NO_SSL) && defined(QT_NO_OPENSSL) && defined(QT_BUILD_INTERNAL) +#include "private/qsslkey_p.h" +#define TEST_CRYPTO +#endif + class tst_QSslKey : public QObject { Q_OBJECT @@ -87,7 +92,14 @@ private slots: 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; @@ -320,18 +332,10 @@ void tst_QSslKey::toEncryptedPemOrDer() } 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); - // ### at this point, encryptedDer is invalid, hence the below QEXPECT_FAILs - QVERIFY(!encryptedDer.isEmpty()); - QSslKey keyDer(encryptedDer, algorithm, QSsl::Der, type, pwBytes); - if (type == QSsl::PrivateKey) - QEXPECT_FAIL( - QTest::currentDataTag(), "We're not able to decrypt these yet...", Continue); - QVERIFY(!keyDer.isNull()); - if (type == QSsl::PrivateKey) - QEXPECT_FAIL( - QTest::currentDataTag(), "We're not able to decrypt these yet...", Continue); - QCOMPARE(keyDer.toPem(), key.toPem()); + QVERIFY(encryptedDer.isEmpty()); } else { // verify that public keys are never encrypted by toDer() QByteArray encryptedDer = key.toDer(pwBytes); @@ -344,77 +348,192 @@ void tst_QSslKey::toEncryptedPemOrDer() // ### add a test to verify that public keys are _decrypted_ correctly (by the ctor) } +void tst_QSslKey::passphraseChecks_data() +{ + QTest::addColumn<QString>("fileName"); + + QTest::newRow("DES") << QString(testDataDir + "/rsa-with-passphrase-des.pem"); + QTest::newRow("3DES") << QString(testDataDir + "/rsa-with-passphrase-3des.pem"); + QTest::newRow("RC2") << QString(testDataDir + "/rsa-with-passphrase-rc2.pem"); +} + void tst_QSslKey::passphraseChecks() { + QFETCH(QString, fileName); + + QFile keyFile(fileName); + QVERIFY(keyFile.exists()); { - QString fileName(testDataDir + "/rsa-with-passphrase.pem"); - 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, "123"); - QVERIFY(!key.isNull()); // correct passphrase - } + 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, "123"); + 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); { - // 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 - } + 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::newRow("DES-CBC, length 0") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray() + << QByteArray::fromHex("956585228BAF9B1F"); + QTest::newRow("DES-CBC, length 1") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray(1, 'a') + << QByteArray::fromHex("E6880AF202BA3C12"); + QTest::newRow("DES-CBC, length 2") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray(2, 'a') + << QByteArray::fromHex("A82492386EED6026"); + QTest::newRow("DES-CBC, length 3") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray(3, 'a') + << QByteArray::fromHex("90B76D5B79519CBA"); + QTest::newRow("DES-CBC, length 4") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray(4, 'a') + << QByteArray::fromHex("63E3DD6FED87052A"); + QTest::newRow("DES-CBC, length 5") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray(5, 'a') + << QByteArray::fromHex("03ACDB0EACBDFA94"); + QTest::newRow("DES-CBC, length 6") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray(6, 'a') + << QByteArray::fromHex("7D95024E42A3A88A"); + QTest::newRow("DES-CBC, length 7") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray(7, 'a') + << QByteArray::fromHex("5003436B8A8E42E9"); + QTest::newRow("DES-CBC, length 8") + << QSslKeyPrivate::DesCbc << QByteArray("01234567") + << QByteArray(8, 'a') + << QByteArray::fromHex("E4C1F054BF5521C0A4A0FD4A2BC6C1B1"); + + QTest::newRow("DES-EDE3-CBC, length 0") + << QSslKeyPrivate::DesEde3Cbc << QByteArray("0123456789abcdefghijklmn") + << QByteArray() + << QByteArray::fromHex("3B2B4CD0B0FD495F"); + QTest::newRow("DES-EDE3-CBC, length 8") + << QSslKeyPrivate::DesEde3Cbc << QByteArray("0123456789abcdefghijklmn") + << QByteArray(8, 'a') + << QByteArray::fromHex("F2A5A87763C54A72A3224103D90CDB03"); + + QTest::newRow("RC2-40-CBC, length 0") + << QSslKeyPrivate::Rc2Cbc << QByteArray("01234") + << QByteArray() + << QByteArray::fromHex("6D05D52392FF6E7A"); + QTest::newRow("RC2-40-CBC, length 8") + << QSslKeyPrivate::Rc2Cbc << QByteArray("01234") + << QByteArray(8, 'a') + << QByteArray::fromHex("75768E64C5749072A5D168F3AFEB0005"); + + QTest::newRow("RC2-64-CBC, length 0") + << QSslKeyPrivate::Rc2Cbc << QByteArray("01234567") + << QByteArray() + << QByteArray::fromHex("ADAE6BF70F420130"); + QTest::newRow("RC2-64-CBC, length 8") + << QSslKeyPrivate::Rc2Cbc << QByteArray("01234567") + << QByteArray(8, 'a') + << QByteArray::fromHex("C7BF5C80AFBE9FBEFBBB9FD935F6D0DF"); + + QTest::newRow("RC2-128-CBC, length 0") + << QSslKeyPrivate::Rc2Cbc << QByteArray("012345679abcdefg") + << QByteArray() + << QByteArray::fromHex("1E965D483A13C8FB"); + QTest::newRow("RC2-128-CBC, length 8") + << QSslKeyPrivate::Rc2Cbc << QByteArray("012345679abcdefg") + << QByteArray(8, 'a') + << QByteArray::fromHex("5AEC1A5B295660B02613454232F7DECE"); +} + +void tst_QSslKey::encrypt() +{ + QFETCH(QSslKeyPrivate::Cipher, cipher); + QFETCH(QByteArray, key); + QFETCH(QByteArray, plainText); + QFETCH(QByteArray, cipherText); + QByteArray iv("abcdefgh"); + +#ifdef Q_OS_WINRT + QEXPECT_FAIL("RC2-40-CBC, length 0", "WinRT treats RC2 as 128-bit", Abort); + QEXPECT_FAIL("RC2-40-CBC, length 8", "WinRT treats RC2 as 128-bit", Abort); + QEXPECT_FAIL("RC2-64-CBC, length 0", "WinRT treats RC2 as 128-bit", Abort); + QEXPECT_FAIL("RC2-64-CBC, length 8", "WinRT 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) diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 30a9e19138..295b60e739 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -138,7 +138,9 @@ private slots: void peerCertificate(); void peerCertificateChain(); void privateKey(); +#ifndef QT_NO_OPENSSL void privateKeyOpaque(); +#endif void protocol(); void protocolServerSide_data(); void protocolServerSide(); @@ -186,7 +188,9 @@ private slots: void writeBigChunk(); void blacklistedCertificates(); void versionAccessors(); +#ifndef QT_NO_OPENSSL void sslOptions(); +#endif void encryptWithoutConnecting(); void resume_data(); void resume(); @@ -810,6 +814,7 @@ void tst_QSslSocket::privateKey() { } +#ifndef QT_NO_OPENSSL void tst_QSslSocket::privateKeyOpaque() { if (!QSslSocket::supportsSsl()) @@ -839,6 +844,7 @@ void tst_QSslSocket::privateKeyOpaque() if (setProxy && !socket->waitForEncrypted(10000)) QSKIP("Skipping flaky test - See QTBUG-29941"); } +#endif void tst_QSslSocket::protocol() { @@ -1027,17 +1033,17 @@ protected: if (m_interFile.isEmpty()) { QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile); QVERIFY(!localCert.isEmpty()); - QVERIFY(localCert.first().handle()); + QVERIFY(!localCert.first().isNull()); socket->setLocalCertificate(localCert.first()); } else { QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile); QVERIFY(!localCert.isEmpty()); - QVERIFY(localCert.first().handle()); + QVERIFY(!localCert.first().isNull()); QList<QSslCertificate> interCert = QSslCertificate::fromPath(m_interFile); QVERIFY(!interCert.isEmpty()); - QVERIFY(interCert.first().handle()); + QVERIFY(!interCert.first().isNull()); socket->setLocalCertificateChain(localCert + interCert); } @@ -1462,25 +1468,25 @@ void tst_QSslSocket::systemCaCertificates() void tst_QSslSocket::wildcardCertificateNames() { // Passing CN matches - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("www.example.com"), QString("www.example.com")), true ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example.com"), QString("www.example.com")), true ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("xxx*.example.com"), QString("xxxwww.example.com")), true ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("f*.example.com"), QString("foo.example.com")), true ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("192.168.0.0"), QString("192.168.0.0")), true ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("www.example.com"), QString("www.example.com")), true ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*.example.com"), QString("www.example.com")), true ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("xxx*.example.com"), QString("xxxwww.example.com")), true ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("f*.example.com"), QString("foo.example.com")), true ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("192.168.0.0"), QString("192.168.0.0")), true ); // Failing CN matches - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("xxx.example.com"), QString("www.example.com")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*"), QString("www.example.com")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.*.com"), QString("www.example.com")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example.com"), QString("baa.foo.example.com")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("f*.example.com"), QString("baa.example.com")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.com"), QString("example.com")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*fail.com"), QString("example.com")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example."), QString("www.example.")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example."), QString("www.example")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString(""), QString("www")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*"), QString("www")), false ); - QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.168.0.0"), QString("192.168.0.0")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("xxx.example.com"), QString("www.example.com")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*"), QString("www.example.com")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*.*.com"), QString("www.example.com")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*.example.com"), QString("baa.foo.example.com")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("f*.example.com"), QString("baa.example.com")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*.com"), QString("example.com")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*fail.com"), QString("example.com")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*.example."), QString("www.example.")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*.example."), QString("www.example")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString(""), QString("www")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*"), QString("www")), false ); + QCOMPARE( QSslSocketPrivate::isMatchingHostname(QString("*.168.0.0"), QString("192.168.0.0")), false ); } void tst_QSslSocket::wildcard() @@ -1527,7 +1533,7 @@ protected: // Only set the certificate QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert"); QVERIFY(!localCert.isEmpty()); - QVERIFY(localCert.first().handle()); + QVERIFY(!localCert.first().isNull()); socket->setLocalCertificate(localCert.first()); QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState)); @@ -1762,7 +1768,7 @@ protected: QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert"); QVERIFY(!localCert.isEmpty()); - QVERIFY(localCert.first().handle()); + QVERIFY(!localCert.first().isNull()); socket->setLocalCertificate(localCert.first()); QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState)); @@ -1992,10 +1998,23 @@ void tst_QSslSocket::peerVerifyError() socket->connectToHostEncrypted(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 443); if (socket->waitForEncrypted(10000)) QSKIP("Skipping flaky test - See QTBUG-29941"); + + // check HostNameMismatch was emitted by peerVerifyError QVERIFY(!peerVerifyErrorSpy.isEmpty()); + SslErrorList peerErrors; + const QList<QVariantList> &peerVerifyList = peerVerifyErrorSpy; + foreach (const QVariantList &args, peerVerifyList) + peerErrors << qvariant_cast<QSslError>(args.first()).error(); + QVERIFY(peerErrors.contains(QSslError::HostNameMismatch)); + + // check HostNameMismatch was emitted by sslErrors QVERIFY(!sslErrorsSpy.isEmpty()); - QCOMPARE(qvariant_cast<QSslError>(peerVerifyErrorSpy.last().at(0)).error(), QSslError::HostNameMismatch); - QCOMPARE(qvariant_cast<QList<QSslError> >(sslErrorsSpy.at(0).at(0)).size(), peerVerifyErrorSpy.size()); + SslErrorList sslErrors; + foreach (const QSslError &err, qvariant_cast<QList<QSslError> >(sslErrorsSpy.first().first())) + sslErrors << err.error(); + QVERIFY(peerErrors.contains(QSslError::HostNameMismatch)); + + QCOMPARE(sslErrors.size(), peerErrors.size()); } void tst_QSslSocket::disconnectFromHostWhenConnecting() @@ -2280,6 +2299,7 @@ void tst_QSslSocket::versionAccessors() qDebug() << QString::number(QSslSocket::sslLibraryVersionNumber(), 16); } +#ifndef QT_NO_OPENSSL void tst_QSslSocket::sslOptions() { if (!QSslSocket::supportsSsl()) @@ -2331,6 +2351,7 @@ void tst_QSslSocket::sslOptions() #endif #endif } +#endif void tst_QSslSocket::encryptWithoutConnecting() { @@ -2458,7 +2479,7 @@ void WebSocket::_startServerEncryption (void) QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile); QVERIFY(!localCert.isEmpty()); - QVERIFY(localCert.first().handle()); + QVERIFY(!localCert.first().isNull()); setLocalCertificate(localCert.first()); QVERIFY(!peerAddress().isNull()); @@ -2638,7 +2659,7 @@ void tst_QSslSocket::qtbug18498_peek2() QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert"); QVERIFY(!localCert.isEmpty()); - QVERIFY(localCert.first().handle()); + QVERIFY(!localCert.first().isNull()); server->setLocalCertificate(localCert.first()); server->setProtocol(QSsl::AnyProtocol); diff --git a/tests/auto/network/ssl/ssl.pro b/tests/auto/network/ssl/ssl.pro index 0b8f269fac..0cf910df73 100644 --- a/tests/auto/network/ssl/ssl.pro +++ b/tests/auto/network/ssl/ssl.pro @@ -16,3 +16,8 @@ contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked): winrt: SUBDIRS -= \ qsslsocket_onDemandCertificates_member \ qsslsocket_onDemandCertificates_static \ + +contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked): + contains(QT_CONFIG, private_tests) { + SUBDIRS += qasn1element +} |