1/**
2 * Copyright (C) 2006 Brad Hards <bradh@frogmouth.net>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <QtCrypto>
27#include <QtTest/QtTest>
28
29#ifdef QT_STATICPLUGIN
30#include "import_plugins.h"
31#endif
32
33#include <memory>
34
35class KeyBundleTest : public QObject
36{
37 Q_OBJECT
38
39private Q_SLOTS:
40 void initTestCase();
41 void cleanupTestCase();
42 void nullBundle();
43 void fromFile();
44 void names();
45 void certChain();
46 void privKey();
47 void createBundle();
48
49private:
50 QCA::Initializer *m_init;
51};
52
53void KeyBundleTest::initTestCase()
54{
55 m_init = new QCA::Initializer;
56}
57
58void KeyBundleTest::cleanupTestCase()
59{
60 QCA::unloadAllPlugins();
61 delete m_init;
62}
63
64void KeyBundleTest::nullBundle()
65{
66 QCA::KeyBundle nullBundle;
67 QVERIFY(nullBundle.isNull());
68 QCOMPARE(nullBundle.name(), QString());
69 QVERIFY(nullBundle.certificateChain().isEmpty());
70 QVERIFY(nullBundle.privateKey().isNull());
71
72 QCA::KeyBundle nullCopy = nullBundle; // NOLINT(performance-unnecessary-copy-initialization) This is copied on
73 // purpose to check the assignment operator
74 QVERIFY(nullCopy.isNull());
75 QCOMPARE(nullCopy.name(), QString());
76 QVERIFY(nullCopy.certificateChain().isEmpty());
77 QVERIFY(nullCopy.privateKey().isNull());
78
79 QCA::KeyBundle nullAssigned(nullCopy); // NOLINT(performance-unnecessary-copy-initialization) This is copied on
80 // purpose to check the copy constructor
81 QVERIFY(nullAssigned.isNull());
82 QCOMPARE(nullAssigned.name(), QString());
83 QVERIFY(nullAssigned.certificateChain().isEmpty());
84 QVERIFY(nullAssigned.privateKey().isNull());
85}
86
87void KeyBundleTest::fromFile()
88{
89 if (QCA::isSupported(features: "pkcs12")) {
90 // "start" is the passphrase, but you wouldn't normally
91 // code it in like this
92 QCA::KeyBundle userBundle(QStringLiteral("user2good.p12"), "start");
93 QCOMPARE(userBundle.isNull(), false);
94 QCOMPARE(userBundle.name(), QString());
95 QCOMPARE(userBundle.certificateChain().isEmpty(), false);
96 QCOMPARE(userBundle.privateKey().isNull(), false);
97
98 QCA::KeyBundle userBundleCopy = userBundle; // NOLINT(performance-unnecessary-copy-initialization) This is
99 // copied on purpose to check the assignment operator
100 QCOMPARE(userBundleCopy.isNull(), false);
101 QCOMPARE(userBundleCopy.name(), QString());
102 QCOMPARE(userBundleCopy.certificateChain().isEmpty(), false);
103 QCOMPARE(userBundleCopy.privateKey().isNull(), false);
104
105 QCA::KeyBundle userBundleAssign(userBundleCopy); // NOLINT(performance-unnecessary-copy-initialization) This is
106 // copied on purpose to check the copy constructor
107 QCOMPARE(userBundleAssign.isNull(), false);
108 QCOMPARE(userBundleAssign.name(), QString());
109 QCOMPARE(userBundleAssign.certificateChain().isEmpty(), false);
110 QCOMPARE(userBundleAssign.privateKey().isNull(), false);
111 }
112}
113
114void KeyBundleTest::names()
115{
116 if (QCA::isSupported(features: "pkcs12")) {
117 QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
118 QCOMPARE(serverBundle.isNull(), false);
119 QCOMPARE(serverBundle.name(), QString());
120
121 serverBundle.setName(QStringLiteral("Some Server Bundle"));
122 QCOMPARE(serverBundle.name(), QStringLiteral("Some Server Bundle"));
123 }
124}
125
126void KeyBundleTest::certChain()
127{
128 if (QCA::isSupported(features: "pkcs12")) {
129 QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
130 QCOMPARE(serverBundle.isNull(), false);
131 QCOMPARE(serverBundle.certificateChain().size(), 1);
132 }
133}
134
135void KeyBundleTest::privKey()
136{
137 if (QCA::isSupported(features: "pkcs12")) {
138 QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
139 QCOMPARE(serverBundle.isNull(), false);
140 QCOMPARE(serverBundle.privateKey().isNull(), false);
141 }
142}
143void KeyBundleTest::createBundle()
144{
145 std::unique_ptr<QCA::KeyBundle> newBundle(new QCA::KeyBundle);
146
147 QVERIFY(newBundle->isNull());
148
149 if (!QCA::isSupported(features: "certificate"))
150 return;
151
152 QCA::Certificate ca(QStringLiteral("RootCA2cert.pem"));
153 QCOMPARE(ca.isNull(), false);
154
155 QCA::Certificate primary(QStringLiteral("user2goodcert.pem"));
156 QCOMPARE(primary.isNull(), false);
157
158 QCA::PrivateKey key(QStringLiteral("user2goodkey.pem"));
159 QCOMPARE(key.isNull(), false);
160
161 QCA::CertificateChain chain(primary);
162 chain.append(t: ca);
163
164 newBundle->setCertificateChainAndKey(c: chain, key);
165 newBundle->setName(QStringLiteral("My New Key Bundle"));
166
167 QCOMPARE(newBundle->certificateChain(), chain);
168 QCOMPARE(newBundle->privateKey(), key);
169 QCOMPARE(newBundle->name(), QStringLiteral("My New Key Bundle"));
170
171 // Try round tripping the bundle
172 foreach (const QCA::Provider *thisProvider, QCA::providers()) {
173 QString provider = thisProvider->name();
174 if (QCA::isSupported(features: "pkcs12", provider)) {
175 qDebug() << "Testing " << provider;
176 QByteArray bundleArray = newBundle->toArray(passphrase: "reel secrut", provider);
177 QCOMPARE(bundleArray.isNull(), false);
178
179 QCA::ConvertResult res;
180 QCA::KeyBundle bundleFromArray = QCA::KeyBundle::fromArray(a: bundleArray, passphrase: "reel secrut", result: &res, provider);
181 QCOMPARE(res, QCA::ConvertGood);
182 QCOMPARE(bundleFromArray.isNull(), false);
183 QCOMPARE(bundleFromArray.name(), QStringLiteral("My New Key Bundle"));
184 QCOMPARE(bundleFromArray.certificateChain(), chain);
185 QCOMPARE(bundleFromArray.privateKey(), key);
186
187 QTemporaryFile tempFile;
188 QVERIFY(tempFile.open());
189
190 bool result = newBundle->toFile(fileName: tempFile.fileName(), passphrase: "file passphrase", provider);
191 QVERIFY(result);
192
193 QCA::KeyBundle bundleFromFile =
194 QCA::KeyBundle::fromFile(fileName: tempFile.fileName(), passphrase: "file passphrase", result: &res, provider);
195 QCOMPARE(res, QCA::ConvertGood);
196 QCOMPARE(bundleFromFile.isNull(), false);
197 QCOMPARE(bundleFromFile.name(), QStringLiteral("My New Key Bundle"));
198 QCOMPARE(bundleFromFile.certificateChain(), chain);
199 QCOMPARE(bundleFromFile.privateKey(), key);
200 }
201 }
202}
203
204QTEST_MAIN(KeyBundleTest)
205
206#include "keybundle.moc"
207

source code of qca/unittest/keybundle/keybundle.cpp