United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 7142172 Custom X509TrustManagers that return null for getAcceptedIssuers will NPE.
7142172 : Custom X509TrustManagers that return null for getAcceptedIssuers will NPE.

Details
Type:
Bug
Submit Date:
2012-02-02
Status:
Closed
Updated Date:
2012-07-15
Project Name:
JDK
Resolved Date:
2012-04-13
Component:
security-libs
OS:
os_x,generic,windows_7
Sub-Component:
javax.net.ssl
CPU:
x86,generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
7,7u4
Fixed Versions:
7u4

Related Reports
Backport:
Duplicate:
Duplicate:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment (build 1.7.0_04-ea-b227)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b12, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Mac OS X 10.7.3

A DESCRIPTION OF THE PROBLEM :
I receive the following exception when running on JDK 7 on OS X.  JDK 7 on Windows or Linux works, as does JDK 6 on OS X.

java.lang.NullPointerException
	at java.util.Collections.addAll(Collections.java:3836)
	at sun.security.ssl.AbstractTrustManagerWrapper.<init>(SSLContextImpl.java:778)
	at sun.security.ssl.SSLContextImpl.chooseTrustManager(SSLContextImpl.java:133)
	at sun.security.ssl.SSLContextImpl.engineInit(SSLContextImpl.java:89)
	at javax.net.ssl.SSLContext.init(SSLContext.java:283)

REGRESSION.  Last worked in version 6u29

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
We encounter the issue while running the example code attached
 


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should not throw an exception
ACTUAL -
throws NPE

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
	at java.util.Collections.addAll(Collections.java:3836)
	at sun.security.ssl.AbstractTrustManagerWrapper.<init>(SSLContextImpl.java:778)
	at sun.security.ssl.SSLContextImpl.chooseTrustManager(SSLContextImpl.java:133)
	at sun.security.ssl.SSLContextImpl.engineInit(SSLContextImpl.java:89)
	at javax.net.ssl.SSLContext.init(SSLContext.java:283)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package testssl;

import java.security.PublicKey;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import sun.misc.BASE64Encoder;

public class TestSSL {

    public static void main(String[] args) throws Exception {
        final String CERT_PBK = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCd8j2M0Ok94KVfY1wxcb6RGfHbBK2NggrDmgF60/nzQmU3Z92AYxDUqXXl9j3SsvTLwgh0HpQgTgkOeJ/1csYMy+Ij1ZtRQ2IReBd9KvCbgpmZA5o0Hgf5bT0Jh6XyJI0cGIZ5PS9lhkJcfBVcEiPMlfvo6ZxaU/Kes6BHG7yWFQIDAQAB";
        SSLContext sslContext;


        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {

        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
        }

        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
            if (certs.length == 1) {
                PublicKey publicKey = certs[0].getPublicKey();
                byte[] encodePublickey = publicKey.getEncoded();
                String s = new BASE64Encoder().encode(encodePublickey);
                if (s.compareTo(CERT_PBK) != 0) {
                    throw new Error("invalid key");
                }
            } else {
                throw new Error("Unexpected number of certs");
            }

        }

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }};

        sslContext = javax.net.ssl.SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
    }
}

---------- END SOURCE ----------

                                    

Comments
EVALUATION

This is due to the change we put in for:

7113275: compatibility issue with MD2 trust anchor and old X509TrustManager

In AbstractTrustManagerWrapper, which is used as a wrapper when the passed-in custom TM isn't a X509ExtendedTrustManager, we are now caching the accepted certificate issuers from the constructor to speed up future AlgorithmConstraints checks.

The addAll(..., null) is throwing the NPE when getAcceptedIssuers is returning null.

There is one other place that calls getAcceptedIssuers, and that's in the ServerHandshaker when we do client authentication.  We'll also throw a NPE there if someone passes in a custom TM that has this behavior.  However, I think this is not normally seen because most applications don't do client auth by default, and don't provide custom trustmanagers with this broken behavior.  This behavior has been there since at least 1.4.2 FCS, so don't feel it's necessary to fix here.

To fix it, we can either remove the caching, or we can check for null during the initialization.  I'm leaning toward the latter, but the former is the safest.
                                     
2012-03-30
EVALUATION

I prefer to checking the null value before adding it to the collection.

Please note that if X509TrustManager.getAcceptedIssuers() does not return the expected trusted issuers as the specification required, it does not grant the application will work as expected during algorithm constraints checking.  The algorithm constraints is expected to ignoring the trusted certificates checking (I think TM.getAcceptedIssuers() return null does not means that there is no trusted certificate), but if the accepted issuers is null or empty, the checking will be done on every cert in the chain.
                                     
2012-03-30
PUBLIC COMMENTS

Please note that getAcceptedIssuers() API does not allow a null entry to be returned.  It must be non-null, possibly empty.

Close as "not a defect".
                                     
2012-02-03



Hardware and Software, Engineered to Work Together