177 lines
6.7 KiB
Diff
177 lines
6.7 KiB
Diff
From 797de4af8231945e1b3688b14719900d9fd0f09e Mon Sep 17 00:00:00 2001
|
|
From: BogDan Vatra <bogdan@kdab.com>
|
|
Date: Tue, 1 Nov 2016 17:53:29 +0200
|
|
Subject: [PATCH] Use apksigner by default if available to sign the APKs
|
|
|
|
apksigner is smart enough to know which techique to use to sign the apk
|
|
based on apk's manifest file.
|
|
|
|
People that really want to use jarsigner they need to pass --jarsigner
|
|
argument
|
|
|
|
Task-number: QTBUG-56702
|
|
Change-Id: I3acd26576c5b0b312d5f2424b1c0a52e48fb920e
|
|
---
|
|
src/androiddeployqt/main.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 109 insertions(+), 1 deletion(-)
|
|
|
|
diff --git x/qttools/src/androiddeployqt/main.cpp y/qttools/src/androiddeployqt/main.cpp
|
|
index c1fd130..fc1cb94 100644
|
|
--- x/qttools/src/androiddeployqt/main.cpp
|
|
+++ y/qttools/src/androiddeployqt/main.cpp
|
|
@@ -102,6 +102,7 @@ struct Options
|
|
, internalSf(false)
|
|
, sectionsOnly(false)
|
|
, protectedAuthenticationPath(false)
|
|
+ , jarSigner(false)
|
|
, gdbServer(Auto)
|
|
, installApk(false)
|
|
, uninstallApk(false)
|
|
@@ -181,6 +182,7 @@ struct Options
|
|
bool internalSf;
|
|
bool sectionsOnly;
|
|
bool protectedAuthenticationPath;
|
|
+ bool jarSigner;
|
|
|
|
// Gdbserver
|
|
TriState gdbServer;
|
|
@@ -446,6 +448,8 @@ Options parseOptions()
|
|
options.sectionsOnly = true;
|
|
} else if (argument.compare(QLatin1String("--protected"), Qt::CaseInsensitive) == 0) {
|
|
options.protectedAuthenticationPath = true;
|
|
+ } else if (argument.compare(QLatin1String("--jarsigner"), Qt::CaseInsensitive) == 0) {
|
|
+ options.jarSigner = true;
|
|
} else if (argument.compare(QLatin1String("--no-generated-assets-cache"), Qt::CaseInsensitive) == 0) {
|
|
options.generateAssetsFileList = false;
|
|
}
|
|
@@ -519,6 +523,8 @@ void printHelp()
|
|
" --internalsf: Include the .SF file inside the signature block.\n"
|
|
" --sectionsonly: Don't compute hash of entire manifest.\n"
|
|
" --protected: Keystore has protected authentication path.\n"
|
|
+ " --jarsigner: Force jarsigner usage, otherwise apksigner will be\n"
|
|
+ " used if available.\n"
|
|
" --gdbserver: Adds the gdbserver to the package. By default the gdbserver\n"
|
|
" is bundled for debug pacakges.\n"
|
|
" --no-gdbserver: Prevents the gdbserver from being added to the package\n"
|
|
@@ -2554,7 +2560,7 @@ bool copyGnuStl(Options *options)
|
|
return true;
|
|
}
|
|
|
|
-bool signPackage(const Options &options)
|
|
+bool jarSignerSignPackage(const Options &options)
|
|
{
|
|
if (options.verbose)
|
|
fprintf(stdout, "Signing Android package.\n");
|
|
@@ -2680,6 +2686,108 @@ bool signPackage(const Options &options)
|
|
return QFile::remove(apkPath(options, UnsignedAPK));
|
|
}
|
|
|
|
+bool signPackage(const Options &options)
|
|
+{
|
|
+ QString apksignerTool = options.sdkPath + QLatin1String("/build-tools/") + options.sdkBuildToolsVersion + QLatin1String("/apksigner");
|
|
+#if defined(Q_OS_WIN32)
|
|
+ apksignerTool += QLatin1String(".bat");
|
|
+#endif
|
|
+
|
|
+ if (options.jarSigner || !QFile::exists(apksignerTool))
|
|
+ return jarSignerSignPackage(options);
|
|
+
|
|
+ // APKs signed with apksigner must not be changed after they're signed, therefore we need to zipalign it before we sign it.
|
|
+
|
|
+ QString zipAlignTool = options.sdkPath + QLatin1String("/tools/zipalign");
|
|
+#if defined(Q_OS_WIN32)
|
|
+ zipAlignTool += QLatin1String(".exe");
|
|
+#endif
|
|
+
|
|
+ if (!QFile::exists(zipAlignTool)) {
|
|
+ zipAlignTool = options.sdkPath + QLatin1String("/build-tools/") + options.sdkBuildToolsVersion + QLatin1String("/zipalign");
|
|
+#if defined(Q_OS_WIN32)
|
|
+ zipAlignTool += QLatin1String(".exe");
|
|
+#endif
|
|
+ if (!QFile::exists(zipAlignTool)) {
|
|
+ fprintf(stderr, "zipalign tool not found: %s\n", qPrintable(zipAlignTool));
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ zipAlignTool = QString::fromLatin1("%1%2 -f 4 %3 %4")
|
|
+ .arg(shellQuote(zipAlignTool))
|
|
+ .arg(options.verbose ? QString::fromLatin1(" -v") : QString())
|
|
+ .arg(apkPath(options, UnsignedAPK))
|
|
+ .arg(apkPath(options, SignedAPK));
|
|
+
|
|
+ FILE *zipAlignCommand = openProcess(zipAlignTool);
|
|
+ if (zipAlignCommand == 0) {
|
|
+ fprintf(stderr, "Couldn't run zipalign.\n");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ char buffer[512];
|
|
+ while (fgets(buffer, sizeof(buffer), zipAlignCommand) != 0)
|
|
+ fprintf(stdout, "%s", buffer);
|
|
+
|
|
+ int errorCode = pclose(zipAlignCommand);
|
|
+ if (errorCode != 0) {
|
|
+ fprintf(stderr, "zipalign command failed.\n");
|
|
+ if (!options.verbose)
|
|
+ fprintf(stderr, " -- Run with --verbose for more information.\n");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ QString apkSignerCommandLine = QString::fromLatin1("%1 sign --ks %2")
|
|
+ .arg(shellQuote(apksignerTool)).arg(shellQuote(options.keyStore));
|
|
+
|
|
+ if (!options.keyStorePassword.isEmpty())
|
|
+ apkSignerCommandLine += QString::fromLatin1(" --ks-pass pass:%1").arg(shellQuote(options.keyStorePassword));
|
|
+
|
|
+ if (!options.keyStoreAlias.isEmpty())
|
|
+ apkSignerCommandLine += QString::fromLatin1(" --ks-key-alias %1").arg(shellQuote(options.keyStoreAlias));
|
|
+
|
|
+ if (!options.keyPass.isEmpty())
|
|
+ apkSignerCommandLine += QString::fromLatin1(" --key-pass pass:%1").arg(shellQuote(options.keyPass));
|
|
+
|
|
+ if (options.verbose)
|
|
+ apkSignerCommandLine += QLatin1String(" --verbose");
|
|
+
|
|
+ apkSignerCommandLine += QString::fromLatin1(" %1")
|
|
+ .arg(apkPath(options, SignedAPK));
|
|
+
|
|
+ auto apkSignerRunner = [&] {
|
|
+ FILE *apkSignerCommand = openProcess(apkSignerCommandLine);
|
|
+ if (apkSignerCommand == 0) {
|
|
+ fprintf(stderr, "Couldn't run apksigner.\n");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ char buffer[512];
|
|
+ while (fgets(buffer, sizeof(buffer), apkSignerCommand) != 0)
|
|
+ fprintf(stdout, "%s", buffer);
|
|
+
|
|
+ errorCode = pclose(apkSignerCommand);
|
|
+ if (errorCode != 0) {
|
|
+ fprintf(stderr, "apksigner command failed.\n");
|
|
+ if (!options.verbose)
|
|
+ fprintf(stderr, " -- Run with --verbose for more information.\n");
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+ };
|
|
+
|
|
+ // Sign the package
|
|
+ if (!apkSignerRunner())
|
|
+ return false;
|
|
+
|
|
+ apkSignerCommandLine = QString::fromLatin1("%1 verify --verbose %2")
|
|
+ .arg(shellQuote(apksignerTool)).arg(apkPath(options, SignedAPK));
|
|
+
|
|
+ // Verify the package and remove the unsigned apk
|
|
+ return apkSignerRunner() && QFile::remove(apkPath(options, UnsignedAPK));
|
|
+}
|
|
+
|
|
bool copyGdbServer(const Options &options)
|
|
{
|
|
if (options.verbose)
|
|
--
|
|
2.10.2
|
|
|