<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p
{mso-style-priority:99;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
span.EmailStyle19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:#0070C0;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">Thanks Valerie!<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">If I understand you correctly, I think you are saying the fix for
</span><span style="color:black"><a href="https://bugs.openjdk.java.net/browse/JDK-8246613"><span style="color:black">https://bugs.openjdk.java.net/browse/JDK-8246613</span></a> 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.
<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:black"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:black">Will this new fix be back-ported into 11 LTS versions as well?
<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:black"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:black">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:black"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:black">Cheers,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:black"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:black">John Gray<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#0070C0"><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Valerie Peng [mailto:valerie.peng@oracle.com]
<br>
<b>Sent:</b> Wednesday, June 10, 2020 4:14 PM<br>
<b>To:</b> John Gray <John.Gray@entrustdatacard.com>; security-dev@openjdk.java.net<br>
<b>Cc:</b> Muthu Kannappan <muthu@entrustdatacard.com>; Raj Arora <Raj.Arora@entrustdatacard.com><br>
<b>Subject:</b> [EXTERNAL]Re: NullPointer in JceSecurity.getVerificationResult - Affects JDK 11.07, and JDK 12 and later.<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><strong><span style="color:red">WARNING:</span></strong> This email originated outside of Entrust Datacard.<br>
<strong><span style="color:red">DO NOT CLICK</span></strong> links or attachments unless you trust the sender and know the content is safe.<o:p></o:p></p>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="100%" align="center">
</div>
<p>Hi John,<o:p></o:p></p>
<p>As you may have noticed, we are progressing a fix for <a href="https://bugs.openjdk.java.net/browse/JDK-8246613">
https://bugs.openjdk.java.net/browse/JDK-8246613</a> 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.
<o:p></o:p></p>
<p>If this will be an issue, please let me know.<o:p></o:p></p>
<p class="MsoNormal">Thanks,<br>
Valerie<o:p></o:p></p>
<div>
<p class="MsoNormal">On 6/2/2020 4:37 PM, Valerie Peng wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p>Thanks for reporting the bug and the detailed analysis.<o:p></o:p></p>
<p>I have filed <a href="https://bugs.openjdk.java.net/browse/JDK-8246383">https://bugs.openjdk.java.net/browse/JDK-8246383</a> to keep track of this. Will aim to fix this for 15 and have it backported accordingly.<o:p></o:p></p>
<p>Is it possible to get hold of an test provider to reproduce and verifying the fix?<o:p></o:p></p>
<p>Regards,<o:p></o:p></p>
<p class="MsoNormal">Valerie<o:p></o:p></p>
<div>
<p class="MsoNormal">On 6/2/2020 1:18 PM, John Gray wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Hello,<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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.
<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">In JDK version 11.07 (and I also think Java 12 and beyond), our toolkit reports the following error:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">java.lang.RuntimeException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: X9_31usingAES256, provider: Entrust, class: com.entrust.toolkit.security.crypto.random.X9_31usingAES256)<br>
at java.base/java.security.SecureRandom.getDefaultPRNG(SecureRandom.java:281)<br>
at java.base/java.security.SecureRandom.<init>(SecureRandom.java:219)<br>
at java.base/javax.crypto.JceSecurity.<clinit>(JceSecurity.java:80)<br>
... 41 more<br>
Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: X9_31usingAES256, provider: Entrust, class: com.entrust.toolkit.security.crypto.random.X9_31usingAES256)<br>
at java.base/java.security.Provider$Service.newInstance(Provider.java:1825)<br>
at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:236)<br>
at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:164)<br>
at java.base/java.security.SecureRandom.getInstance(SecureRandom.java:365)<br>
at java.base/java.security.SecureRandom.getDefaultPRNG(SecureRandom.java:273)<br>
... 43 more<br>
Caused by: java.lang.NullPointerException<br>
at java.base/javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:203)<br>
at java.base/javax.crypto.Cipher.getInstance(Cipher.java:690)<br>
at java.base/javax.crypto.Cipher.getInstance(Cipher.java:625)<br>
at com.entrust.toolkit.security.crypto.random.X9_31usingAES256.initialize(X9_31usingAES256.java:524)<br>
at com.entrust.toolkit.security.crypto.random.X9_31usingAES256.<init>(X9_31usingAES256.java:102)<br>
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)<br>
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)<br>
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)<br>
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)<br>
at java.base/java.security.Provider.newInstanceUtil(Provider.java:176)<br>
at java.base/java.security.Provider$Service.newInstance(Provider.java:1818)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><a href="https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8228613" target="_blank">https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8228613</a><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b>public</b>
<b>static</b> <b>final</b> Cipher getInstance(String transformation,<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> Provider provider)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>throws</b> NoSuchAlgorithmException, NoSuchPaddingException<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>if</b> ((transformation == <b>null</b>) || transformation.equals("")) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>throw</b> <b>new</b> NoSuchAlgorithmException("Null or empty transformation");<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>if</b> (provider == <b>null</b>) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>throw</b> <b>new</b> IllegalArgumentException("Missing provider");<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> Exception failure =
<b>null</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> List<Transform> transforms = getTransforms(transformation);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>boolean</b> providerChecked = <b>false</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> String paddingError =
<b>null</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>for</b> (Transform tr : transforms) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> Service s = provider.getService("Cipher", tr.transform);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>if</b> (s == <b>null</b>) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>continue</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>if</b> (providerChecked == <b>false</b>) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // for compatibility, first do the lookup and then verify<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // the provider. this makes the difference between a NSAE<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // and a SecurityException if the<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // provider does not support the algorithm.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> Exception ve = JceSecurity.getVerificationResult(provider);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <b>if</b> (ve !=
<b>null</b>) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> String msg = "JCE cannot authenticate the provider "<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> + provider.getName();<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>throw</b> <b>new</b> SecurityException(msg, ve);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> providerChecked =
<b>true</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The JceSecurity.getVerificationResult(provider) method is used when initializing the SecureRandom (first highlighted line below) when the classLoader is loading the JceSecurity
class itself. <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">From the JceSecurity class:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b>static</b>
<b>final</b> SecureRandom RANDOM = <b>new</b> SecureRandom();<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // The defaultPolicy and exemptPolicy will be set up<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // in the static initializer.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>private</b> <b>static</b> CryptoPermissions defaultPolicy = <b>null</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>private</b> <b>static</b> CryptoPermissions exemptPolicy = <b>null</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // Map<Provider,?> of the providers we already have verified<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // value == PROVIDER_VERIFIED is successfully verified<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // value is failure cause Exception in error case<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>private</b> <b>static</b> <b>final</b> Map<Provider, Object> verificationResults =<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>new</b> IdentityHashMap<>();<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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.
<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The fix to the issue should be simple, just move the initialization of the verificationResults Map BEFORE the SecureRandom initialization in JceSecurity.java<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Because verificationResults is not initialized, the line highlighted below fails (Because the Map has not been initialized).<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">/*<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> * Verify that the provider JAR files are signed properly, which<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> * means the signer's certificate can be traced back to a<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> * JCE trusted CA.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> * Return null if ok, failure Exception if verification failed.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> */<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>static</b> <b>synchronized</b> Exception getVerificationResult(Provider p) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> Object o = verificationResults.get(p);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>if</b> (o == PROVIDER_VERIFIED) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>return</b> <b>null</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }
<b>else</b> <b>if</b> (o != <b>null</b>) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>return</b> (Exception)o;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>if</b> (verifyingProviders.get(p) != <b>null</b>) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // this method is static synchronized, must be recursion<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // return failure now but do not save the result<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>return</b> <b>new</b> NoSuchProviderException("Recursion during verification");<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>try</b> {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> verifyingProviders.put(p, Boolean.FALSE);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> URL providerURL = getCodeBase(p.getClass());<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> verifyProvider(providerURL, p);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> // Verified ok, cache result<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> verificationResults.put(p, PROVIDER_VERIFIED);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>return</b> <b>null</b>;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }
<b>catch</b> (Exception e) {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> verificationResults.put(p, e);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<b>return</b> e;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }
<b>finally</b> {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> verifyingProviders.remove(p);<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Cheers,<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">John Gray<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">
<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
</blockquote>
</blockquote>
</div>
</body>
</html>