Discussion:
<verifyjar> apparently not passing keystore password along
Phil Edwards
2018-03-16 20:25:00 UTC
Permalink
We're using 1.10.1 to build and sign an executable JAR file. All of
that has been working fine for a while now.

Out of paranoia, we've been asked to run the <verifyjar> task to our
post-build "quick check that this isn't gratuitously broken" target. (Other
targets do more extensive testing including, you know, running the thing
in a paranoid launcher.) We mentioned the concerns that had also been
raised way
back when bug #27596 was opened, in that it's not meant to check complete
chain of validity, merely that the JAR isn't going to crash and burn when
loaded. We figured fine, go ahead and run <verifyjar>, as long as we
continue to do the rest of the testing, more can't hurt.

The task is always concluding with
[verifyjar] jar verified, with signer errors.
[verifyjar]
[verifyjar] Error:
[verifyjar] This jar contains signed entries that are not signed by
alias in this keystore.
BUILD FAILED
the\path\to\the\build.xml:444: jarsigner returned: 32
at org.apache.tools.ant.taskdefs.ExecTask.runExecute(ExecTask.java:645)
at org.apache.tools.ant.taskdefs.ExecTask.runExec(ExecTask.java:670)
at org.apache.tools.ant.taskdefs.ExecTask.execute(ExecTask.java:496)
at org.apache.tools.ant.taskdefs.VerifyJar.verifyOneJar(VerifyJar.java:130)
at org.apache.tools.ant.taskdefs.VerifyJar.execute(VerifyJar.java:93)
...dozen more lines of org.apache.tools...

which doesn't make sense given the rest of the setup. Namely:

1) The JAR is being signed with the same arguments to its task:

<signjar jar="the_jar_file.jar"
keystore="the_keystore.p12" storetype="pkcs12"
storepass="yup_its_in_the_build_file"
alias="signing_alias"
sigfile="..." sigalg="..." digestalg="..." tsaurl="..."/>

works fine.

2) We can run the_jar_file.jar and it's properly verified and loaded.
And we can run

jarsigner -verify -storetype pkcs12 -keystore the_keystore.p12 \
-storepass yup_its_in_the_build_file -strict -certs -verbose \
the_jar_file.jar signing_alias

and everything is fine, along with seeing 'smk' flags printed for each
file in the JAR
listing.

3) But running

<verifyjar jar="the_jar_file.jar"
keystore="the_keystore.p12" storetype="pkcs12"
storepass="yup_its_in_the_build_file"
alias="signing_alias"
certificates="true" strict="true" verbose="true"/>

only prints 'sm' flags for each file before giving the error above.

4) Running ant with -d, we're seeing

[verifyjar] Verifying JAR: the_jar_file.jar
[verifyjar] Current OS is Windows 7
[verifyjar] Using input string
[verifyjar] Executing 'C:\Java\x64\jdk-9.0.4\bin\jarsigner.exe'
with arguments:
[verifyjar] '-strict'
[verifyjar] '-keystore'
[verifyjar] 'full\path\to\the_keystore.p12'
[verifyjar] '-storetype'
[verifyjar] 'pkcs12'
[verifyjar] '-verify'
[verifyjar] '-certs'
[verifyjar] 'path\to\the_jar_file.jar'
[verifyjar]
[verifyjar] The ' characters around the executable and arguments are
[verifyjar] not part of the command.
Execute:Java13CommandLauncher: Executing
'C:\Java\x64\jdk-9.0.4\bin\jarsigner.exe' with arguments:
'-strict'
'-keystore'
'full\path\to\the_keystore.p12'
'-storetype'
'pkcs12'
'-verify'
'-certs'
'path\to\the_jar_file.jar'

Note that the "storepass" and "alias" attributes have not been passed along.
Taking the successful command-line invocation of jarsigner from (2) and
removing those two arguments causes the same error.

And finally, just to be certain that the output from -d is actually what's
happening (yah, they're very paranoid about tools here; fifty times bitten,
twice shy), I checked the current Git tree, and the command sequences built
up in
src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java
src/main/org/apache/tools/ant/taskdefs/SignJar.java
src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
confirm all this. First, that the "alias" attribute is not being included in
the command for the <verifyjar> task. It's not required to check that the
JAR is signed, but it's required to test whether the JAR has been signed by
the cert we "think" (know) has been used.

Second, the storepass is a little tricker. Ant doesn't give "-storepass
your_password" on its command line for security reasons, but instead sets
up a redirection and feeds the password on jarsigner's stdin. However, that
only helps when jarsigner actually reads a password from stdin, and from
looking at the source of the OpenJDK reference implementation
jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
it's clear that -verify turns off keystore password prompting. (See its
loadKeyStore() arguments and how they're passed.)

