More explanations: JarVerifier works in 2 stages: parsing signatures and verifying entries. There are 2 ways to enter the 2nd stage: 1) Someone else call JarEntry::doneWithMeta() directly, 2) JarVerfier itself sees an incoming JarEntry and decides to enter. Before JDK-8021788 (that triggers the regression as described in 8031572), we have:
- JarVerifier: when incoming JarEntry is not in META-INF, automatically enters the 2nd stage - JarFile: feed JarVerifier with all META-INF entries when initializing verifier, and then force JarVerifier into 2nd stage - JarInputStream: feed JarVerifier in natural order So JarFile and JarVerifier are a perfect match, but when using JarInputStream and there are files in META-INF but not signature-related, JarVerifier cannot enter 2nd stage and these entries are treated as unsigned. After JDK-8021788, there is one change: - JarVerifier: when incoming JarEntry is not in signature-related, automatically enters the 2nd stage This fixes the JarInputStream issue (of course, we still need signature files at the beginning). But if a non-signature META-INF file appears before a signature, during the JarFile’s initializing process it could make JarVerifier entering the 2nd stage prematurely and thus ignore later coming signature files. This fix change JarFile behavior: - JarFile: feed JarVerifier with all signature-related META-INF entries when initializing verifier, and then force JarVerifier into 2nd stage so JarFile and JarVerifier work fine together again. As you can see, the 2 ways JarVerifier entering the 2nd stage should have been used by JarFile and JarInputStream separately, so when opened with JarFile it need not enter itself. I would like to make some enhancement in JDK 9 to make the logic more simple and intuitive. Please note that when using a JarFile, the initializing process is before the first getInpuStream(JarEntry) is returned. Therefore you can getJarEntry() on anything (including those non-signatures in META-INF) and call getInputStream() on it and it will be verified. Thanks Max On Jan 22, 2014, at 15:01, Wang Weijun <[email protected]> wrote: > Hi All > > Please take a look at the webrev at > > http://cr.openjdk.java.net/~weijun/8031572/8/webrev.00/ > > JarVerifier has a flag that separates parsing signatures and verifying other > entries. The fix makes sure only signature-related files are processed in the > beginning so JarVerifier does not enter the second stage prematurely. Please > note that JarInputStream always feeds JarVerifier by natural order so once a > non-signatued-related file is processed it goes into verification stage and > will not parse a signature anymore. > > Maybe a smarter solution is to be *always on alert*, which means at anytime > an incoming entry can be anything, so that even if signature-related files > appear at the middle of a file, at least those come after them can be treated > as signed when opening with a JarInputStream. This will be a huge change to > the JarVerifier class and IMHO does not really help much. Also I don’t want > to consider it at this final time of JDK 8. > > You can also find webrevs for jdk9 and jdk7u at > > http://cr.openjdk.java.net/~weijun/8031572/webrev.00/ > > and > > http://cr.openjdk.java.net/~weijun/8031572/7/webrev.00/ > > There are some tiny differences. For 9, the JarVerifier fix needs to be > rebased on a language style changeset. For 7u, there are some differences in > the test because of class name change, implicit final, and default method. > > Thanks > Max >
