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 <QTemporaryFile>
27#include <QTest>
28#include <QtCrypto>
29
30#ifdef QT_STATICPLUGIN
31#include "import_plugins.h"
32#endif
33
34#include <memory>
35
36class KeyBundleTest : public QObject
37{
38 Q_OBJECT
39
40private Q_SLOTS:
41 void initTestCase();
42 void cleanupTestCase();
43 void nullBundle();
44 void fromFile();
45 void names();
46 void certChain();
47 void privKey();
48 void createBundle();
49
50private:
51 QCA::Initializer *m_init;
52};
53
54void KeyBundleTest::initTestCase()
55{
56 m_init = new QCA::Initializer;
57}
58
59void KeyBundleTest::cleanupTestCase()
60{
61 QCA::unloadAllPlugins();
62 delete m_init;
63}
64
65void KeyBundleTest::nullBundle()
66{
67 QCA::KeyBundle nullBundle;
68 QVERIFY(nullBundle.isNull());
69 QCOMPARE(nullBundle.name(), QString());
70 QVERIFY(nullBundle.certificateChain().isEmpty());
71 QVERIFY(nullBundle.privateKey().isNull());
72
73 QCA::KeyBundle nullCopy = nullBundle; // NOLINT(performance-unnecessary-copy-initialization) This is copied on
74 // purpose to check the assignment operator
75 QVERIFY(nullCopy.isNull());
76 QCOMPARE(nullCopy.name(), QString());
77 QVERIFY(nullCopy.certificateChain().isEmpty());
78 QVERIFY(nullCopy.privateKey().isNull());
79
80 QCA::KeyBundle nullAssigned(nullCopy); // NOLINT(performance-unnecessary-copy-initialization) This is copied on
81 // purpose to check the copy constructor
82 QVERIFY(nullAssigned.isNull());
83 QCOMPARE(nullAssigned.name(), QString());
84 QVERIFY(nullAssigned.certificateChain().isEmpty());
85 QVERIFY(nullAssigned.privateKey().isNull());
86}
87
88void KeyBundleTest::fromFile()
89{
90 if (QCA::isSupported(features: "pkcs12")) {
91 // "start" is the passphrase, but you wouldn't normally
92 // code it in like this
93 QCA::KeyBundle userBundle(QStringLiteral("user2good.p12"), "start");
94 QCOMPARE(userBundle.isNull(), false);
95 QCOMPARE(userBundle.name(), QString());
96 QCOMPARE(userBundle.certificateChain().isEmpty(), false);
97 QCOMPARE(userBundle.privateKey().isNull(), false);
98
99 QCA::KeyBundle userBundleCopy = userBundle; // NOLINT(performance-unnecessary-copy-initialization) This is
100 // copied on purpose to check the assignment operator
101 QCOMPARE(userBundleCopy.isNull(), false);
102 QCOMPARE(userBundleCopy.name(), QString());
103 QCOMPARE(userBundleCopy.certificateChain().isEmpty(), false);
104 QCOMPARE(userBundleCopy.privateKey().isNull(), false);
105
106 QCA::KeyBundle userBundleAssign(userBundleCopy); // NOLINT(performance-unnecessary-copy-initialization) This is
107 // copied on purpose to check the copy constructor
108 QCOMPARE(userBundleAssign.isNull(), false);
109 QCOMPARE(userBundleAssign.name(), QString());
110 QCOMPARE(userBundleAssign.certificateChain().isEmpty(), false);
111 QCOMPARE(userBundleAssign.privateKey().isNull(), false);
112 }
113}
114
115void KeyBundleTest::names()
116{
117 if (QCA::isSupported(features: "pkcs12")) {
118 QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
119 QCOMPARE(serverBundle.isNull(), false);
120 QCOMPARE(serverBundle.name(), QString());
121
122 serverBundle.setName(QStringLiteral("Some Server Bundle"));
123 QCOMPARE(serverBundle.name(), QStringLiteral("Some Server Bundle"));
124 }
125}
126
127void KeyBundleTest::certChain()
128{
129 if (QCA::isSupported(features: "pkcs12")) {
130 QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
131 QCOMPARE(serverBundle.isNull(), false);
132 QCOMPARE(serverBundle.certificateChain().size(), 1);
133 }
134}
135
136void KeyBundleTest::privKey()
137{
138 if (QCA::isSupported(features: "pkcs12")) {
139 QCA::KeyBundle serverBundle(QStringLiteral("servergood2.p12"), "start");
140 QCOMPARE(serverBundle.isNull(), false);
141 QCOMPARE(serverBundle.privateKey().isNull(), false);
142 }
143}
144void KeyBundleTest::createBundle()
145{
146 std::unique_ptr<QCA::KeyBundle> newBundle(new QCA::KeyBundle);
147
148 QVERIFY(newBundle->isNull());
149
150 if (!QCA::isSupported(features: "certificate"))
151 return;
152
153 QCA::Certificate ca(QStringLiteral("RootCA2cert.pem"));
154 QCOMPARE(ca.isNull(), false);
155
156 QCA::Certificate primary(QStringLiteral("user2goodcert.pem"));
157 QCOMPARE(primary.isNull(), false);
158
159 QCA::PrivateKey key(QStringLiteral("user2goodkey.pem"));
160 QCOMPARE(key.isNull(), false);
161
162 QCA::CertificateChain chain(primary);
163 chain.append(t: ca);
164
165 newBundle->setCertificateChainAndKey(c: chain, key);
166 newBundle->setName(QStringLiteral("My New Key Bundle"));
167
168 QCOMPARE(newBundle->certificateChain(), chain);
169 QCOMPARE(newBundle->privateKey(), key);
170 QCOMPARE(newBundle->name(), QStringLiteral("My New Key Bundle"));
171
172 // Try round tripping the bundle
173 foreach (const QCA::Provider *thisProvider, QCA::providers()) {
174 QString provider = thisProvider->name();
175 if (QCA::isSupported(features: "pkcs12", provider)) {
176 qDebug() << "Testing " << provider;
177 QByteArray bundleArray = newBundle->toArray(passphrase: "reel secrut", provider);
178 QCOMPARE(bundleArray.isNull(), false);
179
180 QCA::ConvertResult res;
181 QCA::KeyBundle bundleFromArray = QCA::KeyBundle::fromArray(a: bundleArray, passphrase: "reel secrut", result: &res, provider);
182 QCOMPARE(res, QCA::ConvertGood);
183 QCOMPARE(bundleFromArray.isNull(), false);
184 QCOMPARE(bundleFromArray.name(), QStringLiteral("My New Key Bundle"));
185 QCOMPARE(bundleFromArray.certificateChain(), chain);
186 QCOMPARE(bundleFromArray.privateKey(), key);
187
188 QTemporaryFile tempFile;
189 QVERIFY(tempFile.open());
190
191 bool result = newBundle->toFile(fileName: tempFile.fileName(), passphrase: "file passphrase", provider);
192 QVERIFY(result);
193
194 QCA::KeyBundle bundleFromFile =
195 QCA::KeyBundle::fromFile(fileName: tempFile.fileName(), passphrase: "file passphrase", result: &res, provider);
196 QCOMPARE(res, QCA::ConvertGood);
197 QCOMPARE(bundleFromFile.isNull(), false);
198 QCOMPARE(bundleFromFile.name(), QStringLiteral("My New Key Bundle"));
199 QCOMPARE(bundleFromFile.certificateChain(), chain);
200 QCOMPARE(bundleFromFile.privateKey(), key);
201 }
202 }
203}
204
205QTEST_MAIN(KeyBundleTest)
206
207#include "keybundle.moc"
208

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