Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Asked Answered
H

2

5

A spring mvc app uses JavaMail to connect to dovecot/postfix. Both the spring mvc app and the dovecot/postfix installation are running on the same CentOS 7 physical server box. The app was able to use JavaMail to successfully make an imap connection until just recently, when some scripts for setting up OpenVPN seem to have changed things including the SSL configuration. How can I change the JavaMail code (or other configuration parameters) to get the IMAP connection to work again?

The root error I am currently getting is:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException:  
unable to find valid certification path to requested target  

The line of code that throws this error is:

store.connect("hostname", "username", "password");

The context of this code is:

Properties props = new Properties();
props.setProperty("mail.imap.starttls.enable", "true");
props.setProperty("mail.store.protocol", "imap");
props.setProperty("mail.imap.partialfetch", "false");
String dirStart = "/home/import/xml/xmlimporttest/";
try {
    Session session = Session.getInstance(props, null);
    session.setDebug(true);
    Store store = session.getStore();
    store.connect("hostname", "username", "password");
    Folder inbox = store.getFolder("INBOX");  
    //other stuff
} catch....

The complete stack trace is:

DEBUG: setDebug: JavaMail version 1.5.0-b01
DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle]
DEBUG IMAP: mail.imap.partialfetch: false
DEBUG IMAP: mail.imap.ignorebodystructuresize: false
DEBUG IMAP: mail.imap.statuscachetimeout: 1000
DEBUG IMAP: mail.imap.appendbuffersize: -1
DEBUG IMAP: mail.imap.minidletime: 10
DEBUG IMAP: enable STARTTLS
DEBUG IMAP: trying to connect to host "mydomain.com", port 143, isSSL false
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS LOGINDISABLED] Dovecot ready.
DEBUG IMAP: protocolConnect login, host=mydomain.com, user=username, password=<non-null>
A0 STARTTLS  
A0 OK Begin TLS negotiation now.
DEBUG IMAP: STARTTLS Exception, THROW:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable$
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1904)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:279)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:273)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1446)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:209)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:901)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:837)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1023)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:527)
    at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:464)
    at com.sun.mail.iap.Protocol.startTLS(Protocol.java:388)
    at com.sun.mail.imap.protocol.IMAPProtocol.startTLS(IMAPProtocol.java:820)
    at com.sun.mail.imap.IMAPStore.login(IMAPStore.java:697)
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:642)
    at javax.mail.Service.connect(Service.java:295)
    at javax.mail.Service.connect(Service.java:176)        at com.hpp.kp.web.HL7PatientController.processInbox(HL7PatientController.java:1373)
    at com.hpp.kp.web.HL7PatientController.processEmailInbox(HL7PatientController.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.github.dandelion.datatables.core.web.filter.DatatablesFilter.doFilter(DatatablesFilter.java:73)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.github.dandelion.datatables.extras.servlet2.filter.DatatablesFilter.doFilter(DatatablesFilter.java:71)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.github.dandelion.datatables.core.web.filter.DatatablesFilter.doFilter(DatatablesFilter.java:73)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.github.dandelion.datatables.extras.servlet2.filter.DatatablesFilter.doFilter(DatatablesFilter.java:71)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
    at org.apache.coyote.ajp.AbstractAjpProcessor.process(AbstractAjpProcessor.java:831)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certificati$
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1428)
    ... 101 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 107 more