Granted that the usefulness of jarsigner and the <verifyjar> task is
debatable, it should still actually do what it claims to do. :-) I feel
not passing these two arguments is clearly a bug, but that's something the
maintainers can decide. In the meantime, I'd like to find a workaround.
I had been hoping we could sneak the "-storepass" argument through somehow,
perhaps using the task's <sysproperty>, but looking at the jarsigner/Main.java
source it doesn't look for any system properties at all, let alone for the
keystore password.


Phil

---------------------------------------------------------------------
To unsubscribe, e-mail: user-***@ant.apache.org
For additional commands, e-mail: user-***@ant.apache.org
Jaikiran Pai
2018-03-17 08:36:03 UTC
Permalink
Looking at the jarsigner tool and the verifyjar Ant task and based on
what you note, to me, this looks like the bug really is in the "alias"
not being passed by the verifyjar task.

The storepass not being used isn't a bug IMO, since the jarsigner
documentation[1] states:

"The -storepass, -keypass, -sigfile, -sigalg, -digestalg, -signedjar,
and TSA-related options are only relevant when signing a JAR file; they
are not relevant when verifying a signed JAR file. The -keystore option
is relevant for signing and verifying a JAR file. In addition, aliases
are specified when signing and verifying a JAR file."

The alias itself is optional for jarsigner but if it indeed is specified
on the verifyjar task, then it must be passed on to the jarsigner
command execution. Right now, this is what is missing in the verifyjar
task and IMO a bug.

Would you like to file a bug here
https://bz.apache.org/bugzilla/describecomponents.cgi?product=Ant

[1] https://docs.oracle.com/javase/9/tools/jarsigner.htm

-Jaikiran
Post by Phil Edwards
We're using 1.10.1 to build and sign an executable JAR file. All of
that has been working fine for a while now.
Out of paranoia, we've been asked to run the <verifyjar> task to our
post-build "quick check that this isn't gratuitously broken" target. (Other
targets do more extensive testing including, you know, running the thing
in a paranoid launcher.) We mentioned the concerns that had also been
raised way
back when bug #27596 was opened, in that it's not meant to check complete
chain of validity, merely that the JAR isn't going to crash and burn when
loaded. We figured fine, go ahead and run <verifyjar>, as long as we
continue to do the rest of the testing, more can't hurt.
The task is always concluding with
[verifyjar] jar verified, with signer errors.
[verifyjar]
[verifyjar] This jar contains signed entries that are not signed by
alias in this keystore.
BUILD FAILED
the\path\to\the\build.xml:444: jarsigner returned: 32
at org.apache.tools.ant.taskdefs.ExecTask.runExecute(ExecTask.java:645)
at org.apache.tools.ant.taskdefs.ExecTask.runExec(ExecTask.java:670)
at org.apache.tools.ant.taskdefs.ExecTask.execute(ExecTask.java:496)
at org.apache.tools.ant.taskdefs.VerifyJar.verifyOneJar(VerifyJar.java:130)
at org.apache.tools.ant.taskdefs.VerifyJar.execute(VerifyJar.java:93)
...dozen more lines of org.apache.tools...
<signjar jar="the_jar_file.jar"
keystore="the_keystore.p12" storetype="pkcs12"
storepass="yup_its_in_the_build_file"
alias="signing_alias"
sigfile="..." sigalg="..." digestalg="..." tsaurl="..."/>
works fine.
2) We can run the_jar_file.jar and it's properly verified and loaded.
And we can run
jarsigner -verify -storetype pkcs12 -keystore the_keystore.p12 \
-storepass yup_its_in_the_build_file -strict -certs -verbose \
the_jar_file.jar signing_alias
and everything is fine, along with seeing 'smk' flags printed for each
file in the JAR
listing.
3) But running
<verifyjar jar="the_jar_file.jar"
keystore="the_keystore.p12" storetype="pkcs12"
storepass="yup_its_in_the_build_file"
alias="signing_alias"
certificates="true" strict="true" verbose="true"/>
only prints 'sm' flags for each file before giving the error above.
4) Running ant with -d, we're seeing
[verifyjar] Verifying JAR: the_jar_file.jar
[verifyjar] Current OS is Windows 7
[verifyjar] Using input string
[verifyjar] Executing 'C:\Java\x64\jdk-9.0.4\bin\jarsigner.exe'
[verifyjar] '-strict'
[verifyjar] '-keystore'
[verifyjar] 'full\path\to\the_keystore.p12'
[verifyjar] '-storetype'
[verifyjar] 'pkcs12'
[verifyjar] '-verify'
[verifyjar] '-certs'
[verifyjar] 'path\to\the_jar_file.jar'
[verifyjar]
[verifyjar] The ' characters around the executable and arguments are
[verifyjar] not part of the command.
Execute:Java13CommandLauncher: Executing
'-strict'
'-keystore'
'full\path\to\the_keystore.p12'
'-storetype'
'pkcs12'
'-verify'
'-certs'
'path\to\the_jar_file.jar'
Note that the "storepass" and "alias" attributes have not been passed along.
Taking the successful command-line invocation of jarsigner from (2) and
removing those two arguments causes the same error.
And finally, just to be certain that the output from -d is actually what's
happening (yah, they're very paranoid about tools here; fifty times bitten,
twice shy), I checked the current Git tree, and the command sequences built
up in
src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java
src/main/org/apache/tools/ant/taskdefs/SignJar.java
src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
confirm all this. First, that the "alias" attribute is not being included in
the command for the <verifyjar> task. It's not required to check that the
JAR is signed, but it's required to test whether the JAR has been signed by
the cert we "think" (know) has been used.
Second, the storepass is a little tricker. Ant doesn't give "-storepass
your_password" on its command line for security reasons, but instead sets
up a redirection and feeds the password on jarsigner's stdin. However, that
only helps when jarsigner actually reads a password from stdin, and from
looking at the source of the OpenJDK reference implementation
jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
it's clear that -verify turns off keystore password prompting. (See its
loadKeyStore() arguments and how they're passed.)
Granted that the usefulness of jarsigner and the <verifyjar> task is
debatable, it should still actually do what it claims to do. :-) I feel
not passing these two arguments is clearly a bug, but that's something the
maintainers can decide. In the meantime, I'd like to find a workaround.
I had been hoping we could sneak the "-storepass" argument through somehow,
perhaps using the task's <sysproperty>, but looking at the jarsigner/Main.java
source it doesn't look for any system properties at all, let alone for the
keystore password.
Phil
---------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: user-***@ant.apache.org
For additional commands, e-mail: user-***@ant.apache.org
Phil Edwards
2018-03-19 19:57:11 UTC
Permalink
"The -storepass, -keypass, -sigfile, -sigalg, -digestalg, -signedjar, and
TSA-related options are only relevant when signing a JAR file; they are not
relevant when verifying a signed JAR file. The -keystore option is relevant
for signing and verifying a JAR file. In addition, aliases are specified
when signing and verifying a JAR file."
Interesting catch; I missed that part. Something else seems wrong then,
as including the alias name but leaving out the "-storepass nnnn" argument
when running the jarsigner binary (on the command line) gives the same
problematic behavior of verified-but-with-errors, including "entries that
are not signed by alias in this keystore" and tagging each entry with the
capital-X meaning "not signed by the alias you specified".

