You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Kaspar Brand <ht...@velox.ch> on 2008/02/13 10:00:23 UTC

[PATCH] Further refinements for SNI

While I was testing revocation checking for client certs in an SNI
configuration (Dirk, many thanks for make_sni.sh, btw!), I came across a
flaw in the current implementation when CRL information - i.e.
SSLCARevocationFile/SSLCARevocationPath - is set on a per-vhost basis
(don't know how much sense it makes to have non-global CRLs, but anyway...).

The attached patch addresses this issue, and it also improves the
logging behavior for an SNI enabled configuration (previously some of
the messages would always go to the first vhost, or wouldn't appear at
all, depending on the LogLevel of the first vhost).

Kaspar

Re: [PATCH] Further refinements for SNI

Posted by Dirk-Willem van Gulik <di...@webweaving.org>.
On Feb 13, 2008, at 10:00 AM, Kaspar Brand wrote:

> While I was testing revocation checking for client certs in an SNI
> configuration (Dirk, many thanks for make_sni.sh, btw!), I came  
> across a
> flaw in the current implementation when CRL information - i.e.

Thank YOU (me feel silly now - as I spent a fair bit of time trying to  
understand why
one test case of mine was not failing -- but as I was blaming openssl  
- was looking
in the wrong place)

> SSLCARevocationFile/SSLCARevocationPath - is set on a per-vhost basis
> (don't know how much sense it makes to have non-global CRLs, but  
> anyway...).

It may make sense during a roll over ? Not sure ?

> The attached patch addresses this issue, and it also improves the
> logging behavior for an SNI enabled configuration (previously some of
> the messages would always go to the first vhost, or wouldn't appear at
> all, depending on the LogLevel of the first vhost).

Tested and applied as rev 627699.

Thanks!

Dw.

Re: [PATCH] Further refinements for SNI

Posted by Kaspar Brand <ht...@velox.ch>.
Joe Orton wrote:
> I hacked up a quick test based on Dirk's make_sni.sh; this adds 
> "SSLVerifyClient" & SSLCACertificateFile to the second and third named 
> vhosts.
> 
> And this confirms my original suspicions: I can access those vhosts 
> without having to present a certificate, i.e. the configured access 
> control restrictions can be bypassed.  If I move the SSLVerifyClient/etc 
> to the first vhost, it works as expected.

Right, I can reproduce this issue. It's occurring when the client does
*not* include an SNI extension in its ClientHello, which can happen with
both "old" (i.e. non-SNI capable) clients as well as with SNI-capable
clients (if they're trying to downgrade to TLS without extensions or to
SSLv3, e.g.).

>From my understanding/analysis of the code, there are two ways how the
correct vhost configuration can be assigned to an SSL request_rec:

a) in ssl_callback_ServerNameIndication(), which is called very early in
the SSL handshake. This makes sure that the correct SSLVerifyClient,
SSLVerifyDepth and SSLCACertificateFile are set before the server
verifies the client cert, and will result in a handshake error before
any HTTP request has been sent. This method only works for clients which
include an SNI extension in their ClientHello, of course.

b) in protocol.c:ap_read_request(), where the correct vhost is selected
based on the Host: header sent in the HTTP request. Access control for
this case can only be handled after the request has been read, and is
done in ssl_hook_Access(). Unfortunately, ssl_hook_Access() currently
doesn't honor the SSLVerifyClient/SSLVerifyDepth directives at the vhost
level when the vhost config has been updated in ap_read_request() - it
only enforces those set in per-directory context (<Directory>,
<Location> and friends). Depending on the new
SSLVerifyClient/SSLVerifyDepth settings, ssl_hook_Access() will trigger
a renegotiation (to request a client certificate if the default/first
vhost doesn't uses the default settings, i.e. no clientauth).

There are two solutions for the issue you're experiencing, in my view:

1) for the second and third vhost, add an enclosing <Location> block
   to the SSLVerify* directives:

   <VirtualHost 127.0.0.1:4433>
       SSLEngine On
       ServerName nut.my-sni-test.org:4433
       DocumentRoot /home/kbrand/sni/htdocs/nut
       SSLCertificateChainFile /home/kbrand/sni/root.pem
       SSLCertificateFile /home/kbrand/sni/ssl/nut.crt
       TransferLog /home/kbrand/sni/logs/access_nut
       SSLCACertificate /home/kbrand/sni/root.pem
       <Location>
           SSLVerifyClient require
           SSLVerifyDepth 10
       </Location>
   </VirtualHost>

2) apply something like the attached patch, which makes sure that
   ssl_hook_Access also honors SSLVerifyClient/SSLVerifyDepth directives
   set at the vhost level, after a new vhost config has been assigned
   by ap_read_request (maybe there's a more elegant way to write it,
   code-wise, but it should demonstrate the basic principle)

Kaspar

Re: [PATCH] Further refinements for SNI