javax.mail.MessagingException: STARTTLS failure;
  nested exception is:
    com.sun.mail.iap.ProtocolException: STARTTLS failure
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:668)
    at javax.mail.Service.connect(Service.java:295)
    at javax.mail.Service.connect(Service.java:176)
    at com.hpp.kp.web.HL7PatientController.processInbox(HL7PatientController.java:1373)
    at com.hpp.kp.web.HL7PatientController.processEmailInbox(HL7PatientController.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.github.dandelion.datatables.core.web.filter.DatatablesFilter.doFilter(DatatablesFilter.java:73)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.github.dandelion.datatables.extras.servlet2.filter.DatatablesFilter.doFilter(DatatablesFilter.java:71)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
    at org.apache.coyote.ajp.AbstractAjpProcessor.process(AbstractAjpProcessor.java:831)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: com.sun.mail.iap.ProtocolException: STARTTLS failure
    at com.sun.mail.imap.protocol.IMAPProtocol.startTLS(IMAPProtocol.java:834)
    at com.sun.mail.imap.IMAPStore.login(IMAPStore.java:697)
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:642)
    ... 88 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExcept$
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1904)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:279)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:273)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1446)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:209)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:901)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:837)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1023)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:527)
    at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:464)
    at com.sun.mail.iap.Protocol.startTLS(Protocol.java:388)
    at com.sun.mail.imap.protocol.IMAPProtocol.startTLS(IMAPProtocol.java:820)
    ... 90 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certificati$
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1428)
    ... 101 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 107 more  

EDIT

As per @jCoder's suggestion, I typed export JAVA_OPTS=-Djavax.net.debug=all before running startup.sh and then clicking the link in the app that triggers the imap login request that throws the error. The same stack trace as above was thrown, but the new debug instructions caused 1100+ lines of relevant additional output in the catalina.out logs. I have uploaded these additional logs to a file sharing site, and you can view the additional logs by clicking on this link.

Haygood answered 14/2, 2015 at 23:0 Comment(6)
Did you try printing debug infos on the SSL connect as described here: docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/… ? Depending on the debug output you can either add the appropriate SSL certificates to the java trusted keystore or implement and register a custom SSL Socket Factory that accepts your server's certificate.Faruq
@Faruq No I have not. From your link, it looks like I should type java -Djavax.net.debug=all MyApp in the CentOS 7 terminal. But how do I know the correct syntax for the appName, and where do I look for the resulting logs? This is a spring mvc app running on tomcat. I of course know the name tomcat uses for it, but can the java command in the terminal understand the same name? I have been looking in catalina.out for the logs, but where do I look for these logs? And do I run this command right before I am about the click the links in the browser that trigger the JavaMail imap code?Haygood
The -Djavax.net.debug=all parameter has to be passed to the tomcat process on startup (MyApp would actually apply only to the command-line MyApp.class that one might start). You can set the JAVA_OPTS environment variables before starting the tomcat and the startup script should use it as extra parameters. The debugging output then should be logged in catalina.outFaruq
@Faruq Thank you. Are you willing to either explain specifically how to do that on CentOS 7?, or to post a link with instructions? There does not seem to be a tomcat file in /var/run or in /etc/rc.d/init.d. And typing nano /opt/tomcat/startup.sh opens an empty file instead of letting me alter the tomcat startup.sh script.Haygood
I don't have a CentOS at hand, so it's just a guess. The startup.sh is normally located in the bin folder of the tomcat installation (did you just unzip the Tomcat to /opt/tomcat? then it is in /opt/tomcat/bin) However, you don't need to modify the startup script; entering export JAVA_OPTS=-Djavax.net.debug=all before starting the Tomcat by invoking the startup script should do the job.Faruq
@Faruq Please see the EDIT at the end of my OP. I added export JAVA_OPTS=-Djavax.net.debug=all and restarted tomcat, then called the code that triggers the error. Your additional debug settings caused 1100+ additional lines of relevant logs. I posted them at a file sharing site and put the link in the EDIT to my OP. What do you recommend as a solution after reviewing the new logs?Haygood
U
6

The SSL certificate isn't trusted by Java. The certificate may be self-signed, or it may be signed by a CA (Certificate Authority) whose root certificate is not in the Java certificate store. The set of root certificates known by Java isn't as extensive as the set that your web browser knows about.

Assuming you do indeed trust the certificate in question, you can add it to the Java certificate store (which is called cacerts) using the keytool command. For example (change paths as appropriate for your installation and OS):

keytool -import -trustcacerts -file NewRootCACertificate.crt -keystore "C:\Program Files\Java\jre1.8.0_31\lib\security\cacerts"

By default the cacerts keystore has a password of changeit.

