JDBC Error: FIPS mode: only SunJSSE TrustManagers may be used - by gsimone

Status : 

  Won't Fix<br /><br />
		Due to several factors the product team decided to focus its efforts on other items.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 790326 Comments
Status Closed Workarounds
Type Bug Repros 2
Opened 6/17/2013 11:16:35 AM
Access Restriction Public


Java has an option to use Microsoft cryptography libraries instead of the built-in cryptography libraries provided by the JDK.  We would like to use this feature because the Microsoft code is FIPS validated.  In fact once you switch to the Microsoft cryptography libraries, the JVM automatically sets it's "FIPS mode" bit.

Unfortunately when we attempt to use this feature, the SQL Server JDBC driver fails with an exception any time we try to connect to our SQL Server database.   Note that in our specific case, we don't actually require that the JDBC connection to SQL Server be encrypted.  We are using SSL for server-to-server connections elsewhere in the JVM. However once the JVM switches into FIPS mode, the JDBC driver becomes completely unusable and we cannot connect to any SQL Server database, regardless of whether we connect using encryption or not.

Current workaround is to continue using the SQL Server JDBC driver, but not use the Microsoft cryptography libraries.
Sign in to post a comment.
Posted by scorbie00 on 6/27/2013 at 8:25 AM
We received the same error when attempting to use Java's FIPS mode. We did some investigation into the root cause and found that the method below from sun.security.ssl.SSLContextImpl is what is throwing the error:

     private X509TrustManager [More ...] chooseTrustManager(TrustManager[] tm)
             throws KeyManagementException {

         // We only use the first instance of X509TrustManager passed to us.
         for (int i = 0; tm != null && i < tm.length; i++) {
             if (tm[i] instanceof X509TrustManager) {
                 if (SunJSSE.isFIPS() &&
                         !(tm[i] instanceof X509TrustManagerImpl)) {
                     throw new KeyManagementException("FIPS mode: only SunJSSE TrustManagers may be used");
                 if (tm[i] instanceof X509ExtendedTrustManager) {
                     return (X509TrustManager)tm[i];
                 } else {
                     return new AbstractTrustManagerWrapper((X509TrustManager)tm[i]);
         // nothing found, return a dummy X509TrustManager.
         return DummyX509TrustManager.INSTANCE;

Looking into the JDBC driver, you can see that the first TrustManager set in the Array every time is one that does not extend the X509TrustManagerImpl class. While you may argue whether this is a valid check in Java, at the end of the day we are at an impasse. Maybe the JDBC driver can do a check to see if Java is in FIPS mode and the defer to the SunJSSE but default to the current behavior if not in FIPS mode.