From 2f8aad4f7f306f37e7d0dc77178bc9e4ed66e174 Mon Sep 17 00:00:00 2001 From: Michael Groover Date: Fri, 9 Jul 2021 16:12:11 -0700 Subject: [PATCH] Add support for -providerArg in signapk signapk currently accepts a Provider class that can be instantiated and inserted before the signing. This commit adds support to specify a -providerArg parameter that can be used to configure the Provider. Prior to JDK 9 a Provider would accept a providerArg in a constructor accepting a String; in JDK 9+ a Provider should first be instantiated with the zero-arg constructor, then the configure method should be called with the providerArg. Bug: 142334653 Bug: 190974913 Fixes: 232134730 Test: Manually verified new Provider can be inserted with pre- and post-JDK 9 behavior. Change-Id: I96f027640c59d3357e8dcf656626d1601bfef861 --- .../src/com/android/signapk/SignApk.java | 62 +++++++++++++------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java index c127dbe9de..36a220cc0f 100644 --- a/tools/signapk/src/com/android/signapk/SignApk.java +++ b/tools/signapk/src/com/android/signapk/SignApk.java @@ -901,7 +901,7 @@ class SignApk { * Tries to load a JSE Provider by class name. This is for custom PrivateKey * types that might be stored in PKCS#11-like storage. */ - private static void loadProviderIfNecessary(String providerClassName) { + private static void loadProviderIfNecessary(String providerClassName, String providerArg) { if (providerClassName == null) { return; } @@ -920,27 +920,41 @@ class SignApk { return; } - Constructor constructor = null; - for (Constructor c : klass.getConstructors()) { - if (c.getParameterTypes().length == 0) { - constructor = c; - break; + Constructor constructor; + Object o = null; + if (providerArg == null) { + try { + constructor = klass.getConstructor(); + o = constructor.newInstance(); + } catch (ReflectiveOperationException e) { + e.printStackTrace(); + System.err.println("Unable to instantiate " + providerClassName + + " with a zero-arg constructor"); + System.exit(1); + } + } else { + try { + constructor = klass.getConstructor(String.class); + o = constructor.newInstance(providerArg); + } catch (ReflectiveOperationException e) { + // This is expected from JDK 9+; the single-arg constructor accepting the + // configuration has been replaced with a configure(String) method to be invoked + // after instantiating the Provider with the zero-arg constructor. + try { + constructor = klass.getConstructor(); + o = constructor.newInstance(); + // The configure method will return either the modified Provider or a new + // Provider if this one cannot be configured in-place. + o = klass.getMethod("configure", String.class).invoke(o, providerArg); + } catch (ReflectiveOperationException roe) { + roe.printStackTrace(); + System.err.println("Unable to instantiate " + providerClassName + + " with the provided argument " + providerArg); + System.exit(1); + } } } - if (constructor == null) { - System.err.println("No zero-arg constructor found for " + providerClassName); - System.exit(1); - return; - } - final Object o; - try { - o = constructor.newInstance(); - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - return; - } if (!(o instanceof Provider)) { System.err.println("Not a Provider class: " + providerClassName); System.exit(1); @@ -1049,6 +1063,7 @@ class SignApk { "[-a ] " + "[--align-file-size] " + "[-providerClass ] " + + "[-providerArg ] " + "[-loadPrivateKeysFromKeyStore ]" + "[-keyStorePin ]" + "[--min-sdk-version ] " + @@ -1073,6 +1088,7 @@ class SignApk { boolean signWholeFile = false; String providerClass = null; + String providerArg = null; String keyStoreName = null; String keyStorePin = null; int alignment = 4; @@ -1093,6 +1109,12 @@ class SignApk { } providerClass = args[++argstart]; ++argstart; + } else if("-providerArg".equals(args[argstart])) { + if (argstart + 1 >= args.length) { + usage(); + } + providerArg = args[++argstart]; + ++argstart; } else if ("-loadPrivateKeysFromKeyStore".equals(args[argstart])) { if (argstart + 1 >= args.length) { usage(); @@ -1153,7 +1175,7 @@ class SignApk { System.exit(2); } - loadProviderIfNecessary(providerClass); + loadProviderIfNecessary(providerClass, providerArg); String inputFilename = args[numArgsExcludeV4FilePath - 2]; String outputFilename = args[numArgsExcludeV4FilePath - 1];