UPDATE:

Problem resolved to a working system in chat, although not with ideal configuration.

  • It looks like the previously working set-up was not using SSL.
  • This set-up stopped working, perhaps because of software updates changing the configuration (my speculation) to prevent login in the plain.
  • starttls was switched on to address the inability to login in the plaintext IMAP mode.
  • The lack of suitably-trusted certificate then emerged as an issue, hence the error in the question.
  • The certificate that was there (probably default created during installation of the mail server) didn't have the right domain name in the Common Name, but even with a fresh certificate, and adding it to what seemed to be the right cacerts key store (the key store path was mentioned in the application logs) the client failed to trust the certificate. We never got to the bottom of that.
  • Working set-up was arrived at with the following configuration (i.e. trusting the server by hostname and connecting directly with SSL rather than using starttls):
    • props.setProperty("mail.imap.ssl.enable", "true");
    • props.setProperty("mail.imap.ssl.trust", "mydomain.com");

This isn't ideal, however the client application is running on the same machine as the IMAP server, so this is probably not a huge risk.

In the long run, you may want to make a note that you did this work-around, and see whether you can get the certificate verification happening by other means, possibly a custom certificate verification handler or explicitly specifying the certificate store.

Unilingual answered 14/2, 2015 at 23:29 Comment(1)
This is a self-signed certificate. I interpret your response to mean that the scripts run to install OpenVPN somehow caused Java to lose the trust that it had placed in the certificate, thus causing this error. If this is true, do I use the dovecot certificates or some other certs? I looked in /etc/dovecot/conf.d/10-ssl.conf and found ssl_cert = </etc/pki/dovecot/certs/dovecot.pem and ssl_key = </etc/pki/dovecot/private/dovecot.pem. Is one of these the correct cert to use with your keytool command? Or is there some other place I should look? /etc/ssl/certs points to other certsHaygood
S
8
  • You should import certificate of the server:port to java JRE keystore for example for following server and port:

    serverAddress myserver.mydomain.com
    serverPort 443
    keystore default password did not changed, so it is **changeit** if you changed it use yours as password.
    
  • First of all, check $JAVA_HOME and java executable before continue, you should be sure about the choosing correct JAVA_HOME for importing , if you have different ones:

    $ ~/bin$ echo $JAVA_HOME
    /opt/jdk
    $ ~/bin$ which java
    /usr/bin/java
    $ ~/bin$ ls -l /usr/bin/java
    lrwxrwxrwx 1 root root 22 May 10  2014 /usr/bin/java -> /etc/alternatives/java
    $ ~/bin$ ls -l /etc/alternatives/java
    lrwxrwxrwx 1 root root 17 Jun  6  2014 /etc/alternatives/java -> /opt/jdk/bin/java
    $ ~/bin$ java -version
    java version "1.8.0_05"
    Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
    Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
    $ ~/bin$ `which java` -version
    java version "1.8.0_05"
    Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
    Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
    $ ~/bin$   $JAVA_HOME/bin/java -version
    java version "1.8.0_05"
    Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
    Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
    
  • Extracting certificate from the server:

    $ openssl s_client -connect <serverAddress:serverPort> 2>&1 < "/" | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/myserver.crt
    

    For this example <serverAddress:serverPort> should be replaced with myserver.mydomain.com:443

  • The extracted file should be look like as follows:

    $ cat /tmp/myserver.crt
    -----BEGIN CERTIFICATE-----
    blahblahblahaC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCd
    ME22AKpyBPIRbTwTBedJz/KFtwCAxO2jXIcIob99LXv8W4KMOJgazn2UUBm/azZ1
    z+9qhq3UeIy8Z58WK2N5l/SI7s3+bkii/dnpW3Akw8OyXABnN1EyfwnL607POqXm
    blahblahblah
      ...Certificate Data is variable for each server address...
    blahblahblah
    blahblahblahT9p1jar2vxoHv3/dSwKoeLL8XpkmVx9oVUZ3XuICPvEmu8eBfOEm
    ZXNlYXJjaC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCd4I7L
    ME22AKpyBPIRbTwTBedJz/KFtwCAxO2jXIcIob99LXv8W4KMOJgazn2UUBm/azZ1
    -----END CERTIFICATE-----
    
  • You need to import the extracted certificate into JRE keystore:

    $ keytool -import -alias myserverCert -file  /tmp/myserver.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
    
  • You can check that the certification existence in java JRE keystore or not after the import:

     $ keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts
    
  • Default password for java JRE keystore is

    changeit

  • For applying the changes you need to restart the java JVM.

  • After finish you can remove the temporary file if you had created it in a non temporary place:

    $ rm /tmp/myserver.crt
    
  • for your case you can do entire this process two times onetime before VPN establishment and onetime after establishment only you should to use two alias for each time as follows:

    # Before VPN Connect
    $ openssl s_client -connect myserver.mydomain.com:443 2>&1 < "/" | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/myserver.crt
    $ keytool -import -alias myserverCert -file  /tmp/myserver.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
    # After VPN Connect
    $ openssl s_client -connect myserver.mydomain.com:443 2>&1 < "/" | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/myserver-vpn.crt
    $ keytool -import -alias myserverVPNCert -file  /tmp/myserver-vpn.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
    

    If two extracted certificates are same the problem is another thing and you should find another solution.

    $ diff /tmp/myserver.crt /tmp/myserver-vpn.crt
    

