[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#859654: unblock android-platform-tools-apksig/0.5+git168_g10c9d71-1



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package: android-platform-tools-apksig

This is the next upstream release, which only fixes the eToken/HSM issues
as described in #859541.  Upstream still doesn't have release tags,
hence the version string.  I took this opportunity to include the
bash-completion to the package as well, for completeness.

Attached is the debdiff.

diff --git a/debian/README.source b/debian/README.source
new file mode 100644
index 0000000..7d97b6e
--- /dev/null
+++ b/debian/README.source
@@ -0,0 +1,25 @@
+
+This package is normally built as part of the whole Android SDK and
+ends up being included in the "build-tools" package.  So the release
+tags will match all of the various android-platform-* packages.  To
+make this extra confusing, they also publish a standalone JAR library
+of this project with a separate versioning scheme, matching the Gradle
+Android Plugin versions.
+
+The source for this can some from two places:
+
+* https://android.googlesource.com/platform/tools/apksig.git
+* https://jcenter.bintray.com/com/android/tools/build/apksig/2.5.0-alpha-preview-01/apksig-2.5.0-alpha-preview-01-sources.jar
+
+This package started from the git repo, but Google never tags releases
+there with rational tags.  The release versions never show up in the
+git tags.  But using `diff` or `meld`, it is easy to see which
+released source jar matches which git revision:
+
+    unzip apksig-2.5.0-alpha-preview-01-sources.jar
+    meld /path/to/android-platform-tools-apksig/src/main/java/com/  com/
+
+The source JAR does not include the gradle build files, but this
+package only uses the .java files anyway.
+
+ -- Hans-Christoph Steiner <hans@eds.org>, Tue,  4 Apr 2017 22:36:21 +0200
diff --git a/debian/changelog b/debian/changelog
index eb91c32..268c27a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+android-platform-tools-apksig (0.5+git168~g10c9d71-1) unstable; urgency=medium
+
+  * New upstream release (Closes: #859541)
+
+ -- Hans-Christoph Steiner <hans@eds.org>  Tue, 04 Apr 2017 21:25:56 +0200
+
 android-platform-tools-apksig (0.5+git165~g42d07eb-1) unstable; urgency=medium
 
   * New upstream release (Closes: #857027)
diff --git a/debian/control b/debian/control
index 3c9f8a8..ed6ca44 100644
--- a/debian/control
+++ b/debian/control
@@ -13,8 +13,7 @@ Build-Depends: antlr3,
                junit4,
                maven-debian-helper,
                maven-repo-helper,
-               pandoc,
-               proguard
+               pandoc
 Standards-Version: 3.9.8
 Vcs-Browser: https://anonscm.debian.org/cgit/android-tools/android-platform-tools-apksig.git
 Vcs-Git: https://anonscm.debian.org/git/android-tools/android-platform-tools-apksig.git
diff --git a/debian/rules b/debian/rules
index f4911e3..d2d284a 100755
--- a/debian/rules
+++ b/debian/rules
@@ -9,7 +9,7 @@ export CLASSPATH=/usr/share/java/apksig.jar
 %:
 	dh $@ --with maven_repo_helper,javahelper,bash-completion --buildsystem=gradle
 
-tarball_name = 42d07eb
+tarball_name = 10c9d71d48ff2db01a2d1f157651036494f569f7
 
 override_dh_auto_build: debian/apksigner.1
 	dh_auto_build
diff --git a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
index 06b5603..e64fec3 100644
--- a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
+++ b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
@@ -41,6 +41,7 @@ import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.Provider;
 import java.security.PublicKey;
+import java.security.Security;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
@@ -122,6 +123,8 @@ public class ApkSignerTool {
         int maxSdkVersion = Integer.MAX_VALUE;
         List<SignerParams> signers = new ArrayList<>(1);
         SignerParams signerParams = new SignerParams();
+        List<ProviderInstallSpec> providers = new ArrayList<>();
+        ProviderInstallSpec providerParams = new ProviderInstallSpec();
         OptionsParser optionsParser = new OptionsParser(params);
         String optionName;
         String optionOriginalForm = null;
@@ -179,6 +182,20 @@ public class ApkSignerTool {
                 signerParams.certFile = optionsParser.getRequiredValue("Certificate file");
             } else if (("v".equals(optionName)) || ("verbose".equals(optionName))) {
                 verbose = optionsParser.getOptionalBooleanValue(true);
+            } else if ("next-provider".equals(optionName)) {
+                if (!providerParams.isEmpty()) {
+                    providers.add(providerParams);
+                    providerParams = new ProviderInstallSpec();
+                }
+            } else if ("provider-class".equals(optionName)) {
+                providerParams.className =
+                        optionsParser.getRequiredValue("JCA Provider class name");
+            } else if ("provider-arg".equals(optionName)) {
+                providerParams.constructorParam =
+                        optionsParser.getRequiredValue("JCA Provider constructor argument");
+            } else if ("provider-pos".equals(optionName)) {
+                providerParams.position =
+                        optionsParser.getRequiredIntValue("JCA Provider position");
             } else {
                 throw new ParameterException(
                         "Unsupported option: " + optionOriginalForm + ". See --help for supported"
@@ -189,6 +206,10 @@ public class ApkSignerTool {
             signers.add(signerParams);
         }
         signerParams = null;
+        if (!providerParams.isEmpty()) {
+            providers.add(providerParams);
+        }
+        providerParams = null;
 
         if (signers.isEmpty()) {
             throw new ParameterException("At least one signer must be specified");
@@ -219,6 +240,11 @@ public class ApkSignerTool {
                             + ")");
         }
 
+        // Install additional JCA Providers
+        for (ProviderInstallSpec providerInstallSpec : providers) {
+            providerInstallSpec.installProvider();
+        }
+
         List<ApkSigner.SignerConfig> signerConfigs = new ArrayList<>(signers.size());
         int signerNumber = 0;
         try (PasswordRetriever passwordRetriever = new PasswordRetriever()) {
@@ -531,6 +557,46 @@ public class ApkSignerTool {
         }
     }
 
+    private static class ProviderInstallSpec {
+        String className;
+        String constructorParam;
+        Integer position;
+
+        private boolean isEmpty() {
+            return (className == null) && (constructorParam == null) && (position == null);
+        }
+
+        private void installProvider() throws Exception {
+            if (className == null) {
+                throw new ParameterException(
+                        "JCA Provider class name (--provider-class) must be specified");
+            }
+
+            Class<?> providerClass = Class.forName(className);
+            if (!Provider.class.isAssignableFrom(providerClass)) {
+                throw new ParameterException(
+                        "JCA Provider class " + providerClass + " not subclass of "
+                                + Provider.class.getName());
+            }
+            Provider provider;
+            if (constructorParam != null) {
+                // Single-arg Provider constructor
+                provider =
+                        (Provider) providerClass.getConstructor(String.class)
+                                .newInstance(constructorParam);
+            } else {
+                // No-arg Provider constructor
+                provider = (Provider) providerClass.getConstructor().newInstance();
+            }
+
+            if (position == null) {
+                Security.addProvider(provider);
+            } else {
+                Security.insertProviderAt(provider, position);
+            }
+        }
+    }
+
     private static class SignerParams {
         String name;
 
@@ -623,17 +689,18 @@ public class ApkSignerTool {
             }
 
             // 2. Load the KeyStore
-            List<char[]> keystorePasswords = null;
-            if ("NONE".equals(keystoreFile)) {
-                ks.load(null);
-            } else {
+            List<char[]> keystorePasswords;
+            {
                 String keystorePasswordSpec =
                         (this.keystorePasswordSpec != null)
                                 ?  this.keystorePasswordSpec : PasswordRetriever.SPEC_STDIN;
                 keystorePasswords =
                         passwordRetriever.getPasswords(
                                 keystorePasswordSpec, "Keystore password for " + name);
-                loadKeyStoreFromFile(ks, keystoreFile, keystorePasswords);
+                loadKeyStoreFromFile(
+                        ks,
+                        "NONE".equals(keystoreFile) ? null : keystoreFile,
+                        keystorePasswords);
             }
 
             // 3. Load the PrivateKey and cert chain from KeyStore
@@ -725,13 +792,23 @@ public class ApkSignerTool {
             }
         }
 
+        /**
+         * Loads the password-protected keystore from storage.
+         *
+         * @param file file backing the keystore or {@code null} if the keystore is not file-backed,
+         *        for example, a PKCS #11 KeyStore.
+         */
         private static void loadKeyStoreFromFile(KeyStore ks, String file, List<char[]> passwords)
                 throws Exception {
             Exception lastFailure = null;
             for (char[] password : passwords) {
                 try {
-                    try (FileInputStream in = new FileInputStream(file)) {
-                        ks.load(in, password);
+                    if (file != null) {
+                        try (FileInputStream in = new FileInputStream(file)) {
+                            ks.load(in, password);
+                        }
+                    } else {
+                        ks.load(null, password);
                     }
                     return;
                 } catch (Exception e) {
diff --git a/src/apksigner/java/com/android/apksigner/help_sign.txt b/src/apksigner/java/com/android/apksigner/help_sign.txt
index ad865fe..11014e0 100644
--- a/src/apksigner/java/com/android/apksigner/help_sign.txt
+++ b/src/apksigner/java/com/android/apksigner/help_sign.txt
@@ -134,6 +134,25 @@ file in X.509 format (see --key and --cert).
                       must be in X.509 PEM or DER format.
 
 
+        JCA PROVIDER INSTALLATION OPTIONS
+These options enable you to install additional Java Crypto Architecture (JCA)
+Providers, such PKCS #11 providers. Use --next-provider to delimit options of
+different providers. Providers are installed in the order in which they appear
+on the command-line.
+
+--provider-class      Fully-qualified class name of the JCA Provider.
+
+--provider-arg        Value to pass into the constructor of the JCA Provider
+                      class specified by --provider-class. The value is passed
+                      into the constructor as java.lang.String. By default, the
+                      no-arg provider's constructor is used.
+
+--provider-pos        Position / priority at which to install this provider in
+                      the JCA provider list. By default, the provider is
+                      installed as the lowest priority provider.
+                      See java.security.Security.insertProviderAt.
+
+
         EXAMPLES
 
 1. Sign an APK, in-place, using the one and only key in keystore release.jks:
@@ -148,3 +167,7 @@ $ apksigner sign --key release.pk8 --cert release.x509.pem app.apk
 
 4. Sign an APK using two keys:
 $ apksigner sign --ks release.jks --next-signer --ks magic.jks app.apk
+
+5. Sign an APK using PKCS #11 JCA Provider:
+$ apksigner sign --provider-class sun.security.pkcs11.SunPKCS11 \
+    --provider-arg token.cfg --ks NONE --ks-type PKCS11 app.apk

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: