20

I am having an issue with a api that I communicate to via SSL. I am thinking the exception is coming due to the fact that the SSL cert has expired. The problem is that I do not administer the API box. Is it possible to ignore expired certificates?

Exception:

[ERROR,TaacWorkshop] Problem deleting user group from CADA: 
org.apache.thrift.transport.TTransportException: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
    at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:156)
    at company.oss.thrift.cada.CADABackend$Client.send_DeleteUserGroup(CADABackend.java:580)
    at company.oss.thrift.cada.CADABackend$Client.DeleteUserGroup(CADABackend.java:568)
    at com.cable.company.nse.cada.CadaDao.deleteUserGroup(CadaDao.java:72)
    at com.cable.company.nse.taac.business.TaacWorkshop.deleteTaac(TaacWorkshop.java:127)
    at com.cable.company.nse.taac.controller.RemoteVendorAccessController.processRequest(RemoteVendorAccessController.java:130)
    at com.cable.company.nse.taac.controller.RemoteVendorAccessController$$FastClassByCGLIB$$63639bdf.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:67)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
    at com.cable.company.nse.taac.controller.RemoteVendorAccessController$$EnhancerByCGLIB$$bdd8aaad.processRequest(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:592)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:563)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:613)
Caused by: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1232)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.java:1244)
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:43)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
    at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:154)
    ... 66 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1584)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:877)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:618)
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
    at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:154)
    at company.oss.thrift.cada.CADABackend$Client.send_CreateUserGroup(CADABackend.java:546)
    at company.oss.thrift.cada.CADABackend$Client.CreateUserGroup(CADABackend.java:534)
    at com.cable.company.nse.cada.CadaDao.createUserGroup(CadaDao.java:93)
    at com.cable.company.nse.taac.business.TaacWorkshop.createTaac(TaacWorkshop.java:210)
    at com.cable.company.nse.taac.controller.RemoteVendorAccessController.processRequest(RemoteVendorAccessController.java:111)
    ... 61 more
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
    at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:187)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:130)
    at sun.security.validator.Validator.validate(Validator.java:203)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
    at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
    ... 76 more
Caused by: java.security.cert.CertPathValidatorException: timestamp check failed
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139)
    at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:316)
    at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178)
    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:206)
    at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:182)
    ... 81 more
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Sat Jul 17 13:44:42 MDT 2010
    at sun.security.x509.CertificateValidity.valid(CertificateValidity.java:256)
    at sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:570)
    at sun.security.provider.certpath.BasicChecker.verifyTimestamp(BasicChecker.java:157)
    at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:109)
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:117)
    ... 85 more

The current code has to be able to set a trust store, because there is a Client cert authentication. I have tried the below suggestions, but still run into some problem. Here is the current code I use:

        KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType());
        ClassPathResource keystore = new ClassPathResource(cadaBackendCertFile);

        identityStore.load(keystore.getInputStream(), cadaBackendCertFilePassword.toCharArray());

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(identityStore, cadaBackendCertFilePassword.toCharArray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(identityStore);

        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

        SSLSocketFactory fac = ctx.getSocketFactory();
        Socket sslsock = fac.createSocket(cadaBackendEndpoint, cadaBackendPort);
        TTransport transport = new TSocket(sslsock);

Changed that code to the following, and am getting server issues, but it fixed my problem with the security exception:

        KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType());
        ClassPathResource keystore = new ClassPathResource(cadaBackendCertFile);

        identityStore.load(keystore.getInputStream(), cadaBackendCertFilePassword.toCharArray());

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(identityStore, cadaBackendCertFilePassword.toCharArray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(identityStore);

        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(kmf.getKeyManagers(), new TrustManager[] {new X509TrustManager(){
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
            public void checkServerTrusted(X509Certificate[] chain,String authType) throws CertificateException {               
            }
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }       
        }}, new SecureRandom());

        SSLSocketFactory fac = ctx.getSocketFactory();
        Socket sslsock = fac.createSocket(cadaBackendEndpoint, cadaBackendPort);
        TTransport transport = new TSocket(sslsock);

        TProtocol proto = new TBinaryProtocol(transport);
        cadaBackendClient = new Client(proto);

Actually - even that above code throws an exception:

ERROR[com.cable.nse.cada.CadaDaoTest][main] - Error:
org.apache.thrift.transport.TTransportException: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
    at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:156)
    at .oss.thrift.cada.CADABackend$Client.send_UserDetails(CADABackend.java:328)
    at .oss.thrift.cada.CADABackend$Client.UserDetails(CADABackend.java:316)
    at com.cable.nse.cada.CadaDao.getUserDetails(CadaDao.java:136)
    at com.cable.nse.cada.CadaDaoTest.testCada(CadaDaoTest.java:73)
    at com.cable.nse.cada.CadaDaoTest.test(CadaDaoTest.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:592)
    at junit.framework.TestCase.runTest(TestCase.java:154)
    at junit.framework.TestCase.runBare(TestCase.java:127)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:118)
    at junit.framework.TestSuite.runTest(TestSuite.java:208)
    at junit.framework.TestSuite.run(TestSuite.java:203)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:117)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1650)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:618)
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
    at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:154)
    ... 23 more
wuntee
  • 12,170
  • 26
  • 77
  • 106
  • In your edited version, you're using the same keystore for the keymanager and the trustmanager (which might be intended, not sure). If you're not using client-certificate authentication, you don't need it, use `null` as the first argument of `SSLContext.init(...)`. If client-certificate authentication is optionally requested by the server and the client sends a certificate the server doesn't accept, you'll get this sort of error. – Bruno Sep 08 '10 at 22:48
  • I do have client side cert auth. The keystore contains both the client cert as well as the self signed cert for the endpoint. So, the error is most likely because the server is not accepting the cert? – wuntee Sep 09 '10 at 14:56

