SUGGESTED FIX
The following loop is encountered, preventing policy from getting loaded over HTTPS in certain circumstances:
1. load security provider
2. signed provider (like JCE) causes security check
3. init policy
4. policy attempts to load over HTTPS
5. HTTPS code calls Cipher.getInstance
6. Cipher.getInstance loads security providers
7. provider loading code detects recursion, exits
8. HTTPS policy (step 4) unable to be loaded
To fix the problem, the security provider loading mechanism should be changed to trigger policy initialization up front (before actually attempting to load a provider). This results in the following logic:
1. load security provider
2. trigger policy initialization
3. init policy
4. policy attempts to load over HTTPS
5. HTTPS code calls Cipher.getInstance
6. Cipher.getInstance loads security providers
7. trigger policy initialization
8. init policy
9. detect recursion in policy implementation,
install bootstrap policy
10. policy initialization (step 8) succeeds
11. steps (6), (5), (4), (3), (1) succeed as recursion unwraps
The only time we don't want to trigger policy initialization is during signed jar verification. If policy initialization IS triggered in that case, we end up with:
1. load class from signed jar (like firefox's jss.jar)
2. verify jss.jar
3. jar verification code installs thread providers
(SUN and rsaSign)
4. load thread providers
5. trigger policy initialization
6. init policy
7. policy loads over HTTPS
8. HTTPS code calls Cipher.getInstance
9. Cipher.getInstance fails because thread providers
do not support needed functionality
10. HTTPS policy (step 7) unable to be loaded
The proposed fix ensures that when jar verification is performed, the logic remains as before:
1. load class from signed jar (like firefox's jss.jar)
2. verify jss.jar
3. jar verification installs thread providers
(SUN and rsaSign)
4. load thread providers
(no signed providers, so no policy initialization)
5. jar verification succeeds
Separate from this is another loop that starts in plugin:
1. plugin creates HTTPS URL object
2. com.sun.deploy.net.protocol.https.Handler
(HTTPS stream handler) constructor is invoked
3. Handler calls registerSecurityProviders
4. load security providers
5. trigger policy initialization
6. init policy
7. policy attempts to load over HTTPS
8. policy creates HTTPS URL
9. (obselete) sun.plugin.net.protocol.https.Handler
(HTTPS stream handler) constructor is invoked
10. class not found (deleted sometime before 5.0 release)
11. fall back to default SSL context
(uses cacerts and jssecacerts truststores)
12. HTTPS policy (step 7) unable to be loaded because
server cert not installed in cacerts nor jssecacerts
An additional fix (combined with those above) involves plugin triggering policy
initialization prior to creating the HTTPS URL object. The resulting flow then
becomes:
1. plugin triggers policy initialization
2. init policy
3. policy attempts to load over HTTPS
4. policy creates HTTPS URL
5. com.sun.deploy.net.protocol.https.Handler
(HTTPS stream handler) constructor is invoked
6. Handler calls registerSecurityProviders
7. load security providers
8. trigger policy initialization
9. init policy
10 detect recursion in policy implementation,
install bootstrap policy
11. policy initialization (step 9) succeeds
12. steps (7), (5), (3), (2) succeed as recursion unwraps
13. plugin creates HTTPS URL object
14. com.sun.deploy.net.protocol.https.Handler
(previous constructed in step 5) is used
|