Author: mturk Date: Tue Nov 17 07:44:03 2009 New Revision: 881179 URL: http://svn.apache.org/viewvc?rev=881179&view=rev Log: Backport CVE-2009-3555 patch from trunk
Modified: tomcat/native/branches/1.1.x/STATUS.txt tomcat/native/branches/1.1.x/native/include/ssl_private.h tomcat/native/branches/1.1.x/native/src/sslcontext.c tomcat/native/branches/1.1.x/native/src/sslnetwork.c tomcat/native/branches/1.1.x/native/src/sslutils.c tomcat/native/branches/1.1.x/xdocs/miscellaneous/changelog.xml Modified: tomcat/native/branches/1.1.x/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/STATUS.txt?rev=881179&r1=881178&r2=881179&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/STATUS.txt (original) +++ tomcat/native/branches/1.1.x/STATUS.txt Tue Nov 17 07:44:03 2009 @@ -34,10 +34,3 @@ * Add detection of the macosx jvm. Backport from trunk http://svn.eu.apache.org/viewvc?view=rev&revision=803803 - -* Fix CVE-2009-3555 by disabling renegotiation - Backport from trunk - https://svn.apache.org/viewvc?view=revision&revision=835322 - https://svn.apache.org/viewvc?view=revision&revision=835335 - +1: mturk, jfclere - -1: Modified: tomcat/native/branches/1.1.x/native/include/ssl_private.h URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/native/include/ssl_private.h?rev=881179&r1=881178&r2=881179&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/native/include/ssl_private.h (original) +++ tomcat/native/branches/1.1.x/native/include/ssl_private.h Tue Nov 17 07:44:03 2009 @@ -256,12 +256,29 @@ tcn_pass_cb_t *cb_data; }; + typedef struct { apr_pool_t *pool; tcn_ssl_ctxt_t *ctx; SSL *ssl; X509 *peer; int shutdown_type; + /* 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; apr_socket_t *sock; apr_pollset_t *pollset; } tcn_ssl_conn_t; @@ -287,6 +304,7 @@ DH *SSL_dh_get_param_from_file(const char *); RSA *SSL_callback_tmp_RSA(SSL *, int, int); DH *SSL_callback_tmp_DH(SSL *, int, int); +void SSL_callback_handshake(const SSL *, int, int); void SSL_vhost_algo_id(const unsigned char *, unsigned char *, int); int SSL_CTX_use_certificate_chain(SSL_CTX *, const char *, int); int SSL_callback_SSL_verify(int, X509_STORE_CTX *); Modified: tomcat/native/branches/1.1.x/native/src/sslcontext.c URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/native/src/sslcontext.c?rev=881179&r1=881178&r2=881179&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/native/src/sslcontext.c (original) +++ tomcat/native/branches/1.1.x/native/src/sslcontext.c Tue Nov 17 07:44:03 2009 @@ -162,6 +162,7 @@ /* Set default password callback */ SSL_CTX_set_default_passwd_cb(c->ctx, (pem_password_cb *)SSL_password_callback); SSL_CTX_set_default_passwd_cb_userdata(c->ctx, (void *)(&tcn_password_callback)); + SSL_CTX_set_info_callback(c->ctx, SSL_callback_handshake); /* * Let us cleanup the ssl context when the pool is destroyed */ Modified: tomcat/native/branches/1.1.x/native/src/sslnetwork.c URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/native/src/sslnetwork.c?rev=881179&r1=881178&r2=881179&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/native/src/sslnetwork.c (original) +++ tomcat/native/branches/1.1.x/native/src/sslnetwork.c Tue Nov 17 07:44:03 2009 @@ -181,6 +181,10 @@ return APR_ENOPOLL; if (!con->sock) return APR_ENOTSOCK; + if (con->reneg_state == RENEG_ABORT) { + con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN; + return APR_ECONNABORTED; + } /* Check if the socket was already closed */ @@ -384,6 +388,11 @@ int s, i, wr = (int)(*len); apr_status_t rv = APR_SUCCESS; + if (con->reneg_state == RENEG_ABORT) { + *len = 0; + con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN; + return APR_ECONNABORTED; + } for (;;) { if ((s = SSL_read(con->ssl, buf, wr)) <= 0) { apr_status_t os = apr_get_netos_error(); @@ -440,6 +449,11 @@ int s, i, wr = (int)(*len); apr_status_t rv = APR_SUCCESS; + if (con->reneg_state == RENEG_ABORT) { + *len = 0; + con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN; + return APR_ECONNABORTED; + } for (;;) { if ((s = SSL_write(con->ssl, buf, wr)) <= 0) { apr_status_t os = apr_get_netos_error(); @@ -575,6 +589,11 @@ * ssl->state = SSL_ST_ACCEPT * SSL_do_handshake() */ + + /* Toggle the renegotiation state to allow the new + * handshake to proceed. + */ + con->reneg_state = RENEG_ALLOW; retVal = SSL_renegotiate(con->ssl); if (retVal <= 0) return APR_EGENERAL; @@ -603,6 +622,7 @@ } else break; } + con->reneg_state = RENEG_REJECT; if (SSL_get_state(con->ssl) != SSL_ST_OK) { return APR_EGENERAL; Modified: tomcat/native/branches/1.1.x/native/src/sslutils.c URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/native/src/sslutils.c?rev=881179&r1=881178&r2=881179&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/native/src/sslutils.c (original) +++ tomcat/native/branches/1.1.x/native/src/sslutils.c Tue Nov 17 07:44:03 2009 @@ -672,4 +672,41 @@ return ok; } +/* + * This callback function is executed while OpenSSL processes the SSL + * handshake and does SSL record layer stuff. It's used to trap + * client-initiated renegotiations, and for dumping everything to the + * log. + */ +void SSL_callback_handshake(const SSL *ssl, int where, int rc) +{ + tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl); + + /* Retrieve the conn_rec and the associated SSLConnRec. */ + if (con == NULL) { + return; + } + + + /* If the reneg state is to reject renegotiations, check the SSL + * state machine and move to ABORT if a Client Hello is being + * read. */ + if ((where & SSL_CB_ACCEPT_LOOP) && con->reneg_state == RENEG_REJECT) { + int state = SSL_get_state(ssl); + + if (state == SSL3_ST_SR_CLNT_HELLO_A + || state == SSL23_ST_SR_CLNT_HELLO_A) { + con->reneg_state = RENEG_ABORT; + /* XXX: rejecting client initiated renegotiation + */ + } + } + /* If the first handshake is complete, change state to reject any + * subsequent client-initated renegotiation. */ + else if ((where & SSL_CB_HANDSHAKE_DONE) && con->reneg_state == RENEG_INIT) { + con->reneg_state = RENEG_REJECT; + } + +} + #endif Modified: tomcat/native/branches/1.1.x/xdocs/miscellaneous/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/xdocs/miscellaneous/changelog.xml?rev=881179&r1=881178&r2=881179&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/xdocs/miscellaneous/changelog.xml (original) +++ tomcat/native/branches/1.1.x/xdocs/miscellaneous/changelog.xml Tue Nov 17 07:44:03 2009 @@ -36,6 +36,12 @@ new documentation project for Tomcat Native was started. </p> </section> +<section name="Changes between 1.1.17 and 1.1.18"> + <changelog> + <fix> + Fix CVE-2009-3555 SSL-Man-In-The-Middle attack. (mturk) + </fix> +</section> <section name="Changes between 1.1.16 and 1.1.17"> <changelog> <update> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org