2

I found if I turn on fips mode, the JRE only allow SunJSSE TrustManagers and KeyManagers when you create a SSLContext to do SSL handshake. I google the source code of sun.security.ssl.SSLContextImpl, and found the following code:

in chooseTrustManager(TrustManager[] tm) function:

if (tm[i] instanceof X509TrustManager) {
   if (SunJSSE.isFIPS() && !(tm[i] instanceof X509TrustManagerImpl)) {
      throw new KeyManagementException
      ("FIPS mode: only SunJSSE TrustManagers may be used");
   }
}

in chooseKeyManager(KeyManager[] kms) function:

if ((km instanceof X509KeyManagerImpl) || (km instanceof SunX509KeyManagerImpl)) {
    return (X509ExtendedKeyManager)km;
} else {
    // throw exception, we don't want to silently use the
    // dummy keymanager without telling the user.
    throw new KeyManagementException
        ("FIPS mode: only SunJSSE KeyManagers may be used");
}

like the above code shows, the trustmanger must be instance of X509TrustManagerImpl class, and this class is final, so it could not be extended.

But I want to do additional check to the subject of certificate when doing SSL handshake, so I use a customized trust manager which extends X509TrustManager class to do additional check in checkServerTrusted() and checkClientTrusted() function. But it results in the exception "FIPS mode: only SunJSSE TrustManagers may be used" when turn on fips mode.

Although I know forcing user to SunJSSE TrustManagers is for FIPS mode requirement, but I'm curious if there is any other way to fulfill my requirement to do the additional check if I can't use customized trustmanagerr or keymanger?

hyderai
  • 31
  • 1
  • 4
  • 1
    Can't you do `getPeerCertificates()` after generating the connection but before doing anything with it? – Maarten Bodewes Apr 13 '17 at 23:25
  • Yes, that's a good point, some code could move to the position after generating the connection. But some code seems to be hard to be moved. e.g. I prefer to use my customization exception instead of throwing CertificateException out directly in checkServerTrusted(chain, authtype), It could help developer to debug with friendly customized description, in this situation, it seems to be hard to refactor it to other places because the CertificateException will not contain the information about chain and authtype, I have no enough information to wrap it into my customization exception. – hyderai Apr 14 '17 at 11:49
  • FIPS mode defines the architecture, not you. You will just have to do it all via `getPeerCertificates(), probably in a `HandshakeCompletedListener`. – user207421 Apr 30 '17 at 04:32
  • Could you elaborate on "Although I know forcing user to SunJSSE TrustManagers is for FIPS mode requirement"? Do you mean that another provider such as BouncyCastle JSSE (BCJSSE) cannot be used? I ask because in a project I'm working on, I chose the path of creating a fork of BCJSSE's code to satisfy our needs and fully control the handshake. Now that I read this I'm concerned, but not quite sure you're right, as BCJSSE has FIPS mode support. In addition, this method that I followed could be a way to solve the original problem, since you can then customize BCJSSE's ProvX509TrustManagerImpl. – Jose Cifuentes Jan 25 '18 at 18:01
  • I don't use thirdparty library BCJSSE to replace SunJSSE. What I said is for the error message "FIPS mode: only SunJSSE TrustManagers may be used", it's the error message from SunJSSE. I guess it's ok to use another provder if it meets FIPS spec. – hyderai Mar 04 '18 at 14:04

0 Answers0