Bug 47492

Summary: SSLVerifyClient require_no_ca
Product: Apache httpd-2 Reporter: Joe Presbrey <presbrey>
Component: mod_sslAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: RESOLVED DUPLICATE    
Severity: normal CC: andre, apache-bugzilla
Priority: P2    
Version: 2.2.11   
Target Milestone: ---   
Hardware: All   
OS: All   
URL: http://dig.csail.mit.edu/2009/mod_ssl-require_no_ca/mod_ssl-2.2.11-require_no_ca.patch
Attachments: SSLVerifyClient require_no_ca patch for httpd-2.2.11

Description Joe Presbrey 2009-07-07 18:45:15 UTC
Created attachment 23937 [details]
SSLVerifyClient require_no_ca patch for httpd-2.2.11

This patch submission implements an additional option for the SSLVerifyClient directive: require_no_ca.  When configured, this option requires that clients present SSL certificates but allows certificates issued by CAs unknown to the server.

This feature is especially useful for SSL-based authentication schemes implementing trust models independent of typical enterprise CA/chain verification.  The optional_no_ca option is insufficient for widely-deployed solutions of this fashion since "'optional' doesn't work with all browsers" [1].

One example making use of this configuration is the FOAF+SSL [2] protocol which allows a client to assert an identity specified as a URI in the X509v3 extension subjectAltName of their certificate. After SSL negotiation by mod_ssl, mod_authn_webid [3] pulls the URI via ssl_ext_lookup, calculates the modulus and exponent of the client certificate, and authenticates the user to this URI identity if the mod/exp published at the URI match those of the presented certificate.

Please consider this short patch for inclusion.  It applies cleanly to release 2.2.11.

[1] http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslverifyclient
[2] http://esw.w3.org/topic/foaf+ssl
[3] http://dig.csail.mit.edu/2009/mod_authn_webid/
Comment 1 Andre Cruz 2009-08-07 08:39:26 UTC
Does this patch work?

I setup a path like this:
    <Location /LoginWithCert.do>
      SSLVerifyClient require_no_ca
      SSLOptions +OptRenegotiate
    </Location>

The browser asked me for a certificate when the SSL was renegotiated (the outer context has SSLVerifyClient none) and the following appeared in the log:

[Fri Aug 07 16:26:04 2009] [error] Re-negotiation handshake failed: Client verification failed

A "Forbidden" was returned to the browser (Firefox 3.5.2). fyi, the patch does not apply cleanly to 2.1.12 and the certificate I sent is self-signed.

Also, when I don't send a client certificate an error page appears in Firefox, this can be a firefox problem... This appears in the server log:

[Fri Aug 07 16:38:14 2009] [debug] ssl_engine_kernel.c(1772): OpenSSL: Write: SSLv3 read client certificate B
[Fri Aug 07 16:38:14 2009] [debug] ssl_engine_kernel.c(1791): OpenSSL: Exit: error in SSLv3 read client certificate B
[Fri Aug 07 16:38:14 2009] [error] Re-negotiation handshake failed: Not accepted by client!?
Comment 2 Paul Donohue 2010-04-13 16:52:43 UTC
I don't understand the difference between this and optional_no_ca.

I'm pretty sure the Apache documentation is wrong about "optional" not working with all browsers. The SSL handshake is identical for both "optional" and "required" (see section 7.4.4 of RFC2246 or the 'REQUEST-CERTIFICATE' section of http://www.mozilla.org/projects/security/pki/nss/ssl/draft02.html). The only difference is that "required" will immediately send a "handshake failure" alert and close the connection if a certificate is not received from the client, while "optional" will ignore the missing certificate and continue.

I'm guessing the Apache documentation may be referring to older browsers automatically giving up and closing the connection themselves if a suitable cert is not available, essentially making the "optional" option the same as the "required" option for these browsers.

So I think you could accomplish the same thing as this patch simply by using optional_no_ca, then dropping the connection in your application if SSL_VERIFY is set to NONE.
Comment 3 argami 2010-04-13 17:09:20 UTC
require Always ask for client certificate and always verfy with ca
optional_no_ca some times ask for certificate other dont and never verify with ca
and this option require_no_ca always ask for a certificate and never verify its very useful whe you need to ask for a cert but you want to implement you own verify method (like me).

This version have a bug but https://issues.apache.org/bugzilla/show_bug.cgi?id=49037
works great.

(In reply to comment #2)
> I don't understand the difference between this and optional_no_ca.
> 
> I'm pretty sure the Apache documentation is wrong about "optional" not working
> with all browsers. The SSL handshake is identical for both "optional" and
> "required" (see section 7.4.4 of RFC2246 or the 'REQUEST-CERTIFICATE' section
> of http://www.mozilla.org/projects/security/pki/nss/ssl/draft02.html). The only
> difference is that "required" will immediately send a "handshake failure" alert
> and close the connection if a certificate is not received from the client,
> while "optional" will ignore the missing certificate and continue.
> 
> I'm guessing the Apache documentation may be referring to older browsers
> automatically giving up and closing the connection themselves if a suitable
> cert is not available, essentially making the "optional" option the same as the
> "required" option for these browsers.
> 
> So I think you could accomplish the same thing as this patch simply by using
> optional_no_ca, then dropping the connection in your application if SSL_VERIFY
> is set to NONE.
Comment 4 Paul Donohue 2010-04-14 09:17:10 UTC
But optional_no_ca always asks for a certificate as well.

The only difference between require and optional is that require sets the SSL_VERIFY_PEER_STRICT mode on SSL_CTX_set_verify (in ssl_engine_init.c) while optional only sets the SSL_VERIFY_PEER mode. SSL_VERIFY_PEER_STRICT is defined (in ssl_private.h) as SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT. And if you read the SSL documentation (http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html), SSL_VERIFY_FAIL_IF_NO_PEER_CERT simply causes SSL to drop the connection if no cert is available.  But in either case, it ALWAYS asks for a cert.

Therefore, the only difference between optional_no_ca and require_no_ca is that require_no_ca will drop the connection automatically if no cert is provided, while optional_no_ca will accept the connection and just not set the SSL_CLIENT_CERT variable. So if you are implementing your own verify method, why not just use optional_no_ca and check for an empty SSL_CLIENT_CERT yourself?

(In reply to comment #3)
> require Always ask for client certificate and always verfy with ca
> optional_no_ca some times ask for certificate other dont and never verify with
> ca
> and this option require_no_ca always ask for a certificate and never verify its
> very useful whe you need to ask for a cert but you want to implement you own
> verify method (like me).
> 
> This version have a bug but
> https://issues.apache.org/bugzilla/show_bug.cgi?id=49037
> works great.
Comment 5 Paul Donohue 2010-04-14 09:17:48 UTC

*** This bug has been marked as a duplicate of bug 49037 ***