[EXTERNAL]Re: NullPointer in JceSecurity.getVerificationResult - Affects JDK 11.07, and JDK 12 and later.

Valerie Peng valerie.peng at oracle.com
Fri Jun 12 00:07:47 UTC 2020


Hi, John,

Thanks for the reply.

Yes, your understanding is correct. I expect the fix for JDK-8246613 
will be backported into other releases.

BTW, if you have spare time for the test provider, it'd help speeding up 
the fix for JDK-8246383. If not, it's ok as well. Just may take longer 
to get to it.

Regards,

Valerie
On 6/10/2020 1:31 PM, John Gray wrote:
>
> Thanks Valerie!
>
> If I understand you correctly, I think you are saying the fix for 
> https://bugs.openjdk.java.net/browse/JDK-8246613  will mean the first 
> SecureRandom in the provider will be used as the default (which will 
> make it equivalent to JDK 11.06 and previous versions).    If that is 
> the case, I agree it should mitigate the issue and would be ok with 
> lowering the priority of 8246383.
>
> Will this new fix be back-ported into 11 LTS versions as well?
>
> Thanks so much for your amazing fast response.   I have been trying to 
> set aside some time to put together a simple sample you can use to 
> verify 8246383 (that doesn’t require our full toolkit), but haven’t 
> been able to find the time to do that yet.
>
> Cheers,
>
> John Gray
>
> *From:*Valerie Peng [mailto:valerie.peng at oracle.com]
> *Sent:* Wednesday, June 10, 2020 4:14 PM
> *To:* John Gray <John.Gray at entrustdatacard.com>; 
> security-dev at openjdk.java.net
> *Cc:* Muthu Kannappan <muthu at entrustdatacard.com>; Raj Arora 
> <Raj.Arora at entrustdatacard.com>
> *Subject:* [EXTERNAL]Re: NullPointer in 
> JceSecurity.getVerificationResult - Affects JDK 11.07, and JDK 12 and 
> later.
>
> *WARNING:* This email originated outside of Entrust Datacard.
> *DO NOT CLICK* links or attachments unless you trust the sender and 
> know the content is safe.
>
> ------------------------------------------------------------------------
>
> Hi John,
>
> As you may have noticed, we are progressing a fix for 
> https://bugs.openjdk.java.net/browse/JDK-8246613 
> <https://bugs.openjdk.java.net/browse/JDK-8246613> for returning the 
> same default SecureRandom algo for 3rd party providers as in 
> pre-JDK7092821 releases. Thus, the chance of observing JDK-8246613 
> should be lowered significantly. Given this, I plan to lower the 
> priority of JDK-8246383 and it may not be fixed in JDK 15 as earlier 
> communicated.
>
> If this will be an issue, please let me know.
>
> Thanks,
> Valerie
>
> On 6/2/2020 4:37 PM, Valerie Peng wrote:
>
>     Thanks for reporting the bug and the detailed analysis.
>
>     I have filed https://bugs.openjdk.java.net/browse/JDK-8246383 to
>     keep track of this. Will aim to fix this for 15 and have it
>     backported accordingly.
>
>     Is it possible to get hold of an test provider to reproduce and
>     verifying the fix?
>
>     Regards,
>
>     Valerie
>
>     On 6/2/2020 1:18 PM, John Gray wrote:
>
>         Hello,
>
>         At Entrust Datacard, we produce a Java based toolkit that
>         contains our own Security Provider.   This toolkit and
>         provider  has been around for about 19 years.
>
>         In JDK version 11.07 (and I also think Java 12 and beyond),
>         our toolkit reports the following error:
>
>         java.lang.RuntimeException:
>         java.security.NoSuchAlgorithmException: Error constructing
>         implementation (algorithm: X9_31usingAES256, provider:
>         Entrust, class:
>         com.entrust.toolkit.security.crypto.random.X9_31usingAES256)
>         at
>         java.base/java.security.SecureRandom.getDefaultPRNG(SecureRandom.java:281)
>         at
>         java.base/java.security.SecureRandom.<init>(SecureRandom.java:219)
>         at
>         java.base/javax.crypto.JceSecurity.<clinit>(JceSecurity.java:80)
>         ... 41 more
>         Caused by: java.security.NoSuchAlgorithmException: Error
>         constructing implementation (algorithm: X9_31usingAES256,
>         provider: Entrust, class:
>         com.entrust.toolkit.security.crypto.random.X9_31usingAES256)
>         at
>         java.base/java.security.Provider$Service.newInstance(Provider.java:1825)
>         at
>         java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
>         at
>         java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
>         at
>         java.base/java.security.SecureRandom.getInstance(SecureRandom.java:365)
>         at
>         java.base/java.security.SecureRandom.getDefaultPRNG(SecureRandom.java:273)
>         ... 43 more
>         Caused by: java.lang.NullPointerException
>         at
>         java.base/javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:203)
>         at java.base/javax.crypto.Cipher.getInstance(Cipher.java:690)
>         at java.base/javax.crypto.Cipher.getInstance(Cipher.java:625)
>         at
>         com.entrust.toolkit.security.crypto.random.X9_31usingAES256.initialize(X9_31usingAES256.java:524)
>         at
>         com.entrust.toolkit.security.crypto.random.X9_31usingAES256.<init>(X9_31usingAES256.java:102)
>         at
>         java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native
>         Method)
>         at
>         java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
>         at
>         java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
>         at
>         java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
>         at
>         java.base/java.security.Provider.newInstanceUtil(Provider.java:176)
>         at
>         java.base/java.security.Provider$Service.newInstance(Provider.java:1818)
>
>         I investigated this error, and found it was made possible
>         because of the following change in Java 11.07 which unmasked a
>         bug in the JVM that has probably been around for years.
>
>         https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8228613
>
>         It is a problem inside the JceSecurity class.  When the class
>         is being loaded, the call to setup a default SecureRandom()
>         instance is invoked.    That seems to invoke the JVM to find
>         the first available SecureRandom() instance.    This error
>         happens when our Entrust provider is in first position.   In
>         previous versions of the JDK it honoured the order of
>         algorithms specified in the providers.   In our Entrust
>         Security provider, we have a number of SecureRandom
>         implementations.   Now because of the above change, it picks a
>         different SecureRandom instance (the X9_31usingAES256).   That
>         should be fine, however the problem is that the SecureRandom()
>         setup calls Cipher.getInstance() and as you can see below,
>         that calls JceSecurity.getVerificationResult() which is
>         static, and uses the verificationResuts Map that has not yet
>         been initialized (becasuse it’s declaration is after the
>         SecureRandom setup).    That is why there is a
>         NullPointerException.
>
>         *public* *static* *final* Cipher getInstance(String
>         transformation,
>
>         Provider provider)
>
>         *throws* NoSuchAlgorithmException, NoSuchPaddingException
>
>             {
>
>         *if* ((transformation == *null*) || transformation.equals("")) {
>
>         *throw* *new* NoSuchAlgorithmException("Null or empty
>         transformation");
>
>                 }
>
>         *if* (provider == *null*) {
>
>         *throw* *new* IllegalArgumentException("Missing provider");
>
>                 }
>
>                 Exception failure = *null*;
>
>                 List<Transform> transforms =
>         getTransforms(transformation);
>
>         *boolean* providerChecked = *false*;
>
>                 String paddingError = *null*;
>
>         *for* (Transform tr : transforms) {
>
>                     Service s = provider.getService("Cipher",
>         tr.transform);
>
>         *if* (s == *null*) {
>
>         *continue*;
>
>                     }
>
>         *if* (providerChecked == *false*) {
>
>                         // for compatibility, first do the lookup and
>         then verify
>
>                         // the provider. this makes the difference
>         between a NSAE
>
>                         // and a SecurityException if the
>
>                         // provider does not support the algorithm.
>
>                         Exception ve =
>         JceSecurity.getVerificationResult(provider);
>
>         *if* (ve != *null*) {
>
>                             String msg = "JCE cannot authenticate the
>         provider "
>
>                                 + provider.getName();
>
>         *throw* *new* SecurityException(msg, ve);
>
>                         }
>
>                         providerChecked = *true*;
>
>                     }
>
>         The JceSecurity.getVerificationResult(provider) method is used
>         when initializing the SecureRandom (first highlighted line
>         below) when the classLoader is loading the JceSecurity class
>         itself.
>
>         From the JceSecurity class:
>
>         *static* *final* SecureRandom RANDOM = *new* SecureRandom();
>
>             // The defaultPolicy and exemptPolicy will be set up
>
>             // in the static initializer.
>
>         *private* *static* CryptoPermissions defaultPolicy = *null*;
>
>         *private* *static* CryptoPermissions exemptPolicy = *null*;
>
>             // Map<Provider,?> of the providers we already have verified
>
>             // value == PROVIDER_VERIFIED is successfully verified
>
>             // value is failure cause Exception in error case
>
>         *private* *static* *final* Map<Provider, Object>
>         verificationResults =
>
>         *new* IdentityHashMap<>();
>
>         It fails when it calls the following code in JceSecurity.java
>         because the verificationResults Map<Provider, Object> has not
>         been initialized because the SecureRandom() constructor ends
>         up calling the JceSecurity.getVerificationResult() static
>         method that makes use of the Map!  That explains the
>         NullPointerException.
>
>         The fix to the issue should be simple, just move the
>         initialization of the verificationResults Map BEFORE the
>         SecureRandom initialization in JceSecurity.java
>
>         Because verificationResults is not initialized, the line
>         highlighted below fails (Because the Map has not been
>         initialized).
>
>         /*
>
>              * Verify that the provider JAR files are signed properly,
>         which
>
>              * means the signer's certificate can be traced back to a
>
>              * JCE trusted CA.
>
>              * Return null if ok, failure Exception if verification
>         failed.
>
>              */
>
>         *static* *synchronized* Exception
>         getVerificationResult(Provider p) {
>
>                 Object o = verificationResults.get(p);
>
>         *if* (o == PROVIDER_VERIFIED) {
>
>         *return* *null*;
>
>                 } *else* *if* (o != *null*) {
>
>         *return* (Exception)o;
>
>                 }
>
>         *if* (verifyingProviders.get(p) != *null*) {
>
>                     // this method is static synchronized, must be
>         recursion
>
>                     // return failure now but do not save the result
>
>         *return* *new* NoSuchProviderException("Recursion during
>         verification");
>
>                 }
>
>         *try* {
>
>                     verifyingProviders.put(p, Boolean.FALSE);
>
>                     URL providerURL = getCodeBase(p.getClass());
>
>         verifyProvider(providerURL, p);
>
>                     // Verified ok, cache result
>
>         verificationResults.put(p, PROVIDER_VERIFIED);
>
>         *return* *null*;
>
>                 } *catch* (Exception e) {
>
>         verificationResults.put(p, e);
>
>         *return* e;
>
>                 } *finally* {
>
>         verifyingProviders.remove(p);
>
>                 }
>
>             }
>
>         Cheers,
>
>         John Gray
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20200611/e9e43b8b/attachment.htm>


More information about the security-dev mailing list