Posted by Joe Orton <jo...@redhat.com>.
On Tue, Apr 22, 2008 at 06:27:26PM +0200, Dirk-Willem van Gulik wrote:
>
> On Apr 22, 2008, at 5:53 PM, Joe Orton wrote:
>> On Wed, Feb 13, 2008 at 10:00:23AM +0100, Kaspar Brand wrote:
>>> While I was testing revocation checking for client certs in an SNI
>>> configuration (Dirk, many thanks for make_sni.sh, btw!), I came across a
>>> flaw in the current implementation when CRL information - i.e.
>>> SSLCARevocationFile/SSLCARevocationPath - is set on a per-vhost basis
>>> (don't know how much sense it makes to have non-global CRLs, but 
>>> anyway...).
>>
>> Someone bugged me about the SNI support so I finally go round to chasing
>> this up.
>>
>> I hacked up a quick test based on Dirk's make_sni.sh; this adds
>> "SSLVerifyClient" & SSLCACertificateFile to the second and third named
>> vhosts.
>>
>> And this confirms my original suspicions: I can access those vhosts
>> without having to present a certificate, i.e. the configured access
>> control restrictions can be bypassed.  If I move the SSLVerifyClient/etc
>> to the first vhost, it works as expected.
>
> Is this fixed by Kasper Brand his patch ? (See his msg from 13/2) ?

That is the patch committed as r627699, right?  In which case, no, I'm 
seeing this behaviour with the current trunk.

joe

Re: [PATCH] Further refinements for SNI

Posted by Dirk-Willem van Gulik <di...@webweaving.org>.
On Apr 22, 2008, at 5:53 PM, Joe Orton wrote:
> On Wed, Feb 13, 2008 at 10:00:23AM +0100, Kaspar Brand wrote:
>> While I was testing revocation checking for client certs in an SNI
>> configuration (Dirk, many thanks for make_sni.sh, btw!), I came  
>> across a
>> flaw in the current implementation when CRL information - i.e.
>> SSLCARevocationFile/SSLCARevocationPath - is set on a per-vhost basis
>> (don't know how much sense it makes to have non-global CRLs, but  
>> anyway...).
>
> Someone bugged me about the SNI support so I finally go round to  
> chasing
> this up.
>
> I hacked up a quick test based on Dirk's make_sni.sh; this adds
> "SSLVerifyClient" & SSLCACertificateFile to the second and third named
> vhosts.
>
> And this confirms my original suspicions: I can access those vhosts
> without having to present a certificate, i.e. the configured access
> control restrictions can be bypassed.  If I move the SSLVerifyClient/ 
> etc
> to the first vhost, it works as expected.

Is this fixed by Kasper Brand his patch ? (See his msg from 13/2) ?

Dw.


Re: [PATCH] Further refinements for SNI

Posted by Joe Orton <jo...@redhat.com>.
On Wed, Feb 13, 2008 at 10:00:23AM +0100, Kaspar Brand wrote:
> While I was testing revocation checking for client certs in an SNI
> configuration (Dirk, many thanks for make_sni.sh, btw!), I came across a
> flaw in the current implementation when CRL information - i.e.
> SSLCARevocationFile/SSLCARevocationPath - is set on a per-vhost basis
> (don't know how much sense it makes to have non-global CRLs, but anyway...).

Someone bugged me about the SNI support so I finally go round to chasing 
this up.

I hacked up a quick test based on Dirk's make_sni.sh; this adds 
"SSLVerifyClient" & SSLCACertificateFile to the second and third named 
vhosts.

And this confirms my original suspicions: I can access those vhosts 
without having to present a certificate, i.e. the configured access 
control restrictions can be bypassed.  If I move the SSLVerifyClient/etc 
to the first vhost, it works as expected.

I'm testing trunk mod_ssl.

Index: make_sni.sh
===================================================================
--- make_sni.sh	(revision 650539)
+++ make_sni.sh	(working copy)
@@ -118,6 +118,13 @@
     -keyout ${DIR}/root.key -out ${DIR}/root.pem  \
     || exit 2
 
+# Also create a second root for signing client certs
+serial=$RANDOM
+openssl req -new -nodes -batch \
+    -x509  \
+    -days 10 -subj '/CN=Da Second Root/O=SNI testing/' -set_serial $serial \
+    -keyout ${DIR}/root-2.key -out ${DIR}/root-2.pem  \
+    || exit 2
 
 # Create the header for the example '/etc/hosts' file.
 #
@@ -177,10 +184,13 @@
 set -- ${NAMES}
 DEFAULT=$1
 
+order=0
+
 for n in ${NAMES}
 do
     FQDN=$n.$DOMAIN
     serial=`expr $serial + 1`
+    order=`expr $order + 1`
 
     # Create a certificate request for this host.
     #
@@ -230,10 +240,24 @@
     SSLCertificateChainFile ${DIR}/root.pem
     SSLCertificateFile ${DIR}/ssl/$n.crt
     TransferLog ${DIR}/logs/access_$n
-</VirtualHost>
-
 EOM
+    case $order in
+    2) cat >> ${DIR}/httpd-sni.conf <<EOM
+    SSLCACertificate ${DIR}/root.pem
+    SSLVerifyClient require
+    SSLVerifyDepth 10
+EOM
+        ;;
+    3) cat >> ${DIR}/httpd-sni.conf <<EOM
+    SSLCACertificate ${DIR}/root-2.pem
+    SSLVerifyClient require
+    SSLVerifyDepth 10
+EOM
+	;;
+    *) ;;
+    esac
 
+    echo '</VirtualHost>' >> ${DIR}/httpd-sni.conf
 done
 
 cat << EOM