File indexing completed on 2025-01-12 04:20:06
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 <openssl/opensslv.h> 0034 0035 class CMSut : public QObject 0036 { 0037 Q_OBJECT 0038 0039 private Q_SLOTS: 0040 void initTestCase(); 0041 void cleanupTestCase(); 0042 void xcrypt_data(); 0043 void xcrypt(); 0044 void signverify_data(); 0045 void signverify(); 0046 void signverify_message_data(); 0047 void signverify_message(); 0048 void signverify_message_invalid_data(); 0049 void signverify_message_invalid(); 0050 0051 private: 0052 QCA::Initializer *m_init; 0053 }; 0054 0055 void CMSut::initTestCase() 0056 { 0057 m_init = new QCA::Initializer; 0058 } 0059 0060 void CMSut::cleanupTestCase() 0061 { 0062 delete m_init; 0063 } 0064 0065 void CMSut::xcrypt_data() 0066 { 0067 QTest::addColumn<QByteArray>("testText"); 0068 0069 QTest::newRow("empty") << QByteArray(""); 0070 QTest::newRow("0") << QByteArray("0"); 0071 QTest::newRow("07") << QByteArray("07899847jkjjfasjaJKJLJkljklj&kjlj;/**-+.01"); 0072 QTest::newRow("dubious") << QByteArray("~!#**$#&&%^@#^&()"); 0073 } 0074 0075 void CMSut::xcrypt() 0076 { 0077 QStringList providersToTest; 0078 providersToTest.append(QStringLiteral("qca-ossl")); 0079 0080 foreach (const QString provider, providersToTest) { 0081 if (!QCA::isSupported("cert", provider)) 0082 QWARN((QStringLiteral("Certificate not supported for ") + provider).toLocal8Bit().constData()); 0083 else if (!QCA::isSupported("cms", provider)) 0084 QWARN((QStringLiteral("CMS not supported for ") + provider).toLocal8Bit().constData()); 0085 else { 0086 QCA::Certificate pubCert = 0087 QCA::Certificate::fromPEMFile(QStringLiteral("QcaTestClientCert.pem"), nullptr, provider); 0088 QCOMPARE(pubCert.isNull(), false); 0089 0090 QCA::SecureMessageKey secMsgKey; 0091 QCA::CertificateChain chain; 0092 chain += pubCert; 0093 secMsgKey.setX509CertificateChain(chain); 0094 0095 QCA::CMS cms; 0096 QCA::SecureMessage msg(&cms); 0097 QCOMPARE(msg.canClearsign(), false); 0098 QCOMPARE(msg.canSignAndEncrypt(), false); 0099 QCOMPARE(msg.type(), QCA::SecureMessage::CMS); 0100 0101 msg.setRecipient(secMsgKey); 0102 0103 QFETCH(QByteArray, testText); 0104 0105 msg.startEncrypt(); 0106 msg.update(testText); 0107 msg.end(); 0108 0109 msg.waitForFinished(-1); 0110 0111 QByteArray encryptedResult1 = msg.read(); 0112 QCOMPARE(encryptedResult1.isEmpty(), false); 0113 0114 msg.reset(); 0115 msg.setRecipient(secMsgKey); 0116 msg.startEncrypt(); 0117 msg.update(testText); 0118 msg.end(); 0119 0120 msg.waitForFinished(-1); 0121 QVERIFY(msg.success()); 0122 0123 QByteArray encryptedResult2 = msg.read(); 0124 QCOMPARE(encryptedResult2.isEmpty(), false); 0125 0126 QCA::ConvertResult res; 0127 QCA::SecureArray passPhrase = "start"; 0128 QCA::PrivateKey privKey = 0129 QCA::PrivateKey::fromPEMFile(QStringLiteral("QcaTestClientKey.pem"), passPhrase, &res); 0130 QCOMPARE(res, QCA::ConvertGood); 0131 0132 secMsgKey.setX509PrivateKey(privKey); 0133 QCA::SecureMessageKeyList privKeyList; 0134 privKeyList += secMsgKey; 0135 QCA::CMS cms2; 0136 cms2.setPrivateKeys(privKeyList); 0137 0138 QCA::SecureMessage msg2(&cms2); 0139 0140 msg2.startDecrypt(); 0141 msg2.update(encryptedResult1); 0142 msg2.end(); 0143 msg2.waitForFinished(-1); 0144 QVERIFY(msg2.success()); 0145 QByteArray decryptedResult1 = msg2.read(); 0146 QCOMPARE(decryptedResult1, testText); 0147 0148 msg2.reset(); 0149 msg2.startDecrypt(); 0150 msg2.update(encryptedResult1); 0151 msg2.end(); 0152 msg2.waitForFinished(-1); 0153 QVERIFY(msg2.success()); 0154 QByteArray decryptedResult2 = msg2.read(); 0155 0156 QCOMPARE(decryptedResult1, decryptedResult2); 0157 0158 QCOMPARE(msg2.canClearsign(), false); 0159 QCOMPARE(msg2.canSignAndEncrypt(), false); 0160 QCOMPARE(msg2.type(), QCA::SecureMessage::CMS); 0161 } 0162 } 0163 } 0164 0165 void CMSut::signverify_data() 0166 { 0167 QTest::addColumn<QByteArray>("testText"); 0168 0169 QTest::newRow("empty") << QByteArray(""); 0170 QTest::newRow("0") << QByteArray("0"); 0171 QTest::newRow("07") << QByteArray("07899847jkjjfasjaJKJLJkljklj&kjlj;/**-+.01"); 0172 QTest::newRow("dubious") << QByteArray("~!#**$#&&%^@#^&()"); 0173 } 0174 0175 // This one tests Detached format. 0176 void CMSut::signverify() 0177 { 0178 QStringList providersToTest; 0179 providersToTest.append(QStringLiteral("qca-ossl")); 0180 0181 foreach (const QString provider, providersToTest) { 0182 if (!QCA::isSupported("cert", provider)) 0183 QWARN((QStringLiteral("Certificate not supported for ") + provider).toLocal8Bit().constData()); 0184 else if (!QCA::isSupported("cms", provider)) 0185 QWARN((QStringLiteral("CMS not supported for ") + provider).toLocal8Bit().constData()); 0186 else { 0187 QCA::ConvertResult res; 0188 QCA::SecureArray passPhrase = "start"; 0189 QCA::PrivateKey privKey = 0190 QCA::PrivateKey::fromPEMFile(QStringLiteral("QcaTestClientKey.pem"), passPhrase, &res, provider); 0191 QCOMPARE(res, QCA::ConvertGood); 0192 0193 QCA::Certificate pubCert = 0194 QCA::Certificate::fromPEMFile(QStringLiteral("QcaTestClientCert.pem"), &res, provider); 0195 QCOMPARE(res, QCA::ConvertGood); 0196 QCOMPARE(pubCert.isNull(), false); 0197 0198 QCA::CertificateChain chain; 0199 chain += pubCert; 0200 QCA::SecureMessageKey secMsgKey; 0201 secMsgKey.setX509CertificateChain(chain); 0202 secMsgKey.setX509PrivateKey(privKey); 0203 0204 QCA::SecureMessageKeyList privKeyList; 0205 privKeyList += secMsgKey; 0206 QCA::CMS cms2; 0207 cms2.setPrivateKeys(privKeyList); 0208 0209 QCA::SecureMessage msg2(&cms2); 0210 msg2.setSigners(privKeyList); 0211 QCOMPARE(msg2.canClearsign(), false); 0212 QCOMPARE(msg2.canSignAndEncrypt(), false); 0213 QCOMPARE(msg2.type(), QCA::SecureMessage::CMS); 0214 0215 QFETCH(QByteArray, testText); 0216 0217 msg2.startSign(QCA::SecureMessage::Detached); 0218 msg2.update(testText); 0219 msg2.end(); 0220 msg2.waitForFinished(-1); 0221 QVERIFY(msg2.success()); 0222 QByteArray signedResult1 = msg2.signature(); 0223 QCOMPARE(signedResult1.isEmpty(), false); 0224 0225 msg2.reset(); 0226 0227 msg2.setSigners(privKeyList); 0228 msg2.startSign(QCA::SecureMessage::Detached); 0229 msg2.update(testText); 0230 msg2.end(); 0231 msg2.waitForFinished(-1); 0232 QVERIFY(msg2.success()); 0233 QByteArray signedResult2 = msg2.signature(); 0234 0235 QCOMPARE(signedResult2.isEmpty(), false); 0236 0237 QCA::CMS cms; 0238 QCA::Certificate caCert = 0239 QCA::Certificate::fromPEMFile(QStringLiteral("QcaTestRootCert.pem"), &res, provider); 0240 QCOMPARE(res, QCA::ConvertGood); 0241 QCA::CertificateCollection caCertCollection; 0242 caCertCollection.addCertificate(caCert); 0243 0244 cms.setTrustedCertificates(caCertCollection); 0245 QCA::SecureMessage msg(&cms); 0246 QCOMPARE(msg.canClearsign(), false); 0247 QCOMPARE(msg.canSignAndEncrypt(), false); 0248 QCOMPARE(msg.type(), QCA::SecureMessage::CMS); 0249 0250 msg.startVerify(signedResult1); 0251 msg.update(testText); 0252 msg.end(); 0253 0254 msg.waitForFinished(-1); 0255 QVERIFY(msg.wasSigned()); 0256 QVERIFY(msg.success()); 0257 #if OPENSSL_VERSION_NUMBER < 0x1010109fL 0258 QEXPECT_FAIL("empty", "We don't seem to be able to verify signature of a zero length message", Continue); 0259 #endif 0260 QVERIFY(msg.verifySuccess()); 0261 0262 msg.reset(); 0263 0264 msg.startVerify(signedResult2); 0265 msg.update(testText); 0266 msg.end(); 0267 0268 msg.waitForFinished(-1); 0269 QVERIFY(msg.wasSigned()); 0270 QVERIFY(msg.success()); 0271 #if OPENSSL_VERSION_NUMBER < 0x1010109fL 0272 QEXPECT_FAIL("empty", "We don't seem to be able to verify signature of a zero length message", Continue); 0273 #endif 0274 QVERIFY(msg.verifySuccess()); 0275 0276 msg.reset(); 0277 0278 // This tests junk on the end of the signature - should fail 0279 msg.startVerify(signedResult2 + "junk"); 0280 msg.update(testText); 0281 msg.end(); 0282 0283 msg.waitForFinished(-1); 0284 QVERIFY(msg.wasSigned()); 0285 QVERIFY(msg.success()); 0286 #if OPENSSL_VERSION_NUMBER >= 0x1010109fL 0287 QEXPECT_FAIL("empty", "On newer openssl verifaction of zero length message always succeeds", Continue); 0288 #endif 0289 QCOMPARE(msg.verifySuccess(), false); 0290 0291 msg.reset(); 0292 0293 // This tests junk on the end of the message - should fail 0294 msg.startVerify(signedResult2); 0295 msg.update(testText + "junk"); 0296 msg.end(); 0297 0298 msg.waitForFinished(-1); 0299 QVERIFY(msg.wasSigned()); 0300 QVERIFY(msg.success()); 0301 QCOMPARE(msg.verifySuccess(), false); 0302 } 0303 } 0304 } 0305 0306 void CMSut::signverify_message_data() 0307 { 0308 QTest::addColumn<QByteArray>("testText"); 0309 0310 QTest::newRow("empty") << QByteArray(""); 0311 QTest::newRow("0") << QByteArray("0"); 0312 QTest::newRow("07") << QByteArray("07899847jkjjfasjaJKJLJkljklj&kjlj;/**-+.01"); 0313 QTest::newRow("dubious") << QByteArray("~!#**$#&&%^@#^&()"); 0314 } 0315 0316 // This one tests Message format 0317 void CMSut::signverify_message() 0318 { 0319 QStringList providersToTest; 0320 providersToTest.append(QStringLiteral("qca-ossl")); 0321 0322 foreach (const QString provider, providersToTest) { 0323 if (!QCA::isSupported("cert", provider)) 0324 QWARN((QStringLiteral("Certificate not supported for ") + provider).toLocal8Bit().constData()); 0325 else if (!QCA::isSupported("cms", provider)) 0326 QWARN((QStringLiteral("CMS not supported for ") + provider).toLocal8Bit().constData()); 0327 else { 0328 QCA::ConvertResult res; 0329 QCA::SecureArray passPhrase = "start"; 0330 QCA::PrivateKey privKey = 0331 QCA::PrivateKey::fromPEMFile(QStringLiteral("QcaTestClientKey.pem"), passPhrase, &res, provider); 0332 QCOMPARE(res, QCA::ConvertGood); 0333 0334 QCA::Certificate pubCert = 0335 QCA::Certificate::fromPEMFile(QStringLiteral("QcaTestClientCert.pem"), &res, provider); 0336 QCOMPARE(res, QCA::ConvertGood); 0337 QCOMPARE(pubCert.isNull(), false); 0338 0339 QCA::CertificateChain chain; 0340 chain += pubCert; 0341 QCA::SecureMessageKey secMsgKey; 0342 secMsgKey.setX509CertificateChain(chain); 0343 secMsgKey.setX509PrivateKey(privKey); 0344 0345 QCA::SecureMessageKeyList privKeyList; 0346 privKeyList += secMsgKey; 0347 QCA::CMS cms2; 0348 cms2.setPrivateKeys(privKeyList); 0349 0350 QCA::SecureMessage msg2(&cms2); 0351 msg2.setSigners(privKeyList); 0352 QCOMPARE(msg2.canClearsign(), false); 0353 QCOMPARE(msg2.canSignAndEncrypt(), false); 0354 QCOMPARE(msg2.type(), QCA::SecureMessage::CMS); 0355 0356 QFETCH(QByteArray, testText); 0357 0358 msg2.startSign(QCA::SecureMessage::Message); 0359 msg2.update(testText); 0360 msg2.end(); 0361 msg2.waitForFinished(-1); 0362 QVERIFY(msg2.success()); 0363 QByteArray signedResult1 = msg2.read(); 0364 QCOMPARE(signedResult1.isEmpty(), false); 0365 0366 msg2.reset(); 0367 0368 msg2.setSigners(privKeyList); 0369 msg2.startSign(QCA::SecureMessage::Message); 0370 msg2.update(testText); 0371 msg2.end(); 0372 msg2.waitForFinished(-1); 0373 QVERIFY(msg2.success()); 0374 QByteArray signedResult2 = msg2.read(); 0375 0376 QCOMPARE(signedResult2.isEmpty(), false); 0377 0378 QCA::CMS cms; 0379 QCA::Certificate caCert = 0380 QCA::Certificate::fromPEMFile(QStringLiteral("QcaTestRootCert.pem"), &res, provider); 0381 QCOMPARE(res, QCA::ConvertGood); 0382 0383 QCA::CertificateCollection caCertCollection; 0384 caCertCollection.addCertificate(caCert); 0385 0386 cms.setTrustedCertificates(caCertCollection); 0387 QCA::SecureMessage msg(&cms); 0388 QCOMPARE(msg.canClearsign(), false); 0389 QCOMPARE(msg.canSignAndEncrypt(), false); 0390 QCOMPARE(msg.type(), QCA::SecureMessage::CMS); 0391 0392 msg.startVerify(); 0393 msg.update(signedResult1); 0394 msg.end(); 0395 0396 msg.waitForFinished(-1); 0397 QVERIFY(msg.wasSigned()); 0398 QVERIFY(msg.success()); 0399 QVERIFY(msg.verifySuccess()); 0400 0401 msg.reset(); 0402 0403 msg.startVerify(); 0404 msg.update(signedResult2); 0405 msg.end(); 0406 0407 msg.waitForFinished(-1); 0408 QVERIFY(msg.wasSigned()); 0409 QVERIFY(msg.success()); 0410 QVERIFY(msg.verifySuccess()); 0411 0412 msg.reset(); 0413 0414 msg.startVerify(); 0415 msg.update(signedResult2); 0416 msg.end(); 0417 0418 msg.waitForFinished(-1); 0419 QVERIFY(msg.wasSigned()); 0420 QVERIFY(msg.success()); 0421 QCOMPARE(msg.verifySuccess(), true); 0422 } 0423 } 0424 } 0425 0426 void CMSut::signverify_message_invalid_data() 0427 { 0428 QTest::addColumn<QByteArray>("testText"); 0429 0430 QTest::newRow("empty") << QByteArray(""); 0431 QTest::newRow("0") << QByteArray("0"); 0432 QTest::newRow("07") << QByteArray("07899847jkjjfasjaJKJLJkljklj&kjlj;/**-+.01"); 0433 QTest::newRow("dubious") << QByteArray("~!#**$#&&%^@#^&()"); 0434 } 0435 0436 // This one tests Message format 0437 void CMSut::signverify_message_invalid() 0438 { 0439 QStringList providersToTest; 0440 providersToTest.append(QStringLiteral("qca-ossl")); 0441 0442 foreach (const QString provider, providersToTest) { 0443 if (!QCA::isSupported("cert", provider)) 0444 QWARN((QStringLiteral("Certificate not supported for ") + provider).toLocal8Bit().constData()); 0445 else if (!QCA::isSupported("cms", provider)) 0446 QWARN((QStringLiteral("CMS not supported for ") + provider).toLocal8Bit().constData()); 0447 else { 0448 QCA::ConvertResult res; 0449 QCA::SecureArray passPhrase = "start"; 0450 QCA::PrivateKey privKey = 0451 QCA::PrivateKey::fromPEMFile(QStringLiteral("QcaTestClientKey.pem"), passPhrase, &res, provider); 0452 QCOMPARE(res, QCA::ConvertGood); 0453 0454 QCA::Certificate pubCert = 0455 QCA::Certificate::fromPEMFile(QStringLiteral("QcaTestClientCert.pem"), &res, provider); 0456 QCOMPARE(res, QCA::ConvertGood); 0457 QCOMPARE(pubCert.isNull(), false); 0458 0459 QCA::CertificateChain chain; 0460 chain += pubCert; 0461 QCA::SecureMessageKey secMsgKey; 0462 secMsgKey.setX509CertificateChain(chain); 0463 secMsgKey.setX509PrivateKey(privKey); 0464 0465 QCA::SecureMessageKeyList privKeyList; 0466 privKeyList += secMsgKey; 0467 QCA::CMS cms2; 0468 cms2.setPrivateKeys(privKeyList); 0469 0470 QCA::SecureMessage msg2(&cms2); 0471 msg2.setSigners(privKeyList); 0472 QCOMPARE(msg2.canClearsign(), false); 0473 QCOMPARE(msg2.canSignAndEncrypt(), false); 0474 QCOMPARE(msg2.type(), QCA::SecureMessage::CMS); 0475 0476 QFETCH(QByteArray, testText); 0477 0478 msg2.startSign(QCA::SecureMessage::Message); 0479 msg2.update(testText); 0480 msg2.end(); 0481 msg2.waitForFinished(-1); 0482 QVERIFY(msg2.success()); 0483 QByteArray signedResult1 = msg2.read(); 0484 QCOMPARE(signedResult1.isEmpty(), false); 0485 0486 QCA::CMS cms; 0487 QCA::Certificate caCert = 0488 QCA::Certificate::fromPEMFile(QStringLiteral("QcaTestRootCert.pem"), &res, provider); 0489 QCOMPARE(res, QCA::ConvertGood); 0490 0491 QCA::CertificateCollection caCertCollection; 0492 caCertCollection.addCertificate(caCert); 0493 0494 cms.setTrustedCertificates(caCertCollection); 0495 QCA::SecureMessage msg(&cms); 0496 QCOMPARE(msg.canClearsign(), false); 0497 QCOMPARE(msg.canSignAndEncrypt(), false); 0498 QCOMPARE(msg.type(), QCA::SecureMessage::CMS); 0499 0500 // This is just to break things 0501 // signedResult1[30] = signedResult1[30] + 1; 0502 if (signedResult1.at(signedResult1.size() - 2) != 0) { 0503 signedResult1[signedResult1.size() - 2] = 0x00; 0504 } else { 0505 signedResult1[signedResult1.size() - 2] = 0x01; 0506 } 0507 0508 msg.startVerify(); 0509 msg.update(signedResult1); 0510 msg.end(); 0511 0512 msg.waitForFinished(-1); 0513 QVERIFY(msg.wasSigned()); 0514 QVERIFY(msg.success()); 0515 QCOMPARE(msg.verifySuccess(), false); 0516 } 0517 } 0518 } 0519 0520 QTEST_MAIN(CMSut) 0521 0522 #include "cms.moc"