Bug 46950 - SSL renegotiation does not occur when resource with CLIENT-CERT auth is requested
SSL renegotiation does not occur when resource with CLIENT-CERT auth is reque...
Status: RESOLVED FIXED
Product: Tomcat 5
Classification: Unclassified
Component: Native:Integration
5.5.28
PC Linux
: P2 normal (vote)
: ---
Assigned To: Tomcat Developers Mailing List
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2009-04-01 06:33 UTC by Andre Cruz
Modified: 2009-11-30 16:33 UTC (History)
1 user (show)



Attachments
Patch that makes the Apr connector behave like the non-Apr (2.79 KB, patch)
2009-05-14 04:17 UTC, Andre Cruz
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andre Cruz 2009-04-01 06:33:02 UTC
When a part of a webapp requires an SSL connection with a client certificate there should be an SSL renegotiation to request a client certificate from the browser.

This is the configuration I added to an webapp that already uses an SSL connector:

<login-config id="LoginConfig_1">
                <auth-method>CLIENT-CERT</auth-method>
                <realm-name>WPS</realm-name>
</login-config>

<security-constraint id="SecurityConstraint_1">
                <web-resource-collection id="WebResourceCollection_1">
                        <web-resource-name/>   
                        <url-pattern>/LoginWithCert.do</url-pattern>
                        <http-method>DELETE</http-method>
                        <http-method>GET</http-method>
                        <http-method>POST</http-method>
                        <http-method>PUT</http-method>
                        <http-method>HEAD</http-method>
                </web-resource-collection>
                <user-data-constraint id="UserDataConstraint_4">
                        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
                </user-data-constraint>
</security-constraint>

Requests to /LoginWithCert.do require an SSL connection, if there isn't one, but no client certificate is requested.
Comment 1 william.barker 2009-04-01 11:43:50 UTC
There is no <auth-constraint> in the configuration, so of course Tomcat doesn't ask for a certificate.
Comment 2 Andre Cruz 2009-04-02 03:00:48 UTC
Ok. So now I changed the security-constraint to:
<security-constraint id="SecurityConstraint_1">
                <web-resource-collection id="WebResourceCollection_1">
                        <web-resource-name/>
                        <url-pattern>/LoginWithCert.do</url-pattern>
                        <http-method>DELETE</http-method>
                        <http-method>GET</http-method>
                        <http-method>POST</http-method>
                        <http-method>PUT</http-method>
                        <http-method>HEAD</http-method>
                </web-resource-collection>
                <auth-constraint>
                        <role-name>*</role-name>
                </auth-constraint>
                <user-data-constraint id="UserDataConstraint_4">
                        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
                </user-data-constraint>
</security-constraint>

Now I get this error when I access the resource:
HTTP Status 400 - No client certificate chain in this request

BUT no certificate was asked in the SSL (re-)negotiation.
Comment 3 Mark Thomas 2009-04-14 16:15:31 UTC
The following configuration works for me. At a guess, you haven't configured Tomcat to trust the issuer of your client certificate. The browser only prompts you to select a cert if it has one that the server will trust.

Please use the users list if you need further help configuring your SSL certs.

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Bug46950</web-resource-name>
      <url-pattern>/bug46381.jsp</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>manager</role-name>
    </auth-constraint>
  </security-constraint>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Everything</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
  <login-config>
    <auth-method>CLIENT-CERT</auth-method>
  </login-config>
Comment 4 Andre Cruz 2009-04-15 04:03:39 UTC
What works for you? Did you even read what I said?

How can the browser know if a server trusts a certain certificate or not without even asking for it?

Let me explain the problem better.

Most of my site runs without client cert checking, so I have SSLVerifyClient="none" on the connector. But I have one servlet that DOES want a client certificate and so I configured the security restriction accordingly in the deployment descriptor. Just that one resource, not the entire site.

It's in these cases that a SSL renegotiation does not occur to ask for the client certificate. Tomcat only knows that I want a client certificate after the client sends the http request.

Apache httpd has this feature and someone at the tomcat user's list asked me to file this as a bug. Maybe it's just a missing feature.
Comment 5 Mark Thomas 2009-04-15 04:38:10 UTC
(In reply to comment #4)
> What works for you?
The security constraint and login configuration I posted which requires SSL for the entire context but only requires user authentication for a single JSP. If I browse to any resource except the one that requires auth using http I get switched to https as expected. If I then request the protected resource I get prompted for my certificate.

> Did you even read what I said?
Yes I did. Quite carefully. Taking that attitude is not going to induce people to help you.

> How can the browser know if a server trusts a certain certificate or not
> without even asking for it?
This is the way the SSL handshake works. The server provides a client with a list of trusted certs. If the client doesn't have a user cert issued by one of the trysted certs the client doesn't waste time prompting the user to select one.

> Let me explain the problem better.
> 
> Most of my site runs without client cert checking, so I have
> SSLVerifyClient="none" on the connector.

That is new information. Your original bug report made no mention of using the APR/native connector. I'd expect the behaviour to remain the same but I'll re-test with the native and see.
Comment 6 Mark Thomas 2009-04-15 05:21:57 UTC
OK, I can confirm this when I test with the APR/native connector. Looking for a fix now...
Comment 7 Mark Thomas 2009-04-16 12:37:33 UTC
This is going to require a change to the APR/native connector.
Comment 8 Andre Cruz 2009-05-14 04:17:52 UTC
Created attachment 23663 [details]
Patch that makes the Apr connector behave like the non-Apr

This patch will turn on the SSL Client requirement prior to the SSL renegotiation prompting the browser for one.
Comment 9 Mark Thomas 2009-05-27 06:08:48 UTC
The proposed patch does not work exactly as intended. It does not trigger renegotiation, rather it sets SSLVerifyClient for the all future SSL sessions created by that request processor.

The side effects of this are:
- cert still not prompted for when transitioning from resource that doesn't require cert to one that does
- subsequent SSL requests handled by that processor will prompt for a cert, even when not required.

As per comment #7, a fix for this that aligns the APR/native connector behaviour with the Java connectors will require a change to the native component of the native connector (to enable the connection to be renegotiated for the current connection).
Comment 10 Mark Thomas 2009-09-15 10:59:35 UTC
The native fixes have been applied to the 1.1.x branch and trunk (1.2.x)
The Tomcat fixes have been applied to trunk (7.0.x) and proposed for 6.0.x and 5.5.x. Note that the 6.0.x/5.5.x patch depends on there being a new tc-native release
Comment 11 Mark Thomas 2009-11-02 16:33:29 UTC
This has been fixed in 6.0.x and will be included in 6.0.21 onwards.

It will also be proposed for backport to 5.5.x
Comment 12 Andre Cruz 2009-11-03 02:54:46 UTC
Thanks!
Comment 13 Mark Thomas 2009-11-30 16:33:37 UTC
This has been applied to 5.5.x and will be included in 5.5.29 onwards.