<html><head></head><body><div>Hi,</div><div><br></div><div>Quite a few command line tools are available through java.util.spi.ToolProvider. But not so jarsigner and keytool. If that finds some common interest, I'd be glad to contribute a patch or two.</div><div><br></div><div>Advantages of having jarsigner and/or keytool available as a tool (though that could certainly be achieved in another way as well) would be</div><div>- Explicit Stdin, Stdout, and Stderr as parameters (possible already now by forking a separate process with the overhead of running the tools in their own vm)</div><div>- Easy prevention of all possible calls to System.exit upon unfavourable command line paramters (at least with jarsigner, and only when working with sun.security.tools.jarsigner.Main and not with jdk.security.jarsigner.JarSigner)</div><div>- Easier to detect whether a jarsigner or keytool tool is available on the class or module path or not.</div><div>- Those who are more familiar with the command line options can use them also programmatically.</div><div><br></div><div>An example seems to be JLinkSigningTest.java, [1]. Even though only a test and in that context not actually severe but still not such a bad example. I figure the following should not happen in real code:</div><div>- The tests catches an Exception which is never thrown (especially not for the reason in the message, "jarsigner not found", I'd expect at best a NoClassDefFoundError but which would not be caught there).</div><div>- Jarsigner (sun.security.tools.jarsigner.Main) will call System.exit instead of throwing an exception (8 occurrences of System.exit in [2]) for certain command line args</div><div>- If command line arguments would be specified such that jarsigner would prompt for input, it would be most probably stuck indefinitely.</div><div><br></div><div>I tried to search existing resources about the topic but found almost nothing, potentially related [3], [4], and [5].</div><div><br></div><div>I'm not entirely sure, if java.util.spi.ToolProvider is preferred over javax.tools.ToolProvider (or java.util.ServiceLoader). [7] might be a hint that java.util.spi.ToolProvider is more current than javax.tools.ToolProvider.</div><div><br></div><div>An additional point for keytool and jarsigner as opposed to jar, javac, and other tools is that both jarsigner and keytool can use stdin when prompting for passwords or maybe X.509 details which is not currently possible through the api of java.util.spi.ToolProvider and would require an additional parameter for Stdin such as in [6]. I would propose that when jarsigner or keytool are invoked without a Stdin that they throw an exception or return a non-zero exit code as their return value immediately whenever they would have otherwise waited for input.</div><div><br></div><div>Some system properties also have influence on the operation of jarsigner and possibly keytool (for example user.language and java.security.properties among probably others) which could not necessarily be set individually for each invocation of a tool gotten by a ToolProvider but probably that would not be necessary in many cases anyway.</div><div><br></div><div>Just like [3] sounds according to its subject, jdk.security.jarsigner.JarSigner already has a useful API, so the need for a ToolProvider is probably not that big. The current jdk.security.jarsigner.JarSigner API, however, expects a key or certificate or chain of certificates to be provided through the API and therefore does not leverage the jarsigner and keytool command line tools' keystore accessing features and aliases. I also don't see how it would provide a possibility to verify a signed JAR but that could as well be achieved in another way than with a ToolProvider.</div><div><br></div><div>It might be a bit of a challenge to catch all System.out and System.err such as in sun.security.tools.KeyStoreUtil.getPassWithModifier or sun.security.util.Debug or from whatever provider classes involved with algorithms loaded with "-providerClass" or "-altsigner" arguments. One conceivable approach might be the one used in the compiler with a context object holding references to Stdout and Stderr. What I don't like for now in the attached patch is that wrapping System.out or System.err PrintStreams into PrintWriters is repeated a few times and I wonder if that could be refactored or recombined into another PrintWriter constructor or PrintStream.toPrintWriter or something...</div><div><br></div><div>So far I haven't found an overview over all the tools available through java.util.spi.ToolProvider other than the example in ToolProvider#name or other documentation that might have to be updated with introducing jarsigner as a tool.</div><div><br></div><div>Also I wonder if Stdin/System.in should be added to the ToolProvider interface or a run method with only args that takes Stdin, Stdout, and Stderr from System.in, System.out, and System.err but I guess that can be discussed independently.</div><div><br></div><div>Attached is a patch with JarSignerToolProvider that provides jarsigner as a tool. It's not yet meant as ready to merge but shows that it is possible and more or less how big the change is.</div><div><br></div><div>I'm not really familiar at all with the processes involved with such a proposal and would appreciate greatly any kind of guidance. Was this mailing list the right place to propose it?</div><div><br></div><div>Regards,</div><div>Philipp</div><div><br></div><div><br></div><div>[1] <a href="http://hg.openjdk.org/jdk/jdk/file/9c3fe09f69bc/test/jdk/tools/jlink/JLinkSigningTest.java#l79">http://hg.openjdk.org/jdk/jdk/file/9c3fe09f69bc/test/jdk/tools/jlink/JLinkSigningTest.java#l79</a></div><div>[2] <a href="http://hg.openjdk.org/jdk/jdk/file/9c3fe09f69bc/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java">http://hg.openjdk.org/jdk/jdk/file/9c3fe09f69bc/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java</a></div><div>[3] <a href="https://bugs.openjdk.java.net/browse/JDK-8056174">https://bugs.openjdk.java.net/browse/JDK-8056174</a></div><div>[4] <a href="https://bugs.openjdk.java.net/browse/JDK-8058778">https://bugs.openjdk.java.net/browse/JDK-8058778</a></div><div>[5] <a href="http://mail.openjdk.java.net/pipermail/security-dev/2015-March/011831.html">http://mail.openjdk.java.net/pipermail/security-dev/2015-March/011831.html</a></div><div>[6] <a href="http://hg.openjdk.org/jdk/jdk/file/9c3fe09f69bc/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java#l203">http://hg.openjdk.org/jdk/jdk/file/9c3fe09f69bc/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java#l203</a></div><div>[7] <a href="http://hg.openjdk.org/jdk/jdk/file/9c3fe09f69bc/src/java.compiler/share/classes/javax/tools/ToolProvider.java#l90">http://hg.openjdk.org/jdk/jdk/file/9c3fe09f69bc/src/java.compiler/share/classes/javax/tools/ToolProvider.java#l90</a></div><div><br></div></body></html>