Overview: For a location a ssl ciphersuite is configured, let's say "DES-CBC3-SHA". And that ciphersuite is not contained in the ciphersuites configured for the server or virtual host, lets say "RC4-MD5:DES-CBC3-SHA". If that location will be accessed a renegotiation is triggered in ssl_engine_kernel.c line 283 ff about the changed ciphersuite. But if the client wants to resume the previous session the server i.e will accept that. That means a reduced handshake will be made, and the current cipher remains unchanged! From a openssl point of view it is correct, because openssl can not know the reason for that renegotiation. (see also the ssl spec.) But aware of that in openssl 0.9.7 a new flag SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION has been introduced. Steps to reproduce: o setup a apache as descriped above: ssl caching enabled, and for example RC4-MD5,DES-CBC3-SHA configured for the virtual host, and DES-CBC3-SHA configured for the '/' location o connect with a java client using JSSE 1.4 o in the error_log can be seen that there is still the initial cipher RC4-MD5 used after the renegotiation. (a ssldump is attached bellow) That scenario has been tested with different non-java clients (MSIE, Mozilla). The described problem does not arise, because these client are not trying to resume during the renegotiation. Patch: *** ssl_engine_init.c.patched Fri Oct 1 14:15:46 2004 --- ssl_engine_init.c Mon Jun 7 12:18:37 2004 *************** *** 439,450 **** * Configure additional context ingredients */ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); - - /* no resumtion for a active renegotiation */ - #if (OPENSSL_VERSION_NUMBER >= 0x00907000) - SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); - #endif - } static void ssl_init_ctx_session_cache(server_rec *s, --- 439,444 ---- ssldump: New TCP connection #1: adnpool01.zh.adnovum.ch(36320) <-> doug.adnovum.ch(44300) 1 1 0.0119 (0.0119) C>S SSLv2 compatible client hello Version 3.1 cipher suites TLS_RSA_WITH_RC4_128_MD5 SSL2_CK_RC4 TLS_RSA_WITH_RC4_128_SHA Unknown value 0x2f Unknown value 0x33 Unknown value 0x32 TLS_RSA_WITH_3DES_EDE_CBC_SHA SSL2_CK_3DES TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA TLS_RSA_WITH_DES_CBC_SHA SSL2_CK_DES TLS_DHE_RSA_WITH_DES_CBC_SHA TLS_DHE_DSS_WITH_DES_CBC_SHA TLS_RSA_EXPORT_WITH_RC4_40_MD5 SSL2_CK_RC4_EXPORT40 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 1 2 0.0153 (0.0034) S>C Handshake ServerHello Version 3.1 session_id[32]= 0e 5e de 9d 66 47 36 ed 52 ad 43 e5 3f e8 4b 65 96 d4 47 f2 e7 00 f0 0f 81 4f 91 54 3c 55 97 f4 cipherSuite TLS_RSA_WITH_RC4_128_MD5 compressionMethod NULL 1 3 0.0153 (0.0000) S>C Handshake Certificate 1 4 0.0153 (0.0000) S>C Handshake ServerHelloDone 1 5 0.1112 (0.0959) C>S Handshake ClientKeyExchange 1 6 0.1175 (0.0062) C>S ChangeCipherSpec 1 7 0.1252 (0.0076) C>S Handshake Finished 1 8 0.1905 (0.0653) S>C ChangeCipherSpec 1 9 0.1905 (0.0000) S>C Handshake Finished 1 10 0.2025 (0.0120) C>S application_data --------------------------------------------------------------- GET /index.html HTTP/1.1 User-Agent: httpunit-client Accept-Encoding: gzip Cache-Control: no-cache Pragma: no-cache Host: doug.adnovum.ch:44300 Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive --------------------------------------------------------------- 1 11 0.2051 (0.0025) S>C Handshake HelloRequest 1 12 0.2071 (0.0019) C>S Handshake ClientHello Version 3.1 resume [32]= 0e 5e de 9d 66 47 36 ed 52 ad 43 e5 3f e8 4b 65 96 d4 47 f2 e7 00 f0 0f 81 4f 91 54 3c 55 97 f4 cipher suites TLS_RSA_WITH_RC4_128_MD5 TLS_RSA_WITH_RC4_128_SHA Unknown value 0x2f Unknown value 0x33 Unknown value 0x32 TLS_RSA_WITH_3DES_EDE_CBC_SHA TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA TLS_RSA_WITH_DES_CBC_SHA TLS_DHE_RSA_WITH_DES_CBC_SHA TLS_DHE_DSS_WITH_DES_CBC_SHA TLS_RSA_EXPORT_WITH_RC4_40_MD5 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA compression methods NULL 1 13 0.2113 (0.0042) S>C Handshake ServerHello Version 3.1 session_id[32]= 0e 5e de 9d 66 47 36 ed 52 ad 43 e5 3f e8 4b 65 96 d4 47 f2 e7 00 f0 0f 81 4f 91 54 3c 55 97 f4 cipherSuite TLS_RSA_WITH_RC4_128_MD5 compressionMethod NULL 1 14 0.2113 (0.0000) S>C ChangeCipherSpec 1 15 0.2113 (0.0000) S>C Handshake Finished 1 16 0.2190 (0.0076) C>S ChangeCipherSpec 1 17 0.2195 (0.0005) C>S Handshake Finished 1 18 0.3120 (0.0925) S>C application_data --------------------------------------------------------------- HTTP/1.1 200 OK Date: Fri, 01 Oct 2004 12:27:19 GMT Server: Apache Content-Type: text/html Content-Length: 383 Connection: close --------------------------------------------------------------- 1 19 0.3120 (0.0000) S>C application_data --------------------------------------------------------------- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <HTML> <HEAD> <TITLE>Welcome</TITLE> <LINK REL="STYLESHEET" HREF="css/styles.css" TYPE="text/css"></HEAD> <BODY BGCOLOR="#FFFFFF"> <CENTER><H2> <DIV align=right><IMG SRC="img/Nevis_f2.gif" border=0 /></DIV> Welcome to the Nevisweb Reverse Proxy </H2></CENTER> </BODY></HTML> --------------------------------------------------------------- 1 20 0.3134 (0.0014) S>C Alert level warning value close_notify 1 0.3142 (0.0007) S>C TCP FIN 1 21 0.3173 (0.0031) C>S Alert level warning value close_notify 1 0.3176 (0.0003) C>S TCP FIN
Thanks for reporting and fixing this, Hartmut. Since this is a security issue, it has been assigned CVE name CAN-2004-0885 for tracking purposes.
OK, this patch is not of course sufficient to fix the security issue since it only enforces the correct behaviour with OpenSSL 0.9.7. To actually prevent access with both 0.9.7 and 0.9.6, it's necessary to enhance SSL_hook_Access to really check that the correct cipher suite has been negotiated.
To make it working also with OpenSSL 0.9.6 you have to use SSL_CTX_set_session_id_context(..) for disabling a sucessfull cache lookup. But I would skipp supporting OpenSSL 0.9.6 for that special case, and just add the mentioned cipher check. That check would trigger for OpenSSL 0.9.6 and we have a clear situation.
This is what I committed: http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/ssl/ssl_engine_kernel.c?r1=1.110&r2=1.111 http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/ssl/ssl_engine_init.c?r1=1.128&r2=1.129 so now with 0.9.6 you'll simply get a 403 if you try and access a differently-ciphersuite-protected resource with a client which tries to resume a session during the renegotiation, and the ciphersuite in the resumed session is not sufficient. With 0.9.7 even with such a client, you shouldn't hit the check since OpenSSL will refuse to resume the session. This should have all bases covered, have I missed anything?
Proposed for backport for the next 2.0 release. For reference for those looking for an equivalent mod_ssl 2.8 patch: http://marc.theaimsgroup.com/?l=apache-modssl&m=109724918128044&q=raw