You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Subscriber <su...@sepo.dk> on 2006/11/01 11:33:31 UTC

Handling expired client certificate

Hi,

I've configured Tomcat 5.5.17 to use CLIENT-CERT as authentication 
mechanism via web.xml in my web application. This works as expected and 
the user gets prompted for a certificate. I'm facing a problem, because 
when the user supplies a certificate that has expired Tomcat throws an 
exception in the log like this:

INFO: SSL Error getting client Certs
javax.net.ssl.SSLHandshakeException: 
java.security.cert.CertificateExpiredException: NotAfter: Thu Jan 19 
08:40:14 CET 2
006
         at 
com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
         at 
com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1518)
         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.ServerHandshaker.clientCertificate(ServerHandshaker.java:1098)
         at 
com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:187)
         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:818)
         at 
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:680)
         at 
com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
         at java.io.InputStream.read(InputStream.java:89)
         at 
org.apache.tomcat.util.net.jsse.JSSE14Support.synchronousHandshake(JSSE14Support.java:87)
         at 
org.apache.tomcat.util.net.jsse.JSSE14Support.handShake(JSSE14Support.java:66)
         at 
org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(JSSESupport.java:120)
         at 
org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:1126)
         at org.apache.coyote.Request.action(Request.java:348)
         at 
org.apache.catalina.authenticator.SSLAuthenticator.authenticate(SSLAuthenticator.java:134)
         at 
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
         at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
         at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
         at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
         at 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
         at 
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
         at 
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java
:664)
         at 
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
         at 
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
         at 
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
         at java.lang.Thread.run(Thread.java:595)
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Thu 
Jan 19 08:40:14 CET 2006
         at 
sun.security.x509.CertificateValidity.valid(CertificateValidity.java:256)
         at 
sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:570)
         at 
sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:123)
         at sun.security.validator.Validator.validate(Validator.java:203)
         at sun.security.validator.Validator.validate(Validator.java:172)
         at 
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkClientTrusted(X509TrustManagerImpl.java:142)
         at 
com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkClientTrusted(SSLContextImpl.java:303)
         at 
com.sun.net.ssl.internal.ssl.ServerHandshaker.clientCertificate(ServerHandshaker.java:1091)
         ... 24 more
2006-11-01 11:27:58 org.apache.coyote.http11.Http11Processor action
WARNING: Exception getting SSL attributes
javax.net.ssl.SSLHandshakeException: 
java.security.cert.CertificateExpiredException: NotAfter: Thu Jan 19 
08:40:14 CET 2
006
         at 
com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
         at 
com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1518)
         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.ServerHandshaker.clientCertificate(ServerHandshaker.java:1098)
         at 
com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:187)
         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:818)
         at 
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:680)
         at 
com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
         at java.io.InputStream.read(InputStream.java:89)
         at 
org.apache.tomcat.util.net.jsse.JSSE14Support.synchronousHandshake(JSSE14Support.java:87)
         at 
org.apache.tomcat.util.net.jsse.JSSE14Support.handShake(JSSE14Support.java:66)
         at 
org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(JSSESupport.java:120)
         at 
org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:1126)
         at org.apache.coyote.Request.action(Request.java:348)
         at 
org.apache.catalina.authenticator.SSLAuthenticator.authenticate(SSLAuthenticator.java:134)
         at 
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
         at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
         at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
         at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
         at 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
         at 
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
         at 
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java
:664)
         at 
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
         at 
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
         at 
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
         at java.lang.Thread.run(Thread.java:595)
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Thu 
Jan 19 08:40:14 CET 2006
         at 
sun.security.x509.CertificateValidity.valid(CertificateValidity.java:256)
         at 
sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:570)
         at 
sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:123)
         at sun.security.validator.Validator.validate(Validator.java:203)
         at sun.security.validator.Validator.validate(Validator.java:172)
         at 
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkClientTrusted(X509TrustManagerImpl.java:142)
         at 
com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkClientTrusted(SSLContextImpl.java:303)
         at 
com.sun.net.ssl.internal.ssl.ServerHandshaker.clientCertificate(ServerHandshaker.java:1091)
         ... 24 more

My problem is, that I would like to handle the case myself and avoid 
exceptions in the log and present the user with a good error message. In 
this case, the user has no clue what-so-ever of what happened because 
the error remains within Tomcat. What can I do to catch the error myself?

Besides, I would also like to be able to customize the interval before a 
SSL handshake times out with the client. Is this possible to customize?

I've read some of the previous postings on this behaviour, but postings 
are from early 2004 and I guess some progress has been made since.

regards,
kews

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Handling expired client certificate

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Kews,

