Re: TLS renegotiation attack, mod_ssl and OpenSSL
On Wed, Jan 27, 2010 at 10:41:02PM +, Dr Stephen Henson wrote: > FYI the initial documentation is here: > > http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html#SECURE_RENEGOTIATION > > there are currently only two flags to set in an SSL/SSL_CTX structure. Though > servers might want to make use of SSL_get_secure_renegotiation_support() too. Thanks a lot for doing all that work! I've added an "SSLInsecureRenegotiation" directive which will flip that flag on, here: http://svn.apache.org/viewvc?rev=906039&view=rev It seems to all work as expected with 1.0.0 beta 5. Regards, Joe
Re: TLS renegotiation attack, mod_ssl and OpenSSL
fredk2 wrote: > Hi, > > > Joe Orton wrote: >> On Tue, Nov 10, 2009 at 03:19:39PM +0100, Jean-Marc Desperrier wrote: >>> Joe Orton wrote: On Fri, Nov 06, 2009 at 12:00:06AM +, Joe Orton wrote: >> On Thu, Nov 05, 2009 at 09:31:00PM +, Joe Orton wrote: >>> > * we can detect in mod_ssl when the client is renegotiating by >> using the >>> > callback installed using SSL_CTX_set_info_callback(), in >> conjunction >>> > with suitable flags in the SSLConnRec to detect the cases where >> this is >>> > either a server-initiated renegotiation or the initial handshake >> on the >>> > connection. >> Here is a very rough first hack (for discussion/testing purposes > only!): A second hack, slightly less rough hack: >>> Joe, instead of hard coding this, a very nice solution would be to have >>> a new directive "SSLServerRenegociation Allow" or even more flexible >>> "SSLRenegociation disabled/serveronly/enabled" with disabled as default >>> value. >> Yes, sure. What is possible in mod_ssl will depend on what interfaces >> OpenSSL will expose for this, which is not yet clear. >> >> Regards, Joe >> >> > > Now that 0.9.8m-beta1 is available, what is likely to happen with Apache > 2.2.15? > I looked at the svn tree, but I could not see if anyone was working on > adding this excellent idea for a new directive SSLRenegociation > disabled/serveronly/enabled. > If the server does not require renegotiation it seems perfect if the apache > closed the connection upon receipt of the R instead of the current 5 min > (default) timeout wait. > FYI the initial documentation is here: http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html#SECURE_RENEGOTIATION there are currently only two flags to set in an SSL/SSL_CTX structure. Though servers might want to make use of SSL_get_secure_renegotiation_support() too. Steve. -- Dr Stephen N. Henson. Senior Technical/Cryptography Advisor, Open Source Software Institute: www.oss-institute.org OpenSSL Core team: www.openssl.org
Re: TLS renegotiation attack, mod_ssl and OpenSSL
Hi, Joe Orton wrote: > > On Tue, Nov 10, 2009 at 03:19:39PM +0100, Jean-Marc Desperrier wrote: >> Joe Orton wrote: >>> On Fri, Nov 06, 2009 at 12:00:06AM +, Joe Orton wrote: > On Thu, Nov 05, 2009 at 09:31:00PM +, Joe Orton wrote: > > > * we can detect in mod_ssl when the client is renegotiating by > using the > > > callback installed using SSL_CTX_set_info_callback(), in > conjunction > > > with suitable flags in the SSLConnRec to detect the cases where > this is > > > either a server-initiated renegotiation or the initial handshake > on the > > > connection. > > Here is a very rough first hack (for discussion/testing purposes only!): >>> A second hack, slightly less rough hack: >> >> Joe, instead of hard coding this, a very nice solution would be to have >> a new directive "SSLServerRenegociation Allow" or even more flexible >> "SSLRenegociation disabled/serveronly/enabled" with disabled as default >> value. > > Yes, sure. What is possible in mod_ssl will depend on what interfaces > OpenSSL will expose for this, which is not yet clear. > > Regards, Joe > > Now that 0.9.8m-beta1 is available, what is likely to happen with Apache 2.2.15? I looked at the svn tree, but I could not see if anyone was working on adding this excellent idea for a new directive SSLRenegociation disabled/serveronly/enabled. If the server does not require renegotiation it seems perfect if the apache closed the connection upon receipt of the R instead of the current 5 min (default) timeout wait. Thank you - Fred -- View this message in context: http://old.nabble.com/TLS-renegotiation-attack%2C-mod_ssl-and-OpenSSL-tp26215127p27328884.html Sent from the Apache HTTP Server - Dev mailing list archive at Nabble.com.
Re: Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
On Fri, Nov 06, 2009 at 02:00:47AM +, Dirk-Willem van Gulik wrote: > What we really need is 1) a pub/priv key pair of such a cert* (or use > attached CSR) of some random domain (ideally expired and with a totally > bogus CN valye so we can post the private key publicly) and 2) obviously > a browser which support this (but that we can handle). Rick got me an SGC-enabled test cert (thanks a lot!) - I've installed it on box which can be accessed e.g. here: https://dougal.manyfish.co.uk/cgi-bin/printenv with SSLCipherSuite tweaked to enable EXPORT ciphers; it now reads: SSLCipherSuite ALL:!ADH:EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW The box is running the RHEL 2.2.3 with the CVE-2009-3555 patch applied, so should reject any client-initiated renegotiations. Note that the cert has expired already (intentionally), but is otherwise valid. I've been trying to find a real browser to do SGC against this but have failed - help welcome here! I've tried old releases of Netscape 4.0x but they predate the Verisign root from which the cert was issued, so, prerequisite "enable SGC" trust bit in the root CA bundle isn't there. It seems like the best bet to get a working SGC-enabled browser might be Windows 2K or similar vintage with an old "export" (non-US) version of MSIE (4/5?). Can anybody dig out such a best and try loading the above page? You'd need to verify it was an export version by loading some other SSL site and checking the cipher used, and/or verifying that SGC works against one of the sites mentioned ealier: >https://www.chase.com >https://www.wellsfargo.com Regards, Joe
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On Tue, Nov 10, 2009 at 03:19:39PM +0100, Jean-Marc Desperrier wrote: > Joe Orton wrote: >> On Fri, Nov 06, 2009 at 12:00:06AM +, Joe Orton wrote: >>> > On Thu, Nov 05, 2009 at 09:31:00PM +, Joe Orton wrote: > > * we can detect in mod_ssl when the client is renegotiating by using > the > > callback installed using SSL_CTX_set_info_callback(), in conjunction > > with suitable flags in the SSLConnRec to detect the cases where this > is > > either a server-initiated renegotiation or the initial handshake on > the > > connection. >>> > >>> > Here is a very rough first hack (for discussion/testing purposes only!): >> A second hack, slightly less rough hack: > > Joe, instead of hard coding this, a very nice solution would be to have > a new directive "SSLServerRenegociation Allow" or even more flexible > "SSLRenegociation disabled/serveronly/enabled" with disabled as default > value. Yes, sure. What is possible in mod_ssl will depend on what interfaces OpenSSL will expose for this, which is not yet clear. Regards, Joe
Re: TLS renegotiation attack, mod_ssl and OpenSSL
Joe Orton wrote: On Fri, Nov 06, 2009 at 12:00:06AM +, Joe Orton wrote: > On Thu, Nov 05, 2009 at 09:31:00PM +, Joe Orton wrote: > > * we can detect in mod_ssl when the client is renegotiating by using the > > callback installed using SSL_CTX_set_info_callback(), in conjunction > > with suitable flags in the SSLConnRec to detect the cases where this is > > either a server-initiated renegotiation or the initial handshake on the > > connection. > > Here is a very rough first hack (for discussion/testing purposes only!): A second hack, slightly less rough hack: Joe, instead of hard coding this, a very nice solution would be to have a new directive "SSLServerRenegociation Allow" or even more flexible "SSLRenegociation disabled/serveronly/enabled" with disabled as default value. This would allow sites that need server renegotiation to make it quite more secure, by using a strategy similar to what is suggested here : https://issues.apache.org/bugzilla/show_bug.cgi?id=39243#c7 "The obvious answer for an 'upload' style operation is to ensure they never hit your upload page without going through a simpler front page which first enforces the renegotation. This can be your upload form page." So the server would first direct the user to a "SSLRenegociation serveronly" page that is conceived so that request to it can not be abused, and use "SSLRenegociation enabled" for all unsafe locations, the user accessing them only when his connection has already been upgraded to use client certs (this is similar to what Peter suggested already). The only weak point in that solution is that Apache seems to require renegotiation in quite a few case where it should not be really necessary. But as any case of Apache requiring renegotiation will break anyone using the more radical option of fully disabling renegotiation I'll open a separate message for this.
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On 11/09/2009 10:39 AM, Boyle Owen wrote: >> -Original Message- >> From: Dirk-Willem van Gulik [mailto:di...@webweaving.org] >> Sent: Saturday, November 07, 2009 12:28 AM >> To: dev@httpd.apache.org >> Subject: Re: TLS renegotiation attack, mod_ssl and OpenSSL >> >> +1 from me. (FreeBSD, Solaris). Test with and without certs (firefox, >> safari, openssl tool). Tested with renegotion break script openssl. > > Can I just verify what is supposed to happen with the break script test? > > I have built 2.2.14 with 0.9.8l on Solaris 10. I do: > > $ openssl -connect wibble:443 > ... > GET / HTTP/1.1 =20 > Host:wibble > R > RENEGOTIATING > > Then the connection hangs and I get no further data back from the > server. On http://wibble/server-status, I see: > > 6-0 17718 0/1/1 R 0.14 31 90 0.0 0.00 0.00 ? ? ..reading.. > > Is this the intended behaviour? I thought it was supposed to drop the > connection? Dirks tests are about the httpd patch (http://www.apache.org/dist/httpd/patches/apply_to_2.2.14/CVE-2009-3555-2.2.patch) which drops the connection. Not sure what openssl 0.9.8l does or what the intended behaviour is. You might need to ask on the openssl dev list about that. Regards Rüdiger
RE: TLS renegotiation attack, mod_ssl and OpenSSL
> -Original Message- > From: Dirk-Willem van Gulik [mailto:di...@webweaving.org] > Sent: Saturday, November 07, 2009 12:28 AM > To: dev@httpd.apache.org > Subject: Re: TLS renegotiation attack, mod_ssl and OpenSSL > > +1 from me. (FreeBSD, Solaris). Test with and without certs (firefox, > safari, openssl tool). Tested with renegotion break script openssl. Can I just verify what is supposed to happen with the break script test? I have built 2.2.14 with 0.9.8l on Solaris 10. I do: $ openssl -connect wibble:443 ... GET / HTTP/1.1 =20 Host:wibble R RENEGOTIATING Then the connection hangs and I get no further data back from the server. On http://wibble/server-status, I see: 6-0 17718 0/1/1 R 0.14 31 90 0.0 0.00 0.00 ? ? ..reading.. Is this the intended behaviour? I thought it was supposed to drop the connection? Rgds, Owen Boyle Disclaimer: Any disclaimer attached to this message may be ignored. This message is for the named person's use only. It may contain confidential, proprietary or legally privileged information. If you receive this message in error, please notify the sender urgently and then immediately delete the message and any copies of it from your system. Please also immediately destroy any hardcopies of the message. The sender's company reserves the right to monitor all e-mail communications through their networks.
Re: Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
Dirk-Willem van Gulik wrote: > Dirk-Willem van Gulik wrote: > >> Actually Steve - you may know - what besides the obvious >> >> extendedKeyUsage=nsSGC,msSGC >> >> in the extension file needs to go into a sub-ca below a >> self-signed-root-chain to make the browsers dance ? Or have they >> hardcoded in some specific CA or similar ? Or is there a test case in >> opnessl which is useful here ? As that would let us do decent tests >> script. > > Hmm - just found > > http://www.modssl.org/docs/apachecon2001/slide-010-n.html > > which seems to be one of the few places on the web; which suggest that > sepcial tagging in the browser is happening on a per-CA level. > > Is that indeed the case. That would suggest that we do need the help of > a CA to do proper testing. > Actually now I think of this there is another issue. In SGC/Step Up an export grade browser would first connect using weak crypto (because that was the strongest algorithm it would support generally) and (if the certificate was authorised) step up to strong crypto. Now that browsers can connect with strong crypto from the start there isn't a great deal of point doing that any more. In fact there's a good reason not to: the double handshake with Step Up ends up perfomring two expensive server private key operations compared to one in a normal handshake. Do any countries still have browsers restricted to weak crypto and that might use Step Up or SGC? If so you also need an appropriate browser to test it... Steve. -- Dr Stephen N. Henson. Senior Technical/Cryptography Advisor, Open Source Software Institute: www.oss-institute.org OpenSSL Core team: www.openssl.org
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On Fri, Nov 06, 2009 at 12:00:06AM +, Joe Orton wrote: > On Thu, Nov 05, 2009 at 09:31:00PM +, Joe Orton wrote: > > * we can detect in mod_ssl when the client is renegotiating by using the > > callback installed using SSL_CTX_set_info_callback(), in conjunction > > with suitable flags in the SSLConnRec to detect the cases where this is > > either a server-initiated renegotiation or the initial handshake on the > > connection. > > Here is a very rough first hack (for discussion/testing purposes only!): A second hack, slightly less rough hack: Index: ssl_private.h === --- ssl_private.h (revision 832979) +++ ssl_private.h (working copy) @@ -335,6 +335,20 @@ int is_proxy; int disabled; int non_ssl_request; + +/* Track the handshake/renegotiation state for the connection so + * that all client-initiated renegotiations can be rejected, as a + * partial fix for CVE-2009-3555. */ +enum { +RENEG_INIT = 0, /* Before initial handshake */ +RENEG_REJECT, /* After initial handshake; any client-initiated + * renegotiation should be rejected */ +RENEG_ALLOW, /* A server-initated renegotiation is taking + * place (as dictated by configuration) */ +RENEG_ABORT /* Renegotiation initiated by client, abort the + * connection */ +} reneg_state; + server_rec *server; } SSLConnRec; @@ -618,7 +632,7 @@ int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *); SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); -void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int); +void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE, int, int); #ifndef OPENSSL_NO_TLSEXT int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); #endif Index: ssl_engine_init.c === --- ssl_engine_init.c (revision 832979) +++ ssl_engine_init.c (working copy) @@ -520,10 +520,7 @@ SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); -if (s->loglevel >= APLOG_DEBUG) { -/* this callback only logs if LogLevel >= info */ -SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState); -} +SSL_CTX_set_info_callback(ctx, ssl_callback_Info); } static void ssl_init_ctx_verify(server_rec *s, Index: ssl_engine_io.c === --- ssl_engine_io.c (revision 832979) +++ ssl_engine_io.c (working copy) @@ -103,6 +103,7 @@ ap_filter_t*pInputFilter; ap_filter_t*pOutputFilter; intnobuffer; /* non-zero to prevent buffering */ +SSLConnRec *config; } ssl_filter_ctx_t; typedef struct { @@ -193,7 +194,13 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl) { bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); - + +/* Abort early if the client has initiated a renegotiation. */ +if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) { +outctx->rc = APR_ECONNABORTED; +return -1; +} + /* when handshaking we'll have a small number of bytes. * max size SSL will pass us here is about 16k. * (16413 bytes to be exact) @@ -476,6 +483,12 @@ if (!in) return 0; +/* Abort early if the client has initiated a renegotiation. */ +if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) { +inctx->rc = APR_ECONNABORTED; +return -1; +} + /* In theory, OpenSSL should flush as necessary, but it is known * not to do so correctly in some cases; see PR 46952. * @@ -1699,6 +1712,8 @@ filter_ctx = apr_palloc(c->pool, sizeof(ssl_filter_ctx_t)); +filter_ctx->config = myConnConfig(c); + filter_ctx->nobuffer= 0; filter_ctx->pOutputFilter = ap_add_output_filter(ssl_io_filter, filter_ctx, r, c); Index: ssl_engine_kernel.c === --- ssl_engine_kernel.c (revision 832979) +++ ssl_engine_kernel.c (working copy) @@ -733,6 +733,10 @@ (unsigned char *)&id, sizeof(id)); +/* Toggle the renegotiation state to allow the new + * handshake to proceed. */ +sslconn->reneg_state = RENEG_ALLOW; + SSL_renegotiate(ssl); SSL_do_handshake(ssl); @@ -754,6 +758,8 @@ SSL_set_state(ssl, SSL_ST_ACCEPT); SSL_do_handshake(ssl); +sslconn->reneg_state = RENEG
Re: Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
Dirk-Willem van Gulik wrote: > Dirk-Willem van Gulik wrote: > >> Actually Steve - you may know - what besides the obvious >> >> extendedKeyUsage=nsSGC,msSGC >> >> in the extension file needs to go into a sub-ca below a >> self-signed-root-chain to make the browsers dance ? Or have they >> hardcoded in some specific CA or similar ? Or is there a test case in >> opnessl which is useful here ? As that would let us do decent tests >> script. > > Hmm - just found > > http://www.modssl.org/docs/apachecon2001/slide-010-n.html > > which seems to be one of the few places on the web; which suggest that > sepcial tagging in the browser is happening on a per-CA level. > > Is that indeed the case. That would suggest that we do need the help of > a CA to do proper testing. > Some of it is coming back to me now ;-) If any old CA (including user installed ones) could do SGC and/or Step Up then there wouldn't be much point as the whole idea was to restrict who could use strong cryptography, prompted by the export laws of the time. You needed EKU extensions in each intermediate CA and the EE certificate in the chain (it was optional in the root) *and* the root CA had to be authorised to do SGC/Step Up. As I recall you could flip a bit/byte in the NSS certificate database to do this, I think that is documented somewhere. Caused quite a fuss at the time when this was discovered. In these more enlightened times you may be able to do the same with NSS tools. I recall doing experiments with MS CryptoAPI to enable SGC: that was many versions of Windows and MSIE ago though. You couldn't just flip a bit with that: it was hard coded to one root. I also remember that Netscape (as it was then) would only do Step up while MSIE would do Step Up or SGC depending on whether the nsSGC or msSGC EKUs were present in the chain. SGC doesn't actually renegotiate in the normal sense at all. It just sends another client hello before completing the first handshake. That was why OpenSSL needed to be modified to support it: it was a technical violation of the protocol. Steve. -- Dr Stephen N. Henson. Senior Technical/Cryptography Advisor, Open Source Software Institute: www.oss-institute.org OpenSSL Core team: www.openssl.org
Re: Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
Dirk-Willem van Gulik wrote: Actually Steve - you may know - what besides the obvious extendedKeyUsage=nsSGC,msSGC in the extension file needs to go into a sub-ca below a self-signed-root-chain to make the browsers dance ? Or have they hardcoded in some specific CA or similar ? Or is there a test case in opnessl which is useful here ? As that would let us do decent tests script. Hmm - just found http://www.modssl.org/docs/apachecon2001/slide-010-n.html which seems to be one of the few places on the web; which suggest that sepcial tagging in the browser is happening on a per-CA level. Is that indeed the case. That would suggest that we do need the help of a CA to do proper testing. Dw.
Re: Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
Dr Stephen Henson wrote: There are two separate types used by Mozilla (Step up?) and Microsoft SSL/TLS (SGC?) implementations IIRC. One completes the handshake then starts a new session the second cuts it half way through. Been many years since I looked at those though. I recall having to alter the state machine to accommodate the Microsoft flavour. (Checks code, yes look for SGC comments in there) Actually Steve - you may know - what besides the obvious extendedKeyUsage=nsSGC,msSGC in the extension file needs to go into a sub-ca below a self-signed-root-chain to make the browsers dance ? Or have they hardcoded in some specific CA or similar ? Or is there a test case in opnessl which is useful here ? As that would let us do decent tests script. Thanks, Dw
Re: Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
Dr Stephen Henson wrote: There are two separate types used by Mozilla (Step up?) and Microsoft SSL/TLS (SGC?) implementations IIRC. One completes the handshake then starts a new session the second cuts it half way through. Been many years since I looked at those though. I recall having to alter the state machine to accommodate the Microsoft flavour. (Checks code, yes look for SGC comments in there) You aware of any command line tool which implements either or both ? Dw
Re: Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
Andrews, Rick wrote: https://www.chase.com https://www.wellsfargo.com But I suppose you'll need to locate an old international browser that does step up, right? Most modern browsers will start with strong crypto and don't need to step up. What we really need is 1) a pub/priv key pair of such a cert* (or use attached CSR) of some random domain (ideally expired and with a totally bogus CN valye so we can post the private key publicly) and 2) obviously a browser which support this (but that we can handle). As we need to plug it into Joe his patched apache to see if it will still allow that initial re-negotation; but block later re-negotiaion. Dw *: Unless someone can tell me how to make the right thing with openssl; I cannot figure out how to do the extension file right - and thing it is not an option.
Re: Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
Dirk-Willem van Gulik wrote: > we propably > only have the step up 'Server Gated Certs'* let to check. > > Does anyone have such a beast for testing ? > There are two separate types used by Mozilla (Step up?) and Microsoft SSL/TLS (SGC?) implementations IIRC. One completes the handshake then starts a new session the second cuts it half way through. Been many years since I looked at those though. I recall having to alter the state machine to accommodate the Microsoft flavour. (Checks code, yes look for SGC comments in there) Steve. -- Dr Stephen N. Henson. Senior Technical/Cryptography Advisor, Open Source Software Institute: www.oss-institute.org OpenSSL Core team: www.openssl.org
Server Gated Certs (Was: TLS renegotiation attack, mod_ssl and OpenSSL)
So with Joe his patch doing the right thing it seems (would be nice if we could get Ben or the OpenSSL guys to confirm that) - that we propably only have the step up 'Server Gated Certs'* let to check. Does anyone have such a beast for testing ? or Rick - could you help us here ? Thanks, Dw. *: these are basically server certs with a special flag; causing export-grade browsers to reconnect with the export restrictions lifted and then re-negotiating a longer session key.
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On 06.11.2009 01:12, Joe Orton wrote: > On Fri, Nov 06, 2009 at 12:00:06AM +, Joe Orton wrote: > FYI - Dirk points out that you can test this using openssl s_client by > entering a line with the single character 'R' which s_client treats as a > command to initiate a renegotiation. Joe > > $ openssl s_client ... > --- > GET / HTTP/1.1 > Host: localhost > R > RENEGOTIATING > 139919233795736:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake > failure:s3_pkt.c:590: Not sure if everyone is aware: http://extendedsubset.com/Renegotiating_TLS.pdf contains such an exposure example using s_client. Eric Rescorla also explained some more details a few hours ago: http://www.educatedguesswork.org/2009/11/understanding_the_tls_renegoti.html
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On Fri, Nov 06, 2009 at 12:00:06AM +, Joe Orton wrote: > On Thu, Nov 05, 2009 at 09:31:00PM +, Joe Orton wrote: > > * we can detect in mod_ssl when the client is renegotiating by using the > > callback installed using SSL_CTX_set_info_callback(), in conjunction > > with suitable flags in the SSLConnRec to detect the cases where this is > > either a server-initiated renegotiation or the initial handshake on the > > connection. > > Here is a very rough first hack (for discussion/testing purposes only!): FYI - Dirk points out that you can test this using openssl s_client by entering a line with the single character 'R' which s_client treats as a command to initiate a renegotiation. Joe $ openssl s_client ... --- GET / HTTP/1.1 Host: localhost R RENEGOTIATING 139919233795736:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:590:
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On Thu, Nov 05, 2009 at 09:31:00PM +, Joe Orton wrote: > * we can detect in mod_ssl when the client is renegotiating by using the > callback installed using SSL_CTX_set_info_callback(), in conjunction > with suitable flags in the SSLConnRec to detect the cases where this is > either a server-initiated renegotiation or the initial handshake on the > connection. Here is a very rough first hack (for discussion/testing purposes only!): Index: ssl_private.h === --- ssl_private.h (revision 832979) +++ ssl_private.h (working copy) @@ -335,6 +335,14 @@ int is_proxy; int disabled; int non_ssl_request; +enum { +RENEG_INIT = 0, /* before initial handshake. */ +RENEG_ALLOW, /* a server-initated renegotiation is taking place */ +RENEG_REJECT, /* after initial handshake; any client-initiated + * renegotiation should be rejected. */ +RENEG_ABORT /* renegotiation initiated by client, abort abort */ +} reneg_state; + server_rec *server; } SSLConnRec; Index: ssl_engine_init.c === --- ssl_engine_init.c (revision 832979) +++ ssl_engine_init.c (working copy) @@ -520,7 +520,7 @@ SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); -if (s->loglevel >= APLOG_DEBUG) { +if (1 || s->loglevel >= APLOG_DEBUG) { /* this callback only logs if LogLevel >= info */ SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState); } Index: ssl_engine_io.c === --- ssl_engine_io.c (revision 832979) +++ ssl_engine_io.c (working copy) @@ -190,10 +190,27 @@ return -1; } +static int conn_in_reneg(conn_rec *c) +{ +SSLConnRec *scr = myConnConfig(c); + +ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, + "reneg_state == %s", scr->reneg_state == RENEG_INIT ? "INIT" : + scr->reneg_state == RENEG_REJECT ? "REJECT" : + scr->reneg_state == RENEG_ALLOW ? "ALLOW" : "ABORT"); + +return scr->reneg_state == RENEG_ABORT; +} + static int bio_filter_out_write(BIO *bio, const char *in, int inl) { bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); - + +if (conn_in_reneg(outctx->c)) { +outctx->rc = APR_EACCES; +return -1; +} + /* when handshaking we'll have a small number of bytes. * max size SSL will pass us here is about 16k. * (16413 bytes to be exact) @@ -476,6 +493,11 @@ if (!in) return 0; +if (conn_in_reneg(inctx->f->c)) { +inctx->rc = APR_EACCES; +return -1; +} + /* In theory, OpenSSL should flush as necessary, but it is known * not to do so correctly in some cases; see PR 46952. * Index: ssl_engine_kernel.c === --- ssl_engine_kernel.c (revision 832979) +++ ssl_engine_kernel.c (working copy) @@ -733,6 +733,8 @@ (unsigned char *)&id, sizeof(id)); +sslconn->reneg_state = RENEG_ALLOW; + SSL_renegotiate(ssl); SSL_do_handshake(ssl); @@ -754,6 +756,8 @@ SSL_set_state(ssl, SSL_ST_ACCEPT); SSL_do_handshake(ssl); +sslconn->reneg_state = RENEG_REJECT; + if (SSL_get_state(ssl) != SSL_ST_OK) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Re-negotiation handshake failed: " @@ -1824,7 +1828,8 @@ conn_rec *c; server_rec *s; SSLSrvConfigRec *sc; - +SSLConnRec *scr; + /* * find corresponding server */ @@ -1837,6 +1842,18 @@ return; } +scr = myConnConfig(c); + +{ +int state = SSL_get_state(ssl); + +if (scr->reneg_state == RENEG_REJECT +&& (state == SSL3_ST_SR_CLNT_HELLO_A +|| state == SSL23_ST_SR_CLNT_HELLO_A)) { +scr->reneg_state = RENEG_ABORT; +} +} + /* * create the various trace messages */ @@ -1900,6 +1917,9 @@ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER"), ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_USEKEYSIZE"), ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_ALGKEYSIZE")); +if (scr->reneg_state == RENEG_INIT) { +scr->reneg_state = RENEG_REJECT; +} } }
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On 11/05/2009 11:03 PM, Dirk-Willem van Gulik wrote: > Joe Orton wrote: > >> * we can detect in mod_ssl when the client is renegotiating by using the >> callback installed using SSL_CTX_set_info_callback(), in conjunction >> with suitable flags in the SSLConnRec to detect the cases where this is >> either a server-initiated renegotiation or the initial handshake on the >> connection. > > This seems to work for me - i.e. it calls back exactly when needed > (rather than EAGAIN like break bubbling up in kernel_io.c) - and it > _also_ seems to cover the other types of re-negotiation (i.e. other than > for a Cert) which actually worry me a lot more. > > For the record - this MiM can be done with _all_ type of > (re)negotiations - for all parameters right ? As far as I understand it: Yes. One of the examples was regarding cipher spec renegotiations and I see no reasons why other renegotiations beyond cert and cipher spec shouldn't be vulnerable. Regards Rüdiger
Re: TLS renegotiation attack, mod_ssl and OpenSSL
Joe Orton wrote: * we can detect in mod_ssl when the client is renegotiating by using the callback installed using SSL_CTX_set_info_callback(), in conjunction with suitable flags in the SSLConnRec to detect the cases where this is either a server-initiated renegotiation or the initial handshake on the connection. This seems to work for me - i.e. it calls back exactly when needed (rather than EAGAIN like break bubbling up in kernel_io.c) - and it _also_ seems to cover the other types of re-negotiation (i.e. other than for a Cert) which actually worry me a lot more. For the record - this MiM can be done with _all_ type of (re)negotiations - for all parameters right ? Thanks, Dw.
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On Thu, Nov 05, 2009 at 09:38:23PM +0100, Ruediger Pluem wrote: > If server triggered renegotiation will not work at all, people will just > ignore the > update or remove it from 0.9.8l in their self patched versions. > So overall I guess we would be safer with an approach that > > 1. Turns off renegotiation (server and client) by default. > 2. Allows to turn on server and client triggered renegotiation in a way as > proposed >by Joe. > 3. Allow to turn on server triggered renegotiation by a compile time option. In discussion here, Theo Schlossnagle has suggested (and implemented for another SSL server) an approach for (2) which I think we can use for mod_ssl, and doesn't require patching OpenSSL: * we can detect in mod_ssl when the client is renegotiating by using the callback installed using SSL_CTX_set_info_callback(), in conjunction with suitable flags in the SSLConnRec to detect the cases where this is either a server-initiated renegotiation or the initial handshake on the connection. I'll try a patch for this. Regards, Joe
Re: TLS renegotiation attack, mod_ssl and OpenSSL
On 11/05/2009 06:32 PM, Joe Orton wrote: > On Thu, Nov 05, 2009 at 03:39:06PM +, Ben Laurie wrote: >> Joe Orton wrote: >>> In the short term, I think it would be useful to have a new SSL_OP_* >>> flag which enables rejection of a client-initiated handshake in an SSL >>> server. This will fix the issue for 90% of sites without breaking the >>> remaining 10% (case 3 above), and is a change that can be deployed >>> everywhere. >> Case 3 is vulnerable to attack, though, so I'm afraid you want to break it. > > Sites depend on per-dir-reneg and people will simply not upgrade if we > break that - I have tried the "don't do that" response for per-dir-reneg > issues enough times over the years that I'm reasonably confident of > this. (Also I'm told that the Postgres SSL support depends on being > able to do a periodic reneg, in the wider context) > > Being able to ship a 90% solution now and working on the proper fixes > for the remaining 10% is valuable, I think. I agree with Joe here. See the lengthy discussions we had regarding POST bodies handling in mod_ssl during renegotiation at https://issues.apache.org/bugzilla/show_bug.cgi?id=12355 https://issues.apache.org/bugzilla/show_bug.cgi?id=39243 If server triggered renegotiation will not work at all, people will just ignore the update or remove it from 0.9.8l in their self patched versions. So overall I guess we would be safer with an approach that 1. Turns off renegotiation (server and client) by default. 2. Allows to turn on server and client triggered renegotiation in a way as proposed by Joe. 3. Allow to turn on server triggered renegotiation by a compile time option. 1. This way openssl ships save by default. 2. Consumers of the library can decide to overwrite this behaviour. 3. Packagers can decide to deliver only a "90%" solution if they do not want / cannot modify all consumer packages that need server triggered renegotiation. Some of the attacks rely on specific HTTP mechanisms like connection keep alives and pipelining. So we might be able to find patches for mod_ssl to solve these specific cases. Regards Rüdiger