Bug 41337 - Display an error page if no cert is available on CLIENT-CERT login
Summary: Display an error page if no cert is available on CLIENT-CERT login
Status: RESOLVED WONTFIX
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Connector:HTTP (show other bugs)
Version: 5.5.20
Hardware: All All
: P2 enhancement (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-01-10 00:36 UTC by Armin H
Modified: 2011-03-19 07:04 UTC (History)
1 user (show)



Attachments
added a patch with the proposed change in http://issues.apache.org/bugzilla/show_bug.cgi?id=41337#c2 (674 bytes, patch)
2007-01-30 04:09 UTC, Armin H
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Armin H 2007-01-10 00:36:44 UTC
If a client does not have a client certificate or doesn't select a client
certificate to be used for authentication, Tomcat does not display an error
page. It just does nothing (that the client would see).

Steps to reproduce:
1. configure an ssl connector and set clientAuth="false"
2. create a security-constaint in the web.xml of the webapp
3. set the login-config in the web.xml to this:
  <login-config>
  <auth-method>CLIENT-CERT</auth-method>
  </login-config>
4. try to access the page without a client certificate
Comment 1 Armin H 2007-01-10 00:50:00 UTC
org.apache.catalina.authenticator.SSLAuthenticator.authenticate() it tests if
the client has a certificate and displays an error page if not. But the client
doesn't get that error page.

if ((certs == null) || (certs.length < 1)) {
            if (containerLog.isDebugEnabled())
                containerLog.debug("  No certificates included with this request");
            response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                               sm.getString("authenticator.certificates"));
            return (false);
        }
Comment 2 Armin H 2007-01-10 01:00:15 UTC
The bug seems ot be in the JSSE package
I could solve it by changing the method JSSE14Support.handshake() from:

   protected void handShake() throws IOException {
        if( ssl.getWantClientAuth() ) {
            logger.debug("No client cert sent for want");
        } else {
            ssl.setNeedClientAuth(true);
        }
        synchronousHandshake(ssl);
    }

to:

    protected void handShake() throws IOException {
        if( ssl.getNeedClientAuth() ) {
            logger.debug("No client cert sent for want");
        } else {
            ssl.setWantClientAuth(true);
        }
        synchronousHandshake(ssl);
    }

This way in the above scenario wantClientAuth is set to true. So the SSLSocket
would also accept connection without client certificates, but the
SSLAuthenticator will then display an error page.
Comment 3 Armin H 2007-01-30 04:09:42 UTC
Created attachment 19483 [details]
added a patch with the proposed change in http://issues.apache.org/bugzilla/show_bug.cgi?id=41337#c2
Comment 4 Armin H 2007-01-30 04:12:01 UTC
Does this patch introduce a logical change for applications and therefore need
an RFE?
Comment 5 Julius Davies 2007-01-30 08:08:45 UTC
Hi,

The only way to present a useful error page is to establish a socket.  JSSE
won't let the socket happen if there's a problem with a client cert.  In my mind
the only way to provide a useful error page would be to for Tomcat to only ever
use "setWantClientAuth" (which isn't even available pre Java 1.4 !), and to draw
an HTML error page for all requests if "need=true" is set in Tomcat's own config.

It's nicer to just leave all this stuff up to JSSE and not worry about it.  By
circumventing JSSE's "no socket for you" security, Tomcat risks making itself
insecure, even though a helpful error page would be *really* handy!

Workaround:  set your own SSL config in Tomcat to "WANT" instead of "NEED" (in
server.xml) and setup your own ServletFilter on "/*" that draws a nice error
page if no client cert is provided.

<Connector 
           port="8443" minProcessors="5" maxProcessors="75"
           enableLookups="true" disableUploadTimeout="true"
           acceptCount="100" debug="0" scheme="https" secure="true";
           sslProtocol="TLS"

clientAuth="want"
/>
Comment 6 Mark Thomas 2007-01-31 16:45:12 UTC
As Julius notes the desired behaviour is possible with the current configuration
options and a little coding. The lack of useful error message when the SSL
handshake fails is more a browser failing than a Tomcat one.

I am have changed this issue to an enhancement and am resolving as WONTFIX as I
do not believe the benefit of a nice error message outweighs the risk of
allowing users with invalid certificates to make a successful connection.
Comment 7 Armin H 2007-02-13 06:58:14 UTC
The behaviour that I like is a bit different. I have a connector that is
configured with clientAuth="none". And in the web.xml I specify certain pages
that require a certificate.
This way the user is not bothered with a certificate selection dialog, unless he
accesses a page where a client cert authensication level is needed. So
unexpirienced users are not overstrained with selecting a certificate, before
theiy can even access the part of the page that does not need such an
authentucation.
Comment 8 Ralf Hauser 2007-02-13 07:25:23 UTC
I second Armin's observation. If we ever want to make client certificate
authentication mass-ready, we cannot only rely on browser manufacturers making
client-cert-auth dialogs mass proof. It must be possible to first navigate on a
https site/connector and read some "in-page" text and possibly submit some form
info securely and only thereafter be confronted with the certificate selection
popping up.
Do you have any "third" approaches?
Comment 9 Mark Thomas 2011-03-19 07:04:23 UTC
(In reply to comment #7)
> The behaviour that I like is a bit different. I have a connector that is
> configured with clientAuth="none". And in the web.xml I specify certain pages
> that require a certificate.

This is supported out of the box with CLIENT-CERT.

My concerns in comment #6 remain and I am therefore re-closing this.