DisableSslCertificateCheckUtil.java
package net.trajano.commons.testing;
import static javax.net.ssl.HttpsURLConnection.getDefaultHostnameVerifier;
import static javax.net.ssl.HttpsURLConnection.getDefaultSSLSocketFactory;
import static javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier;
import static javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory;
import java.io.IOException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import net.trajano.commons.testing.internal.NullHostnameVerifier;
import net.trajano.commons.testing.internal.NullX509TrustManager;
/**
* Disables SSL certificate checks. Primarily used for doing integration testing
* against self-signed servers.
*/
public final class DisableSslCertificateCheckUtil {
/**
* Flag to indicate that certificate checks are disabled. If this is true,
* then the process to disable the checks are not executed again.
*/
private static boolean disabled;
/**
* Logger.
*/
private static final Logger LOG = Logger
.getLogger(DisableSslCertificateCheckUtil.class.getName(),
"META-INF.Messages");
/**
* Null host name verifier. Made it a constant to prevent new
* instantiations. Made public so the instance can be retrieved directly.
*/
public static final HostnameVerifier NULL_HOSTNAME_VERIFIER = new NullHostnameVerifier();
/**
* Null trust manager. Made it a constant to prevent new instantiations.
* Made public so the instance can be retrieved directly.
*/
public static final X509TrustManager NULL_TRUST_MANAGER = new NullX509TrustManager();
/**
* Original hostname verifier, set by {{@link #disableChecks()}.
*/
private static HostnameVerifier originalHostnameVerifier;
/**
* Original SSL Socket factory, set by {{@link #disableChecks()}.
*/
private static SSLSocketFactory originalSslSocketFactory;
/**
* <p>
* Constructs an unsecure SSL context. This SSL context is configured with a
* {@link #NULL_TRUST_MANAGER}. There is no guarantee that the
* {@link SSLContext} is thread-safe so new ones have to get created in
* order to be safe.
* </p>
* <p>
* The <code>TLSv1</code> is guaranteed to be present according to the
* {@link SSLContext} javadoc. The {@link SSLContext#getInstance(String)}
* method is used rather than {@link SSLContext#getDefault()} as the default
* context would have already been initialized therefore it would not allow
* us to execute
* {@link SSLContext#init(javax.net.ssl.KeyManager[], TrustManager[], java.security.SecureRandom)}
* .
* </p>
*
* @return an unsecure SSL context.
* @throws GeneralSecurityException
*/
public static SSLContext buildUnsecureSslContext()
throws GeneralSecurityException {
final SSLContext context = SSLContext.getInstance("TLSv1");
final TrustManager[] trustManagerArray = { NULL_TRUST_MANAGER };
context.init(null, trustManagerArray, null);
return context;
}
/**
* Disable trust checks for SSL connections. Saves the present ones if it is
* not the disabled ones.
*
* @throws GeneralSecurityException
* thrown when there is a problem disabling the SSL. Shouldn't
* happen unless there is something wrong with the Java
* implementation.
*/
public static void disableChecks() throws GeneralSecurityException {
if (disabled) {
return;
}
try {
new URL("https", "0", "/").getContent();
} catch (final IOException e) {
// This invocation will always fail, but it will register the
// default SSL provider to the URL class.
LOG.log(Level.FINEST,
"DisableSSLCertificateCheckUtil.disableCertificateCheck", e);
}
originalSslSocketFactory = getDefaultSSLSocketFactory();
originalHostnameVerifier = getDefaultHostnameVerifier();
final SSLContext context = buildUnsecureSslContext();
setDefaultSSLSocketFactory(context.getSocketFactory());
setDefaultHostnameVerifier(NULL_HOSTNAME_VERIFIER);
disabled = true;
}
/**
* This will re-enable the SSL checks after it was disabled by
* {@link #disableChecks()}.
*/
public static void reenableChecks() {
if (!disabled) {
return;
}
setDefaultSSLSocketFactory(originalSslSocketFactory);
setDefaultHostnameVerifier(originalHostnameVerifier);
disabled = false;
}
/**
* Prevent instantiation of utility class.
*/
private DisableSslCertificateCheckUtil() {
}
}