Giving a -storepass allows everything to work, including verification of
the named certificate.

Whether that's an upstream bug, a documentation bug, or a gap in our local
understanding, it definitely seems that <verifyjar> is following the upstream
lead with respect to -storepass.
Would you like to file a bug here
https://bz.apache.org/bugzilla/describecomponents.cgi?product=Ant
I will try, although my toleration for bugzilla in general has about reached
an all-time low... I'll see if I can get the 'alias' bug submitted before
the end of the day.


Thanks again!

---------------------------------------------------------------------
To unsubscribe, e-mail: user-***@ant.apache.org
For additional commands, e-mail: user-***@ant.apache.org
Stefan Bodewig
2018-03-20 11:27:24 UTC
Permalink
Post by Phil Edwards
Post by Jaikiran Pai
Would you like to file a bug here
https://bz.apache.org/bugzilla/describecomponents.cgi?product=Ant
I will try, although my toleration for bugzilla in general has about reached
an all-time low... I'll see if I can get the 'alias' bug submitted before
the end of the day.
Thanks a lot to the report Phil. I realized you had disabled mail
notifications on https://bz.apache.org/bugzilla/show_bug.cgi?id=62194
so here is the summary (more details in bugzilla):

* jarsiger is broken, even more so than we knew
* it will work for you in Ant 1.10.3 (and 1.9.11) due to be released
soonish
* a workaround for you might be to set the struct attribute to false

Many thanks again

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: user-***@ant.apache.org
For additional commands, e-mail: user-***@ant.apache.org
Phil Edwards
2018-03-20 19:44:47 UTC
Permalink
Thank you muchly! Am in total agreement with comment #4 wrt
Oracle's bug reporting tools.
Post by Stefan Bodewig
Post by Phil Edwards
Post by Jaikiran Pai
Would you like to file a bug here
https://bz.apache.org/bugzilla/describecomponents.cgi?product=Ant
I will try, although my toleration for bugzilla in general has about reached
an all-time low... I'll see if I can get the 'alias' bug submitted before
the end of the day.
Thanks a lot to the report Phil. I realized you had disabled mail
notifications on https://bz.apache.org/bugzilla/show_bug.cgi?id=62194
* jarsiger is broken, even more so than we knew
* it will work for you in Ant 1.10.3 (and 1.9.11) due to be released
soonish
* a workaround for you might be to set the struct attribute to false
Many thanks again
Stefan
---------------------------------------------------------------------
--
Onen i estel úben,
Ú-chebin estel anim.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-***@ant.apache.org
For additional commands, e-mail: user-***@ant.apache.org
Loading...