This is a JSSE provider that provides logging for entrance and exit of the trust manager, delegating to the original KeyManager
and TrustManager
.
This works on all JSSE implementations, but is transparent, and logs before and after every call.
This only works on "SunJSSE" right now.
More info in the blog post.
Packages are hosted on jCenter:
<repositories>
<repository>
<id>central</id>
<name>bintray</name>
<url>http://jcenter.bintray.com</url>
</repository>
</repositories>
<dependency>
<groupId>com.tersesystems.debugjsse</groupId>
<artifactId>debugjsse</artifactId>
<version>0.5.2</version><!-- see badge for latest version -->
</dependency>
resolvers += Resolver.jcenterRepo
libraryDependencies += "com.tersesystems.debugjsse" % "debugjsse" % "0.5.0"
The security provider must be installed before it will work.
Calling enable
will set the debug provider at the highest level, so it preempts "SunJSSE" and then delegates to it.
DebugJSSEProvider provider = DebugJSSEProvider.enable();
You can install the provider statically by adding the provider as the highest priority item in <java-home>/conf/security/java.security
:
security.provider.1=debugJSSE|com.tersesystems.debugjsse.DebugJSSEProvider
You can change the Debug
instance by calling setDebug
:
Debug sysErrDebug = new PrintStreamDebug(System.err);
provider.setDebug(sysErrDebug);
And you can add your own logging framework by extending AbstractDebug
:
org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger("Main");
Debug slf4jDebug = new AbstractDebug() {
@Override
public void enter(String message) {
logger.debug(message);
}
@Override
public void exit(String message) {
logger.debug(message);
}
@Override
public void exception(String message, Exception e) {
logger.error(message, e);
}
};
Full example here:
import com.tersesystems.debugjsse.AbstractDebug;
import com.tersesystems.debugjsse.Debug;
import com.tersesystems.debugjsse.DebugJSSEProvider;
import org.slf4j.LoggerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509ExtendedTrustManager;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Arrays;
public class Main {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger("Main");
private static final Debug slf4jDebug = new AbstractDebug() {
@Override
public void enter(String message) {
logger.debug(message);
}
@Override
public void exit(String message) {
logger.debug(message);
}
@Override
public void exception(String message, Exception e) {
logger.error(message, e);
}
};
public static void main(String[] args) throws Exception {
DebugJSSEProvider.enable().setDebug(slf4jDebug);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
SSLEngine sslEngine = sslContext.createSSLEngine();
System.out.println("sslEngine = " + sslEngine);
}
}
Produces the output:
2018-08-05 11:47:15,108 DEBUG [main] - enter: [email protected](keyManagers = null, trustManagers = null, secureRandom = null)
2018-08-05 11:47:15,111 DEBUG [main] - enter: [email protected]: args = null
2018-08-05 11:47:15,184 DEBUG [main] - exit: [email protected]: args = null => null
2018-08-05 11:47:15,184 DEBUG [main] - enter: [email protected]()
2018-08-05 11:47:15,185 DEBUG [main] - exit: [email protected]() => [trustManager1-1533494835185@627185331]
2018-08-05 11:47:15,186 DEBUG [main] - exit: [email protected](keyManagers = null, trustManagers = null, secureRandom = null) => null
2018-08-05 11:47:15,186 DEBUG [main] - enter: [email protected]()
2018-08-05 11:47:15,190 DEBUG [main] - exit: [email protected]() => 2a18f23c[SSLEngine[hostname=null port=-1] SSL_NULL_WITH_NULL_NULL]
sslEngine = 2a18f23c[SSLEngine[hostname=null port=-1] SSL_NULL_WITH_NULL_NULL]
Uses Maven Release Plugin:
mvn release:prepare
mvn release:perform