I hope this can help you

Scaramouch answered 26/2, 2015 at 16:7 Comment(0)
U
6

The SSL certificate isn't trusted by Java. The certificate may be self-signed, or it may be signed by a CA (Certificate Authority) whose root certificate is not in the Java certificate store. The set of root certificates known by Java isn't as extensive as the set that your web browser knows about.

Assuming you do indeed trust the certificate in question, you can add it to the Java certificate store (which is called cacerts) using the keytool command. For example (change paths as appropriate for your installation and OS):

keytool -import -trustcacerts -file NewRootCACertificate.crt -keystore "C:\Program Files\Java\jre1.8.0_31\lib\security\cacerts"

By default the cacerts keystore has a password of changeit.

UPDATE:

Problem resolved to a working system in chat, although not with ideal configuration.

  • It looks like the previously working set-up was not using SSL.
  • This set-up stopped working, perhaps because of software updates changing the configuration (my speculation) to prevent login in the plain.
  • starttls was switched on to address the inability to login in the plaintext IMAP mode.
  • The lack of suitably-trusted certificate then emerged as an issue, hence the error in the question.
  • The certificate that was there (probably default created during installation of the mail server) didn't have the right domain name in the Common Name, but even with a fresh certificate, and adding it to what seemed to be the right cacerts key store (the key store path was mentioned in the application logs) the client failed to trust the certificate. We never got to the bottom of that.
  • Working set-up was arrived at with the following configuration (i.e. trusting the server by hostname and connecting directly with SSL rather than using starttls):
    • props.setProperty("mail.imap.ssl.enable", "true");
    • props.setProperty("mail.imap.ssl.trust", "mydomain.com");

This isn't ideal, however the client application is running on the same machine as the IMAP server, so this is probably not a huge risk.

In the long run, you may want to make a note that you did this work-around, and see whether you can get the certificate verification happening by other means, possibly a custom certificate verification handler or explicitly specifying the certificate store.

Unilingual answered 14/2, 2015 at 23:29 Comment(1)
This is a self-signed certificate. I interpret your response to mean that the scripts run to install OpenVPN somehow caused Java to lose the trust that it had placed in the certificate, thus causing this error. If this is true, do I use the dovecot certificates or some other certs? I looked in /etc/dovecot/conf.d/10-ssl.conf and found ssl_cert = </etc/pki/dovecot/certs/dovecot.pem and ssl_key = </etc/pki/dovecot/private/dovecot.pem. Is one of these the correct cert to use with your keytool command? Or is there some other place I should look? /etc/ssl/certs points to other certsHaygood

© 2022 - 2024 — McMap. All rights reserved.