JDK-8267397 : AlgorithmId's OID cache is never refreshed
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 8u291,11.0.11,17
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2021-05-19
  • Updated: 2021-06-17
  • Resolved: 2021-06-14
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 17 JDK 18
17 b27Fixed 18Fixed
Related Reports
Relates :  
Description
Currently the OID cache table in AlgorithmId is never being refreshed once it's initialized. For example if a jar is signed with an uncommon signature algorithm, it might trigger initialization of the OID cache table. When later any Java code uses the initialized cache it might report incorrect availability of algorithms. Note that Security.addProvider() and Security.removeProvider() might add/remove available algorithms.

Example code (using the bouncy castle provider):

$ cat UseBCAlgoWithPreCheck.java
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.Security;
import java.security.NoSuchAlgorithmException;

public class UseBCAlgoWithPreCheck {
    public static void main (String[] args) throws Exception {
        boolean usePreCheck = false;
        if (args.length == 1) {
            usePreCheck = Boolean.parseBoolean(args[0]);
        }
        System.out.println("usePreCheck = " + usePreCheck);
        if (usePreCheck) {
           try {
               new javax.crypto.EncryptedPrivateKeyInfo("GOST3411WITHECGOST3410", new byte[]{0});
               throw new RuntimeException("pre-check FAILED! GOST3411WITHECGOST3410 available?");
           } catch (NoSuchAlgorithmException e) {
               System.out.println("pre-check passed! GOST3411WITHECGOST3410 NOT available!");
           }
        }
        Security.addProvider(new BouncyCastleProvider());
        new javax.crypto.EncryptedPrivateKeyInfo("GOST3411WITHECGOST3410", new byte[]{0});
        System.out.println("Successfully created third-party provider algo. GOOD.");
    }
}

$ javac -cp bcprov-jdk15on-168.jar:. UseBCAlgoWithPreCheck.java
$ java -cp bcprov-jdk15on-168.jar:. UseBCAlgoWithPreCheck false
usePreCheck = false
Successfully created third-party provider algo. GOOD.
$ java -cp bcprov-jdk15on-168.jar:. UseBCAlgoWithPreCheck true
usePreCheck = true
pre-check passed! GOST3411WITHECGOST3410 NOT available!
Exception in thread "main" java.security.NoSuchAlgorithmException: unrecognized algorithm name: GOST3411WITHECGOST3410
	at java.base/sun.security.x509.AlgorithmId.get(AlgorithmId.java:470)
	at java.base/javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:139)
	at UseBCAlgoWithPreCheck.main(UseBCAlgoWithPreCheck.java:22)
Comments
Changeset: f69e2d56 Author: Valerie Peng <valeriep@openjdk.org> Date: 2021-06-14 20:40:26 +0000 URL: https://git.openjdk.java.net/jdk17/commit/f69e2d5651f239209543bc1daf707a1c1114f6e5
14-06-2021

Need to reset the cache when new provider list is set.
09-06-2021

jtreg test showing the issue: https://github.com/jerboaa/jdk/blob/jdk-8267397-test/test/jdk/java/security/Provider/AddRemove.java Fails with: ----------System.out:(3/156)---------- doPreCheck == false Testing EncryptedPrivateKeyInfo foo provider after dyn-add... PASSED. Testing EncryptedPrivateKeyInfo foo provider after dyn-remove... ----------System.err:(13/938)---------- java.lang.RuntimeException: Test failed! Foo provider recognized even though it has been removed at AddRemove.main(AddRemove.java:74) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127) at java.base/java.lang.Thread.run(Thread.java:831) If I flip the run arguments around to do an availability check before the provider is added, I see this failure: doPreCheck == true Testing EncryptedPrivateKeyInfo foo provider before it's loaded... PASSED. Testing EncryptedPrivateKeyInfo foo provider after dyn-add... ----------System.err:(18/1069)---------- java.lang.RuntimeException: Test failed! at AddRemove.main(AddRemove.java:68) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127) at java.base/java.lang.Thread.run(Thread.java:831) Caused by: java.security.NoSuchAlgorithmException: unrecognized algorithm name: FOOBAR at java.base/sun.security.x509.AlgorithmId.get(AlgorithmId.java:470) at java.base/javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:139) at AddRemove.main(AddRemove.java:65) ... 6 more
19-05-2021