aheinecke@404: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik aheinecke@404: * Software engineering by Intevation GmbH aheinecke@404: * aheinecke@404: * This file is Free Software under the GNU GPL (v>=2) aheinecke@404: * and comes with ABSOLUTELY NO WARRANTY! aheinecke@404: * See LICENSE.txt for details. aheinecke@404: */ aheinecke@7: #include "certlistparsertest.h" aheinecke@7: #include "certificatelist.h" aheinecke@87: #include "certificate.h" aheinecke@240: #include "common.h" aheinecke@7: aheinecke@7: #include aheinecke@7: aheinecke@31: void CertListTest::testValidList() aheinecke@31: { andre@359: #ifdef RELEASE_BUILD andre@359: const char *fname = "list-valid-signed-release.txt"; andre@359: #else aheinecke@31: const char *fname = "list-valid-signed.txt"; andre@359: #endif aheinecke@88: aheinecke@88: QDir dataDir = QDir(SOURCE_DIR"/data/"); aheinecke@88: QString fileName = dataDir.absoluteFilePath(fname); aheinecke@88: QFile validList(fileName); aheinecke@87: validList.open(QIODevice::ReadOnly); aheinecke@87: QString validData = QString::fromLatin1(validList.readAll()); aheinecke@87: QStringList instLines; aheinecke@87: QStringList remoLines; aheinecke@87: aheinecke@31: CertificateList *certList = testWithFile(fname); aheinecke@87: QCOMPARE(certList->getStatus(), Valid); aheinecke@87: QVERIFY(certList->isValid()); aheinecke@87: aheinecke@87: QVERIFY(certList->rawData() == validData.toLatin1()); aheinecke@87: aheinecke@249: const QList cList = certList->getCertificates(); aheinecke@87: aheinecke@87: foreach (QString act, validData.split("\r\n")) { aheinecke@87: if (act.startsWith("I:")) { aheinecke@87: instLines << act; aheinecke@87: continue; aheinecke@87: } aheinecke@87: if (act.startsWith("R:")) { aheinecke@87: remoLines << act; aheinecke@87: continue; aheinecke@87: } aheinecke@87: } aheinecke@87: aheinecke@249: int instCnt = 0, aheinecke@249: remoCnt = 0; aheinecke@249: foreach (const Certificate& cert, cList) { aheinecke@87: QVERIFY(cert.isValid()); aheinecke@249: if (cert.isInstallCert()) { aheinecke@249: QVERIFY(instLines.contains(cert.base64Line())); aheinecke@249: instCnt++; aheinecke@249: } else { aheinecke@249: QVERIFY(remoLines.contains(cert.base64Line())); aheinecke@249: remoCnt++; aheinecke@249: } aheinecke@87: } aheinecke@87: aheinecke@87: /* Be variable if test data changes later */ aheinecke@249: QVERIFY(instCnt >= 1); aheinecke@249: QVERIFY(remoCnt >= 1); aheinecke@249: QVERIFY(instLines.size() == instCnt); aheinecke@249: QVERIFY(remoLines.size() == remoCnt); aheinecke@87: andre@204: /* Check that a default certificate is invalid */ aheinecke@95: Certificate cert; aheinecke@95: QVERIFY(!cert.isValid()); aheinecke@95: andre@203: certList->readList(fileName.toLocal8Bit().data()); andre@203: aheinecke@249: const QList cList2 = certList->getCertificates(); aheinecke@249: QVERIFY(instLines.size() + remoLines.size() == cList2.size()); aheinecke@87: aheinecke@31: delete certList; aheinecke@31: } aheinecke@7: aheinecke@7: void CertListTest::testInvalidSig() aheinecke@7: { aheinecke@42: const char *fnames[] = {"list-invalid-signed.txt", aheinecke@42: "list-valid-other-signature.txt", aheinecke@42: "list-valid-sha1-signature.txt", aheinecke@42: NULL}; aheinecke@42: for (int i=0; fnames[i] != NULL; i++) { aheinecke@42: CertificateList *certList = testWithFile(fnames[i]); aheinecke@42: QCOMPARE (certList->getStatus(), InvalidSignature); aheinecke@42: delete certList; aheinecke@42: } aheinecke@7: } aheinecke@7: aheinecke@7: void verifyInvalidFile(const char *fName) { aheinecke@7: CertificateList *certList = new CertificateList(fName); aheinecke@7: QVERIFY (certList->getStatus() != Valid); aheinecke@7: delete certList; aheinecke@7: } aheinecke@7: aheinecke@7: void CertListTest::testInvalidFileNames() aheinecke@7: { aheinecke@7: verifyInvalidFile("/dev/random"); aheinecke@7: verifyInvalidFile("/tmp/"); aheinecke@7: verifyInvalidFile(NULL); aheinecke@7: verifyInvalidFile("ä"); aheinecke@7: verifyInvalidFile("💩 "); aheinecke@7: } aheinecke@7: aheinecke@42: void CertListTest::testEmptyFile() aheinecke@42: { aheinecke@42: const char *fname = "empty_file"; aheinecke@42: CertificateList *certList = testWithFile(fname); aheinecke@95: QCOMPARE (certList->getStatus(), SeekFailed); aheinecke@42: delete certList; aheinecke@42: } aheinecke@42: aheinecke@7: void CertListTest::testGarbage() aheinecke@7: { andre@202: const char *fname = "list-with-null.txt"; andre@202: QString fname2 = getRandomDataFile(200); andre@202: CertificateList *certList = testWithFile(fname); andre@202: QCOMPARE (certList->getStatus(), InvalidFormat); andre@202: delete certList; andre@202: certList = testWithFile(fname2.toLocal8Bit().constData()); andre@202: QVERIFY(QFile::remove(fname2)); andre@202: QCOMPARE (certList->getStatus(), InvalidFormat); andre@202: delete certList; andre@202: } andre@202: aheinecke@7: void CertListTest::testTooLarge() aheinecke@7: { andre@202: QString fname = getRandomDataFile(MAX_LINE_LENGTH * MAX_LINES + 1); andre@202: CertificateList *certList = testWithFile(fname.toLocal8Bit().constData()); andre@202: QVERIFY(QFile::remove(fname)); andre@202: QCOMPARE(certList->getStatus(), TooLarge); andre@202: QVERIFY(!certList->isValid()); aheinecke@7: delete certList; aheinecke@7: } aheinecke@7: aheinecke@7: void CertListTest::benchmarkValid() aheinecke@7: { aheinecke@7: const char *fname = "list-valid-signed.txt"; aheinecke@7: aheinecke@88: QBENCHMARK{ aheinecke@7: CertificateList *certList = testWithFile(fname); aheinecke@7: delete certList; aheinecke@7: } aheinecke@7: } aheinecke@7: aheinecke@7: CertificateList* CertListTest::testWithFile(const char *filename) aheinecke@7: { aheinecke@7: QDir dataDir = QDir(SOURCE_DIR"/data/"); aheinecke@7: QString fileName = dataDir.absoluteFilePath(filename); aheinecke@7: return new CertificateList(fileName.toLocal8Bit().data()); aheinecke@7: } aheinecke@7: andre@351: void CertListTest::testCertificateFromFile() andre@351: { andre@351: QList result; andre@351: andre@351: /* Real certificates in the wild */ andre@351: result = Certificate::fromFileName(":/Intevation-Root-CA-2010.crt"); andre@351: QVERIFY(result.size() == 1); andre@351: QVERIFY(result[0].isValid()); andre@351: result = Certificate::fromFileName(":/Intevation-Root-CA-2010.der"); andre@351: QVERIFY(result.size() == 1); andre@351: QVERIFY(result[0].isValid()); andre@351: andre@351: /* We can handle ECC keys */ andre@351: result = Certificate::fromFileName(":/valid_ssl_bp.pem"); andre@351: QVERIFY(result.size() == 1); andre@351: QVERIFY(result[0].isValid()); andre@351: andre@351: /* Basic stuff */ andre@351: result = Certificate::fromFileName(":/valid_ssl_rsa.pem"); andre@351: QVERIFY(result.size() == 1); andre@351: QVERIFY(result[0].isValid()); andre@351: andre@351: /* Multiple certs */ andre@351: result = Certificate::fromFileName(":/import_test.pem"); andre@351: QVERIFY(result.size() == 15); andre@351: andre@351: QString lastCertB64; andre@351: foreach (const Certificate& cert, result) { andre@351: QVERIFY(cert.isValid()); andre@351: /* Just to verify that it's not all the same */ andre@351: QVERIFY(cert.base64Line() != lastCertB64); andre@351: lastCertB64 = cert.base64Line(); andre@351: } andre@351: andre@351: /* Some robustness */ andre@351: QString fname = getRandomDataFile(MAX_LINE_LENGTH * MAX_LINES - 100); andre@351: result = Certificate::fromFileName(fname); andre@351: QVERIFY(QFile::remove(fname)); andre@351: QVERIFY(result.isEmpty()); andre@351: } andre@1163: bool g_debug = true; andre@351: aheinecke@7: int main( int argc, char **argv ) aheinecke@7: { aheinecke@7: CertListTest tc; aheinecke@7: return QTest::qExec( &tc, argc, argv ); aheinecke@7: } aheinecke@7: aheinecke@7: