andre@636: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
andre@636:  * Software engineering by Intevation GmbH
andre@636:  *
andre@636:  * This file is Free Software under the GNU GPL (v>=2)
andre@636:  * and comes with ABSOLUTELY NO WARRANTY!
andre@636:  * See LICENSE.txt for details.
andre@636:  */
andre@636: #include "binverify.h"
andre@636: #include "binverifytest.h"
andre@869: #include "createinstallerdialog.h"
andre@869: #include "common.h"
andre@869: #include "mainwindow.h"
andre@636: 
andre@869: #include <QtTest>
andre@869: #include <QSettings>
andre@869: #include <QTemporaryFile>
andre@636: 
andre@636: #ifdef Q_OS_WIN
andre@636: # define EXE_SUFFIX ".exe"
andre@636: #else
andre@636: # define EXE_SUFFIX ""
andre@636: #endif
andre@636: 
andre@869: #ifdef Q_OS_WIN
andre@869:  Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
andre@869: #else
andre@869:  Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
andre@869: #endif
andre@869: 
andre@636: /* Some general robustness checks */
andre@636: void BinVerifyTest::testMiscErrors()
andre@636: {
andre@1081:   QVERIFY (verify_binary (NULL, 10).result != VerifyValid);
andre@1081:   QVERIFY (verify_binary ("foo", 10).result != VerifyValid);
andre@1081:   QVERIFY (verify_binary ("bar", -1).result!= VerifyValid);
andre@636:   /* On windows the next line will check that a valid microsoft
andre@636:    * signed executable is not valid for us (pinning). On linux
andre@637:    * it will just fail with a read error which we tested above */
andre@637: #ifdef Q_OS_WIN
andre@636:   QVERIFY (verify_binary ("c:\\Windows\\System32\\mmc.exe",
andre@1081:                           strlen("c:\\Windows\\System32\\mmc.exe")).result != VerifyInvalidCertificate);
andre@637: #endif
andre@1081:   QVERIFY (verify_binary ("/dev/null", strlen("/dev/null")).result != VerifyValid);
andre@636: }
andre@636: 
andre@637: /* Check that a signature with only a different key (of the same size)
andre@637:  * is not validated (Invalid signature because key and cert don't match)*/
andre@637: void BinVerifyTest::testOtherKey()
andre@637: {
andre@637:     QVERIFY(VerifyInvalidSignature == verify_binary ("fakeinst-other-key" EXE_SUFFIX,
andre@1081:                 strlen("fakeinst-other-key" EXE_SUFFIX)).result);
andre@637: }
andre@637: 
andre@637: /* Check that an invalid signature is not validated */
andre@637: void BinVerifyTest::testInvalidSig()
andre@637: {
andre@1081:     bin_verify_result res = verify_binary ("fakeinst-invalid" EXE_SUFFIX,
andre@1081:                 strlen("fakeinst-invalid" EXE_SUFFIX));
andre@1081:     QVERIFY(VerifyValid != res.result);
andre@1081:     QVERIFY(res.fptr == NULL);
andre@637: }
andre@637: 
andre@774: #ifdef Q_OS_WIN
andre@774: /* Check that a signature with a different (valid) certificate is not validated
andre@774:  * on Linux only the key is checked not the certificate */
andre@637: void BinVerifyTest::testOtherCert()
andre@637: {
andre@637:     QVERIFY(VerifyInvalidCertificate == verify_binary ("fakeinst-other-cert" EXE_SUFFIX,
andre@1081:                 strlen("fakeinst-other-cert" EXE_SUFFIX)).result);
andre@637: }
andre@774: #endif
andre@637: 
andre@636: /* Check that no signature is not validated */
andre@636: void BinVerifyTest::testNoSignature()
andre@636: {
andre@1081:     bin_verify_result res = verify_binary ("fakeinst" EXE_SUFFIX,
andre@1081:                 strlen("fakeinst" EXE_SUFFIX));
andre@1081:     QVERIFY(VerifyValid != res.result);
andre@1081:     QVERIFY(res.fptr == NULL);
andre@636: }
andre@636: 
andre@636: /* Check that a valid signed executable is verified */
andre@636: void BinVerifyTest::testValidBinary()
andre@636: {
andre@1081:     bin_verify_result res = verify_binary ("fakeinst-signed" EXE_SUFFIX,
andre@1081:                                           strlen("fakeinst-signed" EXE_SUFFIX));
andre@1081:     QVERIFY (VerifyValid == res.result);
andre@1081:     QFile thefile ("fakeinst-signed" EXE_SUFFIX);
andre@1081: #ifdef WIN32
andre@1081:     /* Verifies the deny write open mode. But on linuy we dont have it. */
andre@1081:     QVERIFY (!thefile.open(QIODevice::ReadWrite));
andre@1081: #endif
andre@1081:     QVERIFY (res.fptr != NULL);
andre@1081:     fclose(res.fptr);
andre@1081:     QVERIFY (thefile.open(QIODevice::ReadWrite));
andre@1081:     thefile.close();
andre@636: }
andre@636: 
andre@869: void BinVerifyTest::testSignatureCreation()
andre@869: {
andre@869:   QSettings testsettings;
andre@869:   testsettings.setValue("CodeSignCert", SOURCE_DIR"/data/codesign/codesigning-combined.pem");
andre@869:   testsettings.sync();
andre@869:   CreateInstallerDialog *theDialog = new CreateInstallerDialog(NULL);
andre@869:   QString garbage = getRandomDataFile(21*1024*1024);
andre@869:   QTemporaryFile outfile;
andre@869:   outfile.open();
andre@869:   outfile.close();
andre@869:   bool ret = theDialog->appendTextSignatureToFile (garbage, outfile.fileName());
andre@869:   QVERIFY(QFile::remove(garbage));
andre@869:   QVERIFY(ret == true);
andre@1081:   bin_verify_result res = verify_binary (outfile.fileName().toUtf8().constData(),
andre@1081:                                         outfile.fileName().toUtf8().size());
andre@1081:   QVERIFY(VerifyValid == res.result);
andre@869: }
andre@1060: bool g_debug = true;
andre@869: 
andre@869: QTEST_MAIN (BinVerifyTest);