Subscriber wrote:
> Hi Hassan,
> 
> Thanks for your answer. Yes, I've already tried your suggestion. Both
> with the java.security.cert.CertificateExpiredException and the
> javax.net.ssl.SSLHandshakeException, but the problem remains. As I can
> see, the exception is thrown somewhere inside Tomcat, before handling
> control to the webapplication. Hence, the exception is not "catchable"
> inside my webapplication, but is to be handled in some other way
> "inside" the Tomcat engine.

What you need to do is override Java's certificate validator. This is
not a Tomcat issue -- you'd have it with any Java-based code that uses
the JRE's SSL libraries.

I'm not sure if Tomcat has a setting for doing this, but you might be
able to do it programmatically.

I have had to deal with this in the past, and I wrote myself a little
readme about it, since it's not worth keeping in my brain. I seem to
have lost it, but I do have some code that will turn off cert validation
for /outgoing/ HttpsURLConnections. You may have to adapt this code to
change the way ServetSockets are handled:

    public static void disableSSLCertificateChecking()
	throws NoSuchAlgorithmException, KeyManagementException
    {
        TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs,
                                               String authType) {
                }
                public void checkServerTrusted(X509Certificate[] certs,
                                               String authType) {
                }
            }
        };

	SSLContext sc = SSLContext.getInstance("SSL");

	sc.init(null, trustAllCerts, new java.security.SecureRandom());

	HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }


If you'd like, you can implement your own version of checking instead of
disabling validation entirely. This is actually overriding the validator
with one that doesn't do any validation... it's not really disabling it.
You are free to provide your own implementation.

I can't seem to find any relevant methods in SSLServerSocketFactory,
which would be the most likely place to call some kind of
setDefaultSSLSocketFactory method, much like the HttpsURLConnection
method of the same name used above.

Sorry if this leads you down the wrong path!

-chris


Re: Handling expired client certificate

Posted by Subscriber <su...@sepo.dk>.
Hi Hassan,

Thanks for your answer. Yes, I've already tried your suggestion. Both 
with the java.security.cert.CertificateExpiredException and the 
javax.net.ssl.SSLHandshakeException, but the problem remains. As I can 
see, the exception is thrown somewhere inside Tomcat, before handling 
control to the webapplication. Hence, the exception is not "catchable" 
inside my webapplication, but is to be handled in some other way 
"inside" the Tomcat engine.

...Suggestions are still very welcome :-)

regards,
kews

Hassan Schroeder wrote:
> On 11/1/06, Subscriber <su...@sepo.dk> wrote:
>> Hi,
>>
>> I've configured Tomcat 5.5.17 to use CLIENT-CERT as authentication
>> mechanism via web.xml in my web application. This works as expected and
>> the user gets prompted for a certificate. I'm facing a problem, because
>> when the user supplies a certificate that has expired Tomcat throws an
>> exception in the log like this:
>>
>> INFO: SSL Error getting client Certs
>> javax.net.ssl.SSLHandshakeException:
>> java.security.cert.CertificateExpiredException: NotAfter: Thu Jan 19
>> 08:40:14 CET 2
>> 006
> 
>> My problem is, that I would like to handle the case myself and avoid
>> exceptions in the log and present the user with a good error message. In
>> this case, the user has no clue what-so-ever of what happened because
>> the error remains within Tomcat. What can I do to catch the error myself?
> 
> Have you tried something like this in your web.xml?
> 
> <error-page>
> <exception-type>java.security.cert.CertificateExpiredException</exception-type> 
> 
> <location>/WEB-INF/errors/expired.jsp</location>
> </error-page>
> 

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Handling expired client certificate

Posted by Hassan Schroeder <ha...@gmail.com>.
On 11/1/06, Subscriber <su...@sepo.dk> wrote:
> Hi,
>
> I've configured Tomcat 5.5.17 to use CLIENT-CERT as authentication
> mechanism via web.xml in my web application. This works as expected and
> the user gets prompted for a certificate. I'm facing a problem, because
> when the user supplies a certificate that has expired Tomcat throws an
> exception in the log like this:
>
> INFO: SSL Error getting client Certs
> javax.net.ssl.SSLHandshakeException:
> java.security.cert.CertificateExpiredException: NotAfter: Thu Jan 19
> 08:40:14 CET 2
> 006

> My problem is, that I would like to handle the case myself and avoid
> exceptions in the log and present the user with a good error message. In
> this case, the user has no clue what-so-ever of what happened because
> the error remains within Tomcat. What can I do to catch the error myself?

Have you tried something like this in your web.xml?

<error-page>
 <exception-type>java.security.cert.CertificateExpiredException</exception-type>
 <location>/WEB-INF/errors/expired.jsp</location>
</error-page>

-- 
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org