File indexing completed on 2024-05-05 04:45:31

0001 /**
0002  * Copyright (C)  2006  Brad Hards <bradh@frogmouth.net>
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  *
0008  * 1. Redistributions of source code must retain the above copyright
0009  *   notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *   notice, this list of conditions and the following disclaimer in the
0012  *   documentation and/or other materials provided with the distribution.
0013  *
0014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0015  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0016  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0017  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0018  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0019  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0020  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0021  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0023  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #include <QtCrypto>
0027 #include <QtTest/QtTest>
0028 
0029 #ifdef QT_STATICPLUGIN
0030 #include "import_plugins.h"
0031 #endif
0032 
0033 #include <memory>
0034 
0035 class KeyBundleTest : public QObject
0036 {
0037     Q_OBJECT
0038 
0039 private Q_SLOTS:
0040     void initTestCase();
0041     void cleanupTestCase();
0042     void nullBundle();
0043     void fromFile();
0044     void names();
0045     void certChain();
0046     void privKey();
0047     void createBundle();
0048 
0049 private:
0050     QCA::Initializer *m_init;
0051 };
0052 
0053 void KeyBundleTest::initTestCase()
0054 {
0055     m_init = new QCA::Initializer;
0056 }
0057 
0058 void KeyBundleTest::cleanupTestCase()
0059 {
0060     QCA::unloadAllPlugins();
0061     delete m_init;
0062 }
0063 
0064 void KeyBundleTest::nullBundle()
0065 {
0066     QCA::KeyBundle nullBundle;
0067     QVERIFY(nullBundle.isNull());
0068     QCOMPARE(nullBundle.name(), QString());
0069     QVERIFY(nullBundle.certificateChain().isEmpty());
0070     QVERIFY(nullBundle.privateKey().isNull());
0071 
0072     QCA::KeyBundle nullCopy = nullBundle; // NOLINT(performance-unnecessary-copy-initialization) This is copied on
0073                                           // purpose to check the assignment operator
0074     QVERIFY(nullCopy.isNull());
0075     QCOMPARE(nullCopy.name(), QString());
0076     QVERIFY(nullCopy.certificateChain().isEmpty());
0077     QVERIFY(nullCopy.privateKey().isNull());
0078 
0079     QCA::KeyBundle nullAssigned(nullCopy); // NOLINT(performance-unnecessary-copy-initialization) This is copied on
0080                                            // purpose to check the copy constructor
0081     QVERIFY(nullAssigned.isNull());
0082     QCOMPARE(nullAssigned.name(), QString());
0083     QVERIFY(nullAssigned.certificateChain().isEmpty());
0084     QVERIFY(nullAssigned.privateKey().isNull());
0085 }
0086 
0087 void KeyBundleTest::fromFile()
0088 {
0089     if (QCA::isSupported("pkcs12")) {
0090         // "start" is the passphrase, but you wouldn't normally
0091         // code it in like this
0092         QCA::KeyBundle userBundle(QStringLiteral("user2good.p12"), "start");
0093         QCOMPARE(userBundle.isNull(), false);
0094         QCOMPARE(userBundle.name(), QString());
0095         QCOMPARE(userBundle.certificateChain().isEmpty(), false);
0096         QCOMPARE(userBundle.privateKey().isNull(), false);
0097 
0098         QCA::KeyBundle userBundleCopy = userBundle; // NOLINT(performance-unnecessary-copy-initialization) This is
0099                                                     // copied on purpose to check the assignment operator
0100         QCOMPARE(userBundleCopy.isNull(), false);
0101         QCOMPARE(userBundleCopy.name(), QString());
0102         QCOMPARE(userBundleCopy.certificateChain().isEmpty(), false);
0103         QCOMPARE(userBundleCopy.privateKey().isNull(), false);
0104 
0105         QCA::KeyBundle userBundleAssign(userBundleCopy); // NOLINT(performance-unnecessary-copy-initialization) This is
0106                                                          // copied on purpose to check the copy constructor
0107         QCOMPARE(userBundleAssign.isNull(), false);
0108         QCOMPARE(userBundleAssign.name(), QString());
0109         QCOMPARE(userBundleAssign.certificateChain().isEmpty(), false);
0110         QCOMPARE(userBundleAssign.privateKey().isNull(), false);
0111     }
0112 }
0113 
0114 void KeyBundleTest::names()
0115 {
0116     if (QCA::isSupported("pkcs12")) {
0117         QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
0118         QCOMPARE(serverBundle.isNull(), false);
0119         QCOMPARE(serverBundle.name(), QString());
0120 
0121         serverBundle.setName(QStringLiteral("Some Server Bundle"));
0122         QCOMPARE(serverBundle.name(), QStringLiteral("Some Server Bundle"));
0123     }
0124 }
0125 
0126 void KeyBundleTest::certChain()
0127 {
0128     if (QCA::isSupported("pkcs12")) {
0129         QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
0130         QCOMPARE(serverBundle.isNull(), false);
0131         QCOMPARE(serverBundle.certificateChain().size(), 1);
0132     }
0133 }
0134 
0135 void KeyBundleTest::privKey()
0136 {
0137     if (QCA::isSupported("pkcs12")) {
0138         QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
0139         QCOMPARE(serverBundle.isNull(), false);
0140         QCOMPARE(serverBundle.privateKey().isNull(), false);
0141     }
0142 }
0143 void KeyBundleTest::createBundle()
0144 {
0145     std::unique_ptr<QCA::KeyBundle> newBundle(new QCA::KeyBundle);
0146 
0147     QVERIFY(newBundle->isNull());
0148 
0149     if (!QCA::isSupported("certificate"))
0150         return;
0151 
0152     QCA::Certificate ca(QStringLiteral("RootCA2cert.pem"));
0153     QCOMPARE(ca.isNull(), false);
0154 
0155     QCA::Certificate primary(QStringLiteral("user2goodcert.pem"));
0156     QCOMPARE(primary.isNull(), false);
0157 
0158     QCA::PrivateKey key(QStringLiteral("user2goodkey.pem"));
0159     QCOMPARE(key.isNull(), false);
0160 
0161     QCA::CertificateChain chain(primary);
0162     chain.append(ca);
0163 
0164     newBundle->setCertificateChainAndKey(chain, key);
0165     newBundle->setName(QStringLiteral("My New Key Bundle"));
0166 
0167     QCOMPARE(newBundle->certificateChain(), chain);
0168     QCOMPARE(newBundle->privateKey(), key);
0169     QCOMPARE(newBundle->name(), QStringLiteral("My New Key Bundle"));
0170 
0171     // Try round tripping the bundle
0172     foreach (const QCA::Provider *thisProvider, QCA::providers()) {
0173         QString provider = thisProvider->name();
0174         if (QCA::isSupported("pkcs12", provider)) {
0175             qDebug() << "Testing " << provider;
0176             QByteArray bundleArray = newBundle->toArray("reel secrut", provider);
0177             QCOMPARE(bundleArray.isNull(), false);
0178 
0179             QCA::ConvertResult res;
0180             QCA::KeyBundle     bundleFromArray = QCA::KeyBundle::fromArray(bundleArray, "reel secrut", &res, provider);
0181             QCOMPARE(res, QCA::ConvertGood);
0182             QCOMPARE(bundleFromArray.isNull(), false);
0183             QCOMPARE(bundleFromArray.name(), QStringLiteral("My New Key Bundle"));
0184             QCOMPARE(bundleFromArray.certificateChain(), chain);
0185             QCOMPARE(bundleFromArray.privateKey(), key);
0186 
0187             QTemporaryFile tempFile;
0188             QVERIFY(tempFile.open());
0189 
0190             bool result = newBundle->toFile(tempFile.fileName(), "file passphrase", provider);
0191             QVERIFY(result);
0192 
0193             QCA::KeyBundle bundleFromFile =
0194                 QCA::KeyBundle::fromFile(tempFile.fileName(), "file passphrase", &res, provider);
0195             QCOMPARE(res, QCA::ConvertGood);
0196             QCOMPARE(bundleFromFile.isNull(), false);
0197             QCOMPARE(bundleFromFile.name(), QStringLiteral("My New Key Bundle"));
0198             QCOMPARE(bundleFromFile.certificateChain(), chain);
0199             QCOMPARE(bundleFromFile.privateKey(), key);
0200         }
0201     }
0202 }
0203 
0204 QTEST_MAIN(KeyBundleTest)
0205 
0206 #include "keybundle.moc"