3 Answers3

10

It is not safe to alter the default SSLContext since it affects the entire process. This lowers the security setting of every connection indiscriminately. It may also not be thread-safe although I am not sure.

I recommend delegating such operations to a separate process per-request.

String content = new HttpsNoVerify.fetch(URL.create(myURL));

Listing of com/example/HttpsNoVerify.java:

package com.example;

import org.apache.commons.io.IOUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.net.URL;

public class HttpsNoVerify {
    public static void main(String... args) throws Exception {
        URL url = new URL(args[0]);

        TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}
                public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType){}
                public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType){}
            }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        IOUtils.copy(url.openStream(), System.out);
    }

    public String fetch(URL url) throws Exception {
        return new SubProcess(HttpsNoVerify.class).run(url.toString());
    }
}

Listing of com/example/SubProcess.java:

package com.example;

import org.apache.commons.io.IOUtils;

import java.util.Arrays;

public class SubProcess {
    private final Class<?> classToRun;

    public SubProcess(Class<?> classToRun) {
        this.classToRun = classToRun;
    }

    public String run(String... args) throws Exception {
        ProcessBuilder processBuilder = new ProcessBuilder("java",
                "-Djava.library.path=" + System.getProperty("java.library.path"),
                "-classpath", System.getProperty("java.class.path"),
                classToRun.getCanonicalName());

        for (String arg : args) processBuilder.command().add(arg);

        processBuilder.redirectErrorStream();

        Process process = processBuilder.start();

        String output = IOUtils.toString(process.getInputStream());

        process.waitFor();

        if (process.exitValue() != 0)
            throw new IllegalStateException(
                    String.format("Running %s with %s failed", classToRun, Arrays.toString(args)));

        return output;
    }
}
Alain O'Dea
  • 21,033
  • 1
  • 58
  • 84
  • I suppose you mean "It is not safe to alter the *default* SSLContext", with which I'd agree. – Bruno Sep 08 '10 at 20:05
  • I have added the code I use - I tried to create the new trust manager, but was getting a "javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown" exception... – wuntee Sep 08 '10 at 20:26
  • Sorry, I am thinking this exception is coming from the server. Specifically it is: org.apache.thrift.transport.TTransportException: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown – wuntee Sep 08 '10 at 20:45
  • Thinking that that 'certificate_unknown' exception is the client side... any idea why that would be being thrown? – wuntee Sep 08 '10 at 21:51
  • 1
    @wuntee, I would *strongly* recommend against using this `TrustManager`, which doesn't check anything about any server certificate this client may connect to. Instead, you could use the variant I suggested in my answer where (a) you only catch the `CertificateExpiredException` and (b) potentially ignore it once you've verified this was the certificate you wanted (from `chain[0]`). – Bruno Sep 08 '10 at 22:42
  • @wuntee @Bruno's TrustManager is definitely preferable to the no-op one I use here. I would combine my process-based approach with his TrustManager to get a holistic solution. – Alain O'Dea Sep 09 '10 at 12:17
  • i was going to add more logic, initially i was just trying to get it working... thanks – wuntee Sep 09 '10 at 14:57
  • @Alain, one of the motivations for writing jSSLutils and its wrappers was to be able to use the existing trust managers (with minimal configuration), while being able to catch and handle certain cases and exceptions. It just makes it slightly easier to use I think, by being able to access the "origManager" in my example (which would be the one set up without specific settings here. – Bruno Sep 10 '10 at 11:07
3

I'm not aware of a property that would let you ignore the time validity check on the remote certificate for the default X509TrustManagers, but if you have access to the client code, you can probably configure a different SSLContext with your own X509TrustManager, within which you could catch this exception.

If you want to use something like jSSLutils and its SSLContextFactory, you could write a wrapper along these lines:

PKIXSSLContextFactory sslContextFactory = new PKIXSSLContextFactory();
sslContextFactory.setTrustManagerWrapper(new X509TrustManagerWrapper() {
    @Override
    public X509TrustManager wrapTrustManager(final X509TrustManager origManager) {
        return new X509TrustManager() { 
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return origManager.getAcceptedIssuers();
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain,
                                                   String authType)
                    throws CertificateException {
                try {
                    origManager.checkServerTrusted(chain, authType);
                } catch (CertificateExpiredException e) {
                    // TODO log or do something else to rethrow
                                    // the exception if chain[0] isn't the certificate
                                    // for which you want to make this special case.
                }
            }

            @Override
            public void checkClientTrusted(X509Certificate[] chain,
                                                   String authType)
                    throws CertificateException {
                origManager.checkClientTrusted(chain, authType);
            }
        };
    }
});
SSLContext sslContext = sslContextFactory.buildSSLContext();

Making use of this SSLContext then really depends on what uses SSL in your application. In the worst case, you can configure it globally using SSLContext.setDefault(sslContext) with Java 6 and above. Otherwise, some libraries will let you configure an SSLContext.

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • 1
    Isn't this very fragile - if another check is done after the date/time checking it will be skipped silently? – dascandy Feb 19 '13 at 09:23
  • @dascandy, you're absolutely right. I had completely forgotten about this answer, but I've mentioned something along these lines in [this similar answer](http://stackoverflow.com/a/13742250/372643). – Bruno Feb 19 '13 at 09:47
-5

i think you can download the cert and add it to your store. You then configure your jvm with environment properties to indicate where the store is.

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
  • 1
    that is already what i am doing. the problem is that the cert has expired, and causing the exception. i was hoping there is some property you can set to ignore expired keys. – wuntee Sep 08 '10 at 18:27
  • adding this cert won't resolve problem, because this cert is outdated (expired). then it won't pass verification. – Znik Jul 14 '16 at 14:01