JDK-8047698 : Clicking cancel on security dialog for preloader clears the DeniedCertStore
  • Type: Bug
  • Component: deploy
  • Affected Version: 8u20
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-06-20
  • Updated: 2015-09-29
  • Resolved: 2015-03-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u60 b07Fixed 9Fixed
Description
original synopses: Clicking cancel on security dialog for preloader won't cause applet to quit
(see comments)

Testing env:
64bit win7, 8u20 b19

Steps to reproduce:
- download http://rehte.cn.oracle.com:8080/wshost/reproduce/Preloader/self.valid.cert and import it to user cert - Signer CA in jcp
- Open http://rehte.cn.oracle.com:8080/wshost/reproduce/Preloader/html/SignedHelloPreloaderExt1.html 
- Click Cancel on security dialog, wait for a moment, if there is another security dialog pops up, bug is reproduced.

This only occurs if there is a progress-class identified, and the jar implementing that class is not identified with download="progress"


Comments
Crucible review: https://java.se.oracle.com/code/cru/CR-JDK9CLIENT-810
09-03-2015

Based on our current design - if you cancel the preloader's security dialog, you will continue to run with the default preloader, and will not then necessarily exit 1.) if The applet needs to relaunch, it is appropriate to show pre-loader's security dialog again in the second VM. (this is the case in the original example, http://rehte.cn.oracle.com:8080/wshost/reproduce/Preloader/html/SignedHelloPreloaderExt1.html so the original bug could be closed as will not fix. 2.) However If the preloader and the app are signed with the same cert, as in http://oklahoma.us.oracle.com/www/tests/1.9.0/preloader/appletd.html, we should not show the same cert dialog again in the same VM. This happens because after the preloaders cert dialog is denied, the AWTDefaultPreloader handles the preloader error by calling showError() with last arg true, meaning we get to doShowError with offerReload true. We pass this arg on to constructor of AWTErrorPannel which results in the DeniedCertStore being reset, even though the applet is still trying to launch. With the DeniedCertStore cleared out, the applet tries to load a jar signed with the same cert, and we show dialog again (in this case third time). Perhaps a BlockedException received by the preloader should not cause the ErrorPanel at all, but it certainly should not clear the denied store before the applet itself is loaded. - changing to just pass false when preload error event is caused by BlockedException fixes this.
24-02-2015

This has nothing to do with extension - as can be see by http://oklahoma.us.oracle.com/www/tests/1.9.0/preloader/appletd.html which has no extension, but same preloader jar and main jar. If you cancel the preloader jar - it will proceed with default preloader, that is as expected. However, in these cases (both appletc.html and appletd.html above) you actually see three security dialogs. The first is for the preloader, then app relaunches. The second is for the preloader again after relaunch (assuming you cancelled the first time)
06-11-2014

OK - so above analysis is still wrong. The difference between given fx applet and : http://oklahoma.us.oracle.com/www/tests/1.9.0/preloader/appleta.html is not that one is fx (unless extension jnlp was generated by fx). The difference is the progress extension has the jar attribute download="eager" instead of download="progress". By not identifying any jars as progress jars, progress jar loading completes without throwing an exception (since there are no progress jars). I can reproduce with simple AWT applet by changing attribute on progress jar in progress extension: http://oklahoma.us.oracle.com/www/tests/1.9.0/preloader/appletc.html Like the given app, we have progress class implemented in an extension, and progress-class attribute set in applet-desc, but the jar in the extension does not have download="progress". So the code has no way of knowing where the progress class is.
18-09-2014

OK - round and round - Problem 1 should not be addressed by saving DeniedStore in session data. I have simple java webstart app: http://oklahoma.us.oracle.com/www/tests/1.9.0/preloader/testa.jnlp and simple awt applet: http://oklahoma.us.oracle.com/www/tests/1.9.0/preloader/appleta.html that do the same thing (have a secure property, and have a preloader in an extension, both preloader and main jnlp are signed and request all-permissions). In both cases if I accept the security dialog for the preloader, it will relaunch with the secure property and not show cert dialog again since it is in the SessionStore). If I deny the preloader cert dialog, it will exit. In the javaws case, denying the cert dialog (different from being blocked) will just call Main.SystemExit() calling System.exit() and exit. in the plugin case, trying to call System.exit() throws an exception (there may be other applets using this VM) which is caught and processed (in AWTDefaultPreloader) , causing the main applet to exit before relaunch is tried. The given case uses javafx, so the problem seems to be in the default javafx preloader
18-09-2014

Making DeniedCertStore just another SessionCertStore fixes "Problem 1" as described above - which is the gist of this bug, and only one cert dialog is now shown. However "Problem 2" still occurs, the red error text is shown before relaunch, then cleared at beginning of relaunch and then shown again in second vm.
17-09-2014

OK - I confirmed that without the secure property it behaves as expected - one dialog (for preloader) then no relaunch and since same certs, security check for main jar returns denied because it is denied store. So it would be easy to fix this case by implementing SessionState.Client in DeniedCertStore as in SessionCertStore. The following questions might still remain: 1.) What if preloader and main applet are differently signed ? I expect we are showing default error panel too soon (after denied preloader) . Correct behavior (I believe) would be run applet if preloader cert dialog denied, and applet cert dialog accepted. 2.) You can now also get ExitException in preloader initialization if the currently running default jre is prohibited by the DRS run rule. In that case also we are required to not run preloader till after relaunch into allowed jre.
17-09-2014

The above analysis is not correct in this case. The applet relaunches - the first launch shows the preloader security dialog and then the error pane when it is denied. Then the second vm launches the applet and shows the security dialog for the main jar. Unlike the SessionCertStore, the DeniedCertStore does not implement SessionState.Client, and is not preserved across launches - so the second launch shows the dialog for the main app even though it's cert was denied in the first launch. Remains to be understood why applet relaunches, probably due to having secure property "jnlp.fx.perf". Will compare behavior with same app without any properties.
17-09-2014

several things going on here. first, we have a signed all-permission fx applet (or application) with a signed fx pre-loader. (note in the given case, both main applet and preloader are signed with the same cert) The first security dialog is for the pre-loader, the second security dialog is for the main applet. In general, it might make sense to not run the preloader and still run the applet but: Problem 1) since the jars are signed by the same cert, we would want the decision to not run the preloader to be recorded in the session cert store, then used when we look for permission to run the applet. It is not because the synchronization in TrustDecider releases the deployLock before calling the gui code (which has it's own locking) to show the dialog, then gets it again to set the value(s) in session store. This allows multiple security dialogs from multiple threads to "stack up" in TrustDecidr.askUser(). Although this behavior is easiestly sees using a preloader, the same effect cound be created with a main app with two signed extensions (signed with differnt cert than main app but the same as each other), where the main app starts two threads that each access one of the extensions. Problem 2) when the preloader dialog is denied, we briefly see the default greybox error content "Runtime Error click for details" and then it is replaced by grey box, while the second security dialog is shown. Denying the preloader should not be considered fatal. The ExitException , or any other exception from initializing the custom preloader should just be noted in the console and the default preloader used.
17-09-2014

SQE OK to defer the fix in 8u40 as far as this is not a regression and it's intermittent failure.
02-07-2014

Please try with JDK 8 fcs.
30-06-2014

seems not., tried 8u5 b02, it can be reproduced.
30-06-2014

Fred, Is it a regression?
26-06-2014