summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Griebl <robert.griebl@pelagicore.com>2018-08-02 17:45:42 +0200
committerRobert Griebl <robert.griebl@pelagicore.com>2018-08-03 12:37:35 +0000
commitd16409c723495cef98ab691de5e03b87a7596038 (patch)
tree7d15a06b63919e1ef4e07ae3703ce56680823d33
parent580e5eac4dadfd96b591b81e4af3bf072bcb461a (diff)
Fix store-signed packages
There were multiple bugs in the way store signatures were created and verified. This patch should fix all issues, plus it adds auto-tests to catch regressions going forward. Change-Id: I903bcc7d2dc485b5ed4ee7448d1f1e1ac8242c29 Reviewed-by: Bernd Weimer <bernd.weimer@pelagicore.com>
-rw-r--r--doc/configuration.qdoc5
-rw-r--r--doc/installer.qdoc2
-rw-r--r--doc/packager.qdoc4
-rw-r--r--src/installer-lib/applicationinstaller.cpp16
-rw-r--r--src/installer-lib/applicationinstaller.h5
-rw-r--r--src/installer-lib/applicationinstaller_p.h1
-rw-r--r--src/installer-lib/installationtask.cpp15
-rw-r--r--src/main-lib/defaultconfiguration.cpp6
-rw-r--r--src/main-lib/defaultconfiguration.h1
-rw-r--r--src/main-lib/main.cpp7
-rw-r--r--src/main-lib/main.h1
-rw-r--r--src/tools/packager/packager.cpp2
-rw-r--r--src/tools/packager/packagingjob.cpp14
-rw-r--r--tests/applicationinstaller/tst_applicationinstaller.cpp96
-rwxr-xr-xtests/data/certificates/create-test-certificates.sh2
-rwxr-xr-xtests/data/create-test-packages.sh6
-rw-r--r--tests/packager-tool/tst_packager-tool.cpp2
17 files changed, 138 insertions, 47 deletions
diff --git a/doc/configuration.qdoc b/doc/configuration.qdoc
index 841725b9..b2941c69 100644
--- a/doc/configuration.qdoc
+++ b/doc/configuration.qdoc
@@ -254,6 +254,11 @@ all your imports paths and file references relative to your main config file.
\li bool
\li Disables all security related checks. Use this in a development setup only! (default: false)
\row
+ \li \b --development-mode
+ \br \e flags/developmentMode
+ \li bool
+ \li Allows the installation of packages that only come with a valid developer signature. (default: false)
+\row
\li \b --no-ui-watchdog
\br \e flags/noUiWatchdog
\li bool
diff --git a/doc/installer.qdoc b/doc/installer.qdoc
index d1474c6a..5094c2d1 100644
--- a/doc/installer.qdoc
+++ b/doc/installer.qdoc
@@ -85,7 +85,7 @@ If you want to make use of signed packages, you need to setup a public key infra
support this. You need:
\list
- \li A \e {Developer CA} which is responsible for creating certicates that are distributed
+ \li A \e {Developer CA} which is responsible for creating certificates that are distributed
to developers in P12 format. The developers use these certificates to developer-sign their
packages (using the Packager tool), before submitting to an app-store.
\li An \e {App-Store CA} which is responsible for creating certificates that are used
diff --git a/doc/packager.qdoc b/doc/packager.qdoc
index 2f71cbbd..853df484 100644
--- a/doc/packager.qdoc
+++ b/doc/packager.qdoc
@@ -116,10 +116,10 @@ developer only (development mode), and packages that are signed by a trusted app
\c{<password>}
- \c{[device-id]}
+ \c{<device-id>}
\li Takes the input \c package, adds a store signature and writes the output to \c signed-package.
You need to supply a \c certificate in P12 format together with a \c password matching the
- certificate. If you specify the optional \c device-id, the resulting package can only be
+ certificate. If you don't leave the \c device-id empty, the resulting package can only be
installed on this specific device. The following options are supported:
\c{--verbose}: Dump the package's meta-data header and footer information to stdout.
diff --git a/src/installer-lib/applicationinstaller.cpp b/src/installer-lib/applicationinstaller.cpp
index 94190a41..a8b24281 100644
--- a/src/installer-lib/applicationinstaller.cpp
+++ b/src/installer-lib/applicationinstaller.cpp
@@ -167,7 +167,7 @@
for this \a taskId, to either cancel the installation or try to complete it.
The ApplicationInstaller has two convenience functions to help the System-UI with verifying the
- meta-data: versionCompare() and, in case you are using reverse-DNS notation for application-ids,
+ meta-data: compareVersions() and, in case you are using reverse-DNS notation for application-ids,
validateDnsName().
\sa taskStateChanged(), startPackageInstallation()
@@ -197,13 +197,14 @@ ApplicationInstaller *ApplicationInstaller::s_instance = nullptr;
ApplicationInstaller::ApplicationInstaller(const QVector<InstallationLocation> &installationLocations,
const QDir &manifestDir, const QDir &imageMountDir,
- QObject *parent)
+ const QString &hardwareId, QObject *parent)
: QObject(parent)
, d(new ApplicationInstallerPrivate())
{
d->installationLocations = installationLocations;
d->manifestDir = manifestDir;
d->imageMountDir = imageMountDir;
+ d->hardwareId = hardwareId;
}
ApplicationInstaller::~ApplicationInstaller()
@@ -213,7 +214,8 @@ ApplicationInstaller::~ApplicationInstaller()
}
ApplicationInstaller *ApplicationInstaller::createInstance(const QVector<InstallationLocation> &installationLocations,
- const QDir &manifestDir, const QDir &imageMountDir, QString *error)
+ const QDir &manifestDir, const QDir &imageMountDir,
+ const QString &hardwareId, QString *error)
{
if (Q_UNLIKELY(s_instance))
qFatal("ApplicationInstaller::createInstance() was called a second time.");
@@ -235,7 +237,8 @@ ApplicationInstaller *ApplicationInstaller::createInstance(const QVector<Install
qmlRegisterSingletonType<ApplicationInstaller>("QtApplicationManager", 1, 0, "ApplicationInstaller",
&ApplicationInstaller::instanceForQml);
- return s_instance = new ApplicationInstaller(installationLocations, manifestDir, imageMountDir, QCoreApplication::instance());
+ return s_instance = new ApplicationInstaller(installationLocations, manifestDir, imageMountDir,
+ hardwareId, QCoreApplication::instance());
}
ApplicationInstaller *ApplicationInstaller::instance()
@@ -271,6 +274,11 @@ void ApplicationInstaller::setAllowInstallationOfUnsignedPackages(bool b)
d->allowInstallationOfUnsignedPackages = b;
}
+QString ApplicationInstaller::hardwareId() const
+{
+ return d->hardwareId;
+}
+
bool ApplicationInstaller::isApplicationUserIdSeparationEnabled() const
{
return d->userIdSeparation;
diff --git a/src/installer-lib/applicationinstaller.h b/src/installer-lib/applicationinstaller.h
index 1a3e54ba..c82c30af 100644
--- a/src/installer-lib/applicationinstaller.h
+++ b/src/installer-lib/applicationinstaller.h
@@ -79,7 +79,7 @@ public:
~ApplicationInstaller();
static ApplicationInstaller *createInstance(const QVector<InstallationLocation> &installationLocations,
- const QDir &manifestDir, const QDir &imageMountDir,
+ const QDir &manifestDir, const QDir &imageMountDir, const QString &hardwareId,
QString *error);
static ApplicationInstaller *instance();
static QObject *instanceForQml(QQmlEngine *qmlEngine, QJSEngine *);
@@ -88,6 +88,7 @@ public:
void setDevelopmentMode(bool b);
bool allowInstallationOfUnsignedPackages() const;
void setAllowInstallationOfUnsignedPackages(bool b);
+ QString hardwareId() const;
bool isApplicationUserIdSeparationEnabled() const;
uint commonApplicationGroupId() const;
@@ -170,7 +171,7 @@ private:
private:
ApplicationInstaller(const QVector<InstallationLocation> &installationLocations, const QDir &manifestDir,
- const QDir &imageMountDir, QObject *parent);
+ const QDir &imageMountDir, const QString &hardwareId, QObject *parent);
ApplicationInstaller(const ApplicationInstaller &);
static ApplicationInstaller *s_instance;
diff --git a/src/installer-lib/applicationinstaller_p.h b/src/installer-lib/applicationinstaller_p.h
index 7db32049..88f51b74 100644
--- a/src/installer-lib/applicationinstaller_p.h
+++ b/src/installer-lib/applicationinstaller_p.h
@@ -71,6 +71,7 @@ public:
QString error;
+ QString hardwareId;
QList<QByteArray> chainOfTrust;
QQueue<AsynchronousTask *> taskQueue;
diff --git a/src/installer-lib/installationtask.cpp b/src/installer-lib/installationtask.cpp
index 5ab9bfd5..29f68929 100644
--- a/src/installer-lib/installationtask.cpp
+++ b/src/installer-lib/installationtask.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <QTemporaryDir>
+#include <QMessageAuthenticationCode>
#include "logging.h"
#include "applicationinstaller_p.h"
@@ -217,9 +218,19 @@ void InstallationTask::execute()
if (ApplicationManager::instance()->securityChecksEnabled()) {
if (!m_extractor->installationReport().storeSignature().isEmpty()) {
// normal package from the store
- if (!Signature(m_extractor->installationReport().digest()).verify(m_extractor->installationReport().storeSignature(), chainOfTrust))
+ QByteArray sigDigest = m_extractor->installationReport().digest();
+ bool sigOk = false;
+
+ if (Signature(sigDigest).verify(m_extractor->installationReport().storeSignature(), chainOfTrust)) {
+ sigOk = true;
+ } else if (!m_ai->hardwareId().isEmpty()) {
+ // did not verify - if we have a hardware-id, try to verify with it
+ sigDigest = QMessageAuthenticationCode::hash(sigDigest, m_ai->hardwareId().toUtf8(), QCryptographicHash::Sha256);
+ if (Signature(sigDigest).verify(m_extractor->installationReport().storeSignature(), chainOfTrust))
+ sigOk = true;
+ }
+ if (!sigOk)
throw Exception(Error::Package, "could not verify the package's store signature");
-
} else if (!m_extractor->installationReport().developerSignature().isEmpty()) {
// developer package - needs a device in dev mode
if (!m_ai->developmentMode())
diff --git a/src/main-lib/defaultconfiguration.cpp b/src/main-lib/defaultconfiguration.cpp
index c6e3a1c9..28492d79 100644
--- a/src/main-lib/defaultconfiguration.cpp
+++ b/src/main-lib/defaultconfiguration.cpp
@@ -108,6 +108,7 @@ DefaultConfiguration::DefaultConfiguration(const QStringList &defaultConfigFileP
m_clp.addOption({ qSL("slow-animations"), qSL("run all animations in slow motion.") });
m_clp.addOption({ qSL("load-dummydata"), qSL("loads QML dummy-data.") });
m_clp.addOption({ qSL("no-security"), qSL("disables all security related checks (dev only!)") });
+ m_clp.addOption({ qSL("development-mode"), qSL("enable development mode, allowing installation of dev-signed packages.") });
m_clp.addOption({ qSL("no-ui-watchdog"), qSL("disables detecting hung UI applications (e.g. via Wayland's ping/pong).") });
m_clp.addOption({ qSL("no-dlt-logging"), qSL("disables logging using automotive DLT.") });
m_clp.addOption({ qSL("force-single-process"), qSL("forces single-process mode even on a wayland enabled build.") });
@@ -213,6 +214,11 @@ bool DefaultConfiguration::noSecurity() const
return value<bool>("no-security", { "flags", "noSecurity" });
}
+bool DefaultConfiguration::developmentMode() const
+{
+ return value<bool>("development-mode", { "flags", "developmentMode" });
+}
+
bool DefaultConfiguration::noUiWatchdog() const
{
return value<bool>("no-ui-watchdog", { "flags", "noUiWatchdog" });
diff --git a/src/main-lib/defaultconfiguration.h b/src/main-lib/defaultconfiguration.h
index 884bc253..2b2f4bbe 100644
--- a/src/main-lib/defaultconfiguration.h
+++ b/src/main-lib/defaultconfiguration.h
@@ -75,6 +75,7 @@ public:
bool slowAnimations() const;
bool loadDummyData() const;
bool noSecurity() const;
+ bool developmentMode() const;
bool noUiWatchdog() const;
bool noDltLogging() const;
bool forceSingleProcess() const;
diff --git a/src/main-lib/main.cpp b/src/main-lib/main.cpp
index 3b4faa0e..37f3682d 100644
--- a/src/main-lib/main.cpp
+++ b/src/main-lib/main.cpp
@@ -189,6 +189,7 @@ void Main::setup(const DefaultConfiguration *cfg, const QStringList &deploymentW
{
// basics that are needed in multiple setup functions below
m_noSecurity = cfg->noSecurity();
+ m_developmentMode = cfg->developmentMode();
m_builtinAppsManifestDirs = cfg->builtinAppsManifestDirs();
m_installedAppsManifestDir = cfg->installedAppsManifestDir();
@@ -501,11 +502,15 @@ void Main::setupInstaller(const QString &appImageMountDir, const QStringList &ca
m_applicationInstaller = ApplicationInstaller::createInstance(m_installationLocations,
m_installedAppsManifestDir,
appImageMountDir,
+ hardwareId(),
&error);
if (Q_UNLIKELY(!m_applicationInstaller))
throw Exception(Error::System, error);
- if (m_noSecurity) {
+
+ if (m_developmentMode)
m_applicationInstaller->setDevelopmentMode(true);
+
+ if (m_noSecurity) {
m_applicationInstaller->setAllowInstallationOfUnsignedPackages(true);
} else {
QList<QByteArray> caCertificateList;
diff --git a/src/main-lib/main.h b/src/main-lib/main.h
index d07aa695..675ece9c 100644
--- a/src/main-lib/main.h
+++ b/src/main-lib/main.h
@@ -170,6 +170,7 @@ private:
QVector<QVariantMap> m_systemProperties;
bool m_noSecurity = false;
+ bool m_developmentMode = false;
QStringList m_builtinAppsManifestDirs;
QString m_installedAppsManifestDir;
};
diff --git a/src/tools/packager/packager.cpp b/src/tools/packager/packager.cpp
index b237cc99..d6b3a830 100644
--- a/src/tools/packager/packager.cpp
+++ b/src/tools/packager/packager.cpp
@@ -265,7 +265,7 @@ int main(int argc, char *argv[])
clp.showHelp(1);
p = PackagingJob::storeVerify(clp.positionalArguments().at(1),
- clp.positionalArguments().mid(2, clp.positionalArguments().size() - 2),
+ clp.positionalArguments().mid(2, clp.positionalArguments().size() - 3),
*--clp.positionalArguments().cend());
break;
}
diff --git a/src/tools/packager/packagingjob.cpp b/src/tools/packager/packagingjob.cpp
index 66ef4336..d0e1a8c8 100644
--- a/src/tools/packager/packagingjob.cpp
+++ b/src/tools/packager/packagingjob.cpp
@@ -261,8 +261,11 @@ void PackagingJob::execute() Q_DECL_NOEXCEPT_EXPR(false)
m_output = qSL("no store signature");
m_resultCode = 1;
} else {
- QByteArray digestPlusId = QMessageAuthenticationCode::hash(report.digest(), m_hardwareId.toUtf8(), QCryptographicHash::Sha256);
- Signature sig(digestPlusId);
+ QByteArray sigDigest = report.digest();
+ if (!m_hardwareId.isEmpty())
+ sigDigest = QMessageAuthenticationCode::hash(sigDigest, m_hardwareId.toUtf8(), QCryptographicHash::Sha256);
+
+ Signature sig(sigDigest);
if (!sig.verify(report.storeSignature(), certificates)) {
m_output = qSL("invalid store signature (") + sig.errorString() + qSL(")");
m_resultCode = 2;
@@ -295,8 +298,11 @@ void PackagingJob::execute() Q_DECL_NOEXCEPT_EXPR(false)
throw Exception(Error::Package, "could not create signature: %1").arg(sig.errorString());
report.setDeveloperSignature(signature);
} else if (m_mode == StoreSign) {
- QByteArray digestPlusId = QMessageAuthenticationCode::hash(report.digest(), m_hardwareId.toUtf8(), QCryptographicHash::Sha256);
- Signature sig(digestPlusId);
+ QByteArray sigDigest = report.digest();
+ if (!m_hardwareId.isEmpty())
+ sigDigest = QMessageAuthenticationCode::hash(sigDigest, m_hardwareId.toUtf8(), QCryptographicHash::Sha256);
+
+ Signature sig(sigDigest);
QByteArray signature = sig.create(certificates.first(), m_passphrase.toUtf8());
if (signature.isEmpty())
diff --git a/tests/applicationinstaller/tst_applicationinstaller.cpp b/tests/applicationinstaller/tst_applicationinstaller.cpp
index b4f08dab..259a7575 100644
--- a/tests/applicationinstaller/tst_applicationinstaller.cpp
+++ b/tests/applicationinstaller/tst_applicationinstaller.cpp
@@ -59,20 +59,42 @@ static QString sudoServerError;
static int spyTimeout = 5000; // shorthand for specifying QSignalSpy timeouts
// RAII to reset the global attribute
-class AllowUnsignedInstallation
+class AllowInstallations
{
public:
- AllowUnsignedInstallation(bool b = true)
- : m_old(ApplicationInstaller::instance()->allowInstallationOfUnsignedPackages())
+ enum Type {
+ AllowUnsinged,
+ RequireDevSigned,
+ RequireStoreSigned
+ };
+
+ AllowInstallations(Type t)
+ : m_oldUnsigned(ApplicationInstaller::instance()->allowInstallationOfUnsignedPackages())
+ , m_oldDevMode(ApplicationInstaller::instance()->developmentMode())
{
- ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(b);
+ switch (t) {
+ case AllowUnsinged:
+ ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(true);
+ ApplicationInstaller::instance()->setDevelopmentMode(false);
+ break;
+ case RequireDevSigned:
+ ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(false);
+ ApplicationInstaller::instance()->setDevelopmentMode(true);
+ break;
+ case RequireStoreSigned:
+ ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(false);
+ ApplicationInstaller::instance()->setDevelopmentMode(false);
+ break;
+ }
}
- ~AllowUnsignedInstallation()
+ ~AllowInstallations()
{
- ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(m_old);
+ ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(m_oldUnsigned);
+ ApplicationInstaller::instance()->setDevelopmentMode(m_oldDevMode);
}
private:
- bool m_old;
+ bool m_oldUnsigned;
+ bool m_oldDevMode;
};
class tst_ApplicationInstaller : public QObject
@@ -359,7 +381,7 @@ void tst_ApplicationInstaller::initTestCase()
// finally, instantiate the ApplicationInstaller and a bunch of signal-spies for its signals
QString installerError;
- m_ai = ApplicationInstaller::createInstance(m_installationLocations, pathTo(Manifests), pathTo(ImageMounts), &installerError);
+ m_ai = ApplicationInstaller::createInstance(m_installationLocations, pathTo(Manifests), pathTo(ImageMounts), m_hardwareId, &installerError);
QVERIFY2(m_ai, qPrintable(installerError));
m_startedSpy = new QSignalSpy(m_ai, &ApplicationInstaller::taskStarted);
@@ -374,9 +396,11 @@ void tst_ApplicationInstaller::initTestCase()
// crypto stuff - we need to load the root CA and developer CA certificates
QFile devcaFile(AM_TESTDATA_DIR "certificates/devca.crt");
+ QFile storecaFile(AM_TESTDATA_DIR "certificates/store.crt");
QFile caFile(AM_TESTDATA_DIR "certificates/ca.crt");
QVERIFY2(devcaFile.open(QIODevice::ReadOnly), qPrintable(devcaFile.errorString()));
- QVERIFY2(caFile.open(QIODevice::ReadOnly), qPrintable(devcaFile.errorString()));
+ QVERIFY2(storecaFile.open(QIODevice::ReadOnly), qPrintable(storecaFile.errorString()));
+ QVERIFY2(caFile.open(QIODevice::ReadOnly), qPrintable(caFile.errorString()));
QList<QByteArray> chainOfTrust;
chainOfTrust << devcaFile.readAll() << caFile.readAll();
@@ -547,6 +571,7 @@ void tst_ApplicationInstaller::packageInstallation_data()
QTest::addColumn<QString>("updatePackageName");
QTest::addColumn<QString>("updateInstallationLocationId");
QTest::addColumn<bool>("devSigned");
+ QTest::addColumn<bool>("storeSigned");
QTest::addColumn<bool>("expectedSuccess");
QTest::addColumn<bool>("updateExpectedSuccess");
QTest::addColumn<QVariantMap>("extraMetaData");
@@ -569,59 +594,71 @@ void tst_ApplicationInstaller::packageInstallation_data()
QTest::newRow("normal") \
<< "test.appkg" << "internal-0" << "test-update.appkg" << "internal-0"
- << false << true << true << nomd<< "";
+ << false << false << true << true << nomd<< "";
+ QTest::newRow("no-dev-signed") \
+ << "test.appkg" << "internal-0" << "" << ""
+ << true << false << false << false << nomd << "cannot install unsigned packages";
QTest::newRow("dev-signed") \
<< "test-dev-signed.appkg" << "internal-0" << "test-update-dev-signed.appkg" << "internal-0"
- << true << true << true << nomd << "";
+ << true << false << true << true << nomd << "";
+ QTest::newRow("no-store-signed") \
+ << "test.appkg" << "internal-0" << "" << ""
+ << false << true << false << false << nomd << "cannot install unsigned packages";
+ QTest::newRow("no-store-but-dev-signed") \
+ << "test-dev-signed.appkg" << "internal-0" << "" << ""
+ << false << true << false << false << nomd << "cannot install development packages on consumer devices";
+ QTest::newRow("store-signed") \
+ << "test-store-signed.appkg" << "internal-0" << "" << ""
+ << false << true << true << false << nomd << "";
QTest::newRow("extra-metadata") \
<< "test-extra.appkg" << "internal-0" << "" << ""
- << false << true << false << extramd << "";
+ << false << false << true << false << extramd << "";
QTest::newRow("extra-metadata-dev-signed") \
<< "test-extra-dev-signed.appkg" << "internal-0" << "" << ""
- << true << true << false << extramd << "";
+ << true << false << true << false << extramd << "";
QTest::newRow("update-to-different-location") \
<< "test.appkg" << "internal-0" << "test-update.appkg" << "internal-1"
- << false << true << false << nomd << "the application com.pelagicore.test cannot be installed to internal-1, since it is already installed to internal-0";
+ << false << false << true << false << nomd << "the application com.pelagicore.test cannot be installed to internal-1, since it is already installed to internal-0";
QTest::newRow("invalid-location") \
<< "test.appkg" << "internal-42" << "" << ""
- << false << false << false << nomd << "invalid installation location";
+ << false << false << false << false << nomd << "invalid installation location";
QTest::newRow("invalid-file-order") \
<< "test-invalid-file-order.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "could not find info.yaml and icon.png at the beginning of the package";
+ << false << false << false << false << nomd << "could not find info.yaml and icon.png at the beginning of the package";
QTest::newRow("invalid-header-format") \
<< "test-invalid-header-formatversion.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "metadata has an invalid format specification: wrong formatVersion header: expected 1, got 2";
+ << false << false << false << false << nomd << "metadata has an invalid format specification: wrong formatVersion header: expected 1, got 2";
QTest::newRow("invalid-header-diskspaceused") \
<< "test-invalid-header-diskspaceused.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "metadata has an invalid diskSpaceUsed field (0)";
+ << false << false << false << false << nomd << "metadata has an invalid diskSpaceUsed field (0)";
QTest::newRow("invalid-header-id") \
<< "test-invalid-header-id.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "metadata has an invalid applicationId field (:invalid)";
+ << false << false << false << false << nomd << "metadata has an invalid applicationId field (:invalid)";
QTest::newRow("non-matching-header-id") \
<< "test-non-matching-header-id.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "the application identifiers in --PACKAGE-HEADER--' and info.yaml do not match";
+ << false << false << false << false << nomd << "the application identifiers in --PACKAGE-HEADER--' and info.yaml do not match";
QTest::newRow("tampered-extra-signed-header") \
<< "test-tampered-extra-signed-header.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "~package digest mismatch.*";
+ << false << false << false << false << nomd << "~package digest mismatch.*";
QTest::newRow("invalid-info.yaml") \
<< "test-invalid-info.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "~.*YAML parse error at line \\d+, column \\d+: did not find expected key";
+ << false << false << false << false << nomd << "~.*YAML parse error at line \\d+, column \\d+: did not find expected key";
QTest::newRow("invalid-info.yaml-id") \
<< "test-invalid-info-id.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "~.*the identifier \\(:invalid\\) is not a valid application-id: must consist of printable ASCII characters only, except any of .*";
+ << false << false << false << false << nomd << "~.*the identifier \\(:invalid\\) is not a valid application-id: must consist of printable ASCII characters only, except any of .*";
QTest::newRow("invalid-footer-signature") \
<< "test-invalid-footer-signature.appkg" << "internal-0" << "" << ""
- << false << false << false << nomd << "could not verify the package's developer signature";
+ << true << false << false << false << nomd << "could not verify the package's developer signature";
#ifdef Q_OS_LINUX
QTest::newRow("sdcard") \
<< "test.appkg" << "removable-0" << "test-update.appkg" << "removable-0"
- << false << true << true << nomd << "";
+ << false << false << true << true << nomd << "";
QTest::newRow("sdcard-dev-signed") \
<< "test-dev-signed.appkg" << "removable-0" << "test-update-dev-signed.appkg" << "removable-0"
- << true << true << true << nomd << "";
+ << true << false << true << true << nomd << "";
QTest::newRow("sdcard-no-space") \
<< "bigtest-dev-signed.appkg" << "removable-0" << "" << ""
- << true << false << false << nomd << "~not enough storage space left on removable-0: [0-9.]+ MB available, but [0-9.]+ MB needed";
+ << true << false << false << false << nomd << "~not enough storage space left on removable-0: [0-9.]+ MB available, but [0-9.]+ MB needed";
#endif
}
@@ -635,6 +672,7 @@ void tst_ApplicationInstaller::packageInstallation()
QFETCH(QString, updatePackageName);
QFETCH(QString, updateInstallationLocationId);
QFETCH(bool, devSigned);
+ QFETCH(bool, storeSigned);
QFETCH(bool, expectedSuccess);
QFETCH(bool, updateExpectedSuccess);
QFETCH(QVariantMap, extraMetaData);
@@ -645,7 +683,9 @@ void tst_ApplicationInstaller::packageInstallation()
QSKIP("no removable installation locations on this platform");
#endif
- AllowUnsignedInstallation allow(!devSigned);
+ AllowInstallations allow(storeSigned ? AllowInstallations::RequireStoreSigned
+ : (devSigned ? AllowInstallations::RequireDevSigned
+ : AllowInstallations::AllowUnsinged));
int lastPass = (updatePackageName.isEmpty() ? 1 : 2);
// pass 1 is the installation / pass 2 is the update (if needed)
diff --git a/tests/data/certificates/create-test-certificates.sh b/tests/data/certificates/create-test-certificates.sh
index c7ab2b78..3bc69874 100755
--- a/tests/data/certificates/create-test-certificates.sh
+++ b/tests/data/certificates/create-test-certificates.sh
@@ -100,7 +100,7 @@ runSSL req -batch -subj '/C=DE/ST=Foo/L=Bar/CN=www.other.com' -newkey rsa:2048 -
runSSL ca -batch -config openssl-other-ca.cnf -policy signing_policy -extensions signing_req -out other.crt -infiles other.csr
runSSL pkcs12 -export -out other.p12 -password pass:password -inkey other-priv.key -nodes -certfile other-ca.crt -in other.crt -name "Other Certificate"
-echo -e "$G All test certificated have been created successfully$W"
+echo -e "$G All test certificates have been created successfully$W"
echo
exit 0
diff --git a/tests/data/create-test-packages.sh b/tests/data/create-test-packages.sh
index 109defd9..5c4d16f5 100755
--- a/tests/data/create-test-packages.sh
+++ b/tests/data/create-test-packages.sh
@@ -101,6 +101,12 @@ packager create-package "$dst/test.appkg" "$src"
info "Dev-sign package"
packager dev-sign-package "$dst/test.appkg" "$dst/test-dev-signed.appkg" certificates/dev1.p12 password
+info "Store-sign package"
+packager store-sign-package "$dst/test.appkg" "$dst/test-store-signed.appkg" certificates/store.p12 password "foobar"
+
+info "Store-sign dev package"
+packager store-sign-package "$dst/test-dev-signed.appkg" "$dst/test-store-dev-signed.appkg" certificates/store.p12 password "foobar"
+
info "Create package with extra meta-data"
cat >"$tmp/exmd" <<EOT
array:
diff --git a/tests/packager-tool/tst_packager-tool.cpp b/tests/packager-tool/tst_packager-tool.cpp
index 0546cffe..bed5c5d3 100644
--- a/tests/packager-tool/tst_packager-tool.cpp
+++ b/tests/packager-tool/tst_packager-tool.cpp
@@ -104,7 +104,7 @@ void tst_PackagerTool::initTestCase()
QVector<InstallationLocation> locations = InstallationLocation::parseInstallationLocations({ internalLocation }, m_hardwareId);
QString errorString;
- m_ai = ApplicationInstaller::createInstance(locations, pathTo("manifests"), pathTo("image-mounts"), &errorString);
+ m_ai = ApplicationInstaller::createInstance(locations, pathTo("manifests"), pathTo("image-mounts"), m_hardwareId, &errorString);
QVERIFY2(m_ai, qPrintable(errorString));
QVERIFY2(ApplicationManager::createInstance(nullptr, true, &errorString), qPrintable(errorString));