Here is the solution obtained by combining java - ignore expired ssl certificate and Java SSL: how to disable hostname verification.
public class IgnoreExpiredServerCertificateAgent {
public static void premain(String args, Instrumentation inst) throws Exception {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
TrustManager[] trustManagers = tmf.getTrustManagers();
final X509TrustManager origTrustManager = (X509TrustManager) trustManagers[0];
TrustManager[] wrappedTrustManagers = new TrustManager[]{
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return origTrustManager.getAcceptedIssuers();
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
origTrustManager.checkClientTrusted(certs, authType);
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
try {
origTrustManager.checkServerTrusted(certs, authType);
} catch (CertificateExpiredException ignored) {
}
}
}
};
//SSLContext sc = SSLContext.getDefault();
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, wrappedTrustManagers, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
}
Then just add -javaagent:IgnoreExpiredServerCertificateAgent.jar
to program's java startup arguments.
See also Difference between SSL and TLS and their usage in Java and Java 8 SSLContext.getInstance("TLSv1.2") what does it mean? for appropriate argument for SSLContext.getInstance()
in your case.
Also note that the server with expired certificate may also itself check the expiry of the matching client certificate:
Caused by:javax.net.ssl.SSLHandshakeException: Received fatal alert:
certificate_expired at
com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at
com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199)
at
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195)
at
java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
at
sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
If you meet such stacktrace then there is no way to mitigate the problem without touching the server.
And the proper solution would be to reissue the certificate with future expiry date.