[RFC][icedtea-web] Unit tests for the new updates to JarSIgner (incomplete)

Danesh Dadachanji ddadacha at redhat.com
Mon Apr 2 13:46:47 PDT 2012


Hi,

I've been working on updating JarSigner to be able to handle multiple 
signers properly. Currently, it mashes and saves all of the signers' 
properties (flags for expired/badly signed/not yet valid) as one. In 
other words, if one signer has expired, all signers are seen by 
IcedTea-Web as expired. If one has signing issues, then they all have 
signing issues. This is definitely not an ideal solution since we're 
telling users that verifiable applications are not verified.

The attached patch contains a set of unit tests for the (former) 
verifyJar method. I'm going to avoid including the actual code for these 
changes just yet because the entire class isn't fully cleaned up. Here's 
a bit of background info on what I've changed though.


* What verifyJar should be doing:

My understanding of the idea behind verifyJar is that it does 2 somewhat 
separate tasks. First, given a jar, iterate over all of its entries. For 
every entry that can be signed, go through the list of signers and see 
if any have issues. If they do, setup the flags accordingly (issues 
could be expiry/bad key usage/not yet valid start date etc). Also, keep 
track of the number of entries each signer has signed, as well as the 
total number of possible signable entries. The second step is going 
through all of the signers after all the entries have been iterated over 
to see if there is a common signer that has signed them all. If there is 
any entry that is not signed but should be, or if there is one entry 
that does not share a common signer between all other entries, then this 
jar is considered UNSIGNED. If all entries (that should be signed) share 
a common signer, then the signer itself is checked. If the signer has 
signing issues, the jar is considered SIGNED_NOT_OKAY, if it has no 
signing issues, the jar is considered SIGNED_OK.

Please correct me if I am wrong!


* Summary of my changes to verifyJar:

I've split verifyJar into 2 methods, all the logic/implementations from 
line 265[1] and onwards is now in a method named verifyJarEntryCerts. 
Here's a quick snippet of its javadoc and method declaration:

     /**
      * Checks through all the jar entries for signers, storing all the 
common
      * ones in the certs hash map.
      * @param jarHasManifest Whether or not the associated jar has a 
manifest.
      * @param entries The list of entries in the associated jar.
      * @return If there is at least one signable entry that is not 
signed by a
      * common signer, return UNSIGNED. Otherwise every signable entry is
      * signed by at least one common signer. If the signer has no issues,
      * return SIGNED_OK. If there are any signing issues, return 
SIGNED_NOT_OK.
      * @throws Exception Will be thrown if there are issues with entries.
      */
     VerifyResult verifyJarEntryCerts(boolean jarHasManifest, 
Vector<JarEntry> entries) throws Exception

The reason I've split this method up is so that JarSigner can be made 
unit testable. The method verifyJar takes in a jar name and 
creating/commiting one to upstream isn't suitable. Instead, I've created 
an extra helper method that takes in a list of jar entries and tests 
everything the original code tests. The new unit test class then hard 
codes these entries, along with their signers, to make this method testable.

In order to do this, I've created a subclass of JarEntry so that I can 
skip all the unnecessary bits JarEntry does that is not needed by 
verifyJarEntryCerts.

For the entries' signers, I've created a helper class that creates 
X509Certificate objects with specified domain names/start dates/validity 
periods. This code is essentially taken from 
sun.security.tools.KeyTool#doGenKeyPair (which calls 
KeyTool#doSelfCert), I've removed the bits that aren't needed 
(KeyStore/alias etc) and left the bare minimum that is needed to create 
an X509Certificate. I'm not 100% sure of the copyright header that is 
needed for this class so I used the same one provided by KeyTool from 
here [2] (with s/2011/2012). I would appreciate any insight as to if 
this is correct. =)

The unit tests themselves are pretty self-explanatory, to save on 
space/repetition, I've kept testing 1 entry and then 3 entries with the 
same scenario under one method (with different asserts). I think this is 
cleanest but am open to criticism! I've covered everything I could think 
of except for the badKeyUsage/badExtendedKeyUsage/badNetscapeCertType 
cases, I have yet to figure out how to setup certs using them. Is there 
any corner case I've missed?

Comments are very appreciated!

Regards,
Danesh

[1] 
http://icedtea.classpath.org/hg/icedtea-web/file/tip/netx/net/sourceforge/jnlp/tools/JarSigner.java#l265
[2] 
http://icedtea.classpath.org/hg/icedtea8-forest/jdk/file/9a59860aaccb/src/share/classes/sun/security/tools/KeyTool.java
-------------- next part --------------
A non-text attachment was scrubbed...
Name: jar-signer-tests-01.patch
Type: text/x-patch
Size: 23245 bytes
Desc: not available
Url : http://mail.openjdk.java.net/pipermail/distro-pkg-dev/attachments/20120402/9adf2f45/jar-signer-tests-01.patch 


More information about the distro-pkg-dev mailing list