Author: mturk Date: Thu Nov 12 10:29:34 2009 New Revision: 835322 URL: http://svn.apache.org/viewvc?rev=835322&view=rev Log: Port mod_ssl fix for CVE-2009-3555
Modified: tomcat/native/trunk/native/include/ssl_private.h tomcat/native/trunk/native/src/sslcontext.c tomcat/native/trunk/native/src/sslnetwork.c tomcat/native/trunk/native/src/sslutils.c Modified: tomcat/native/trunk/native/include/ssl_private.h URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/include/ssl_private.h?rev=835322&r1=835321&r2=835322&view=diff ============================================================================== --- tomcat/native/trunk/native/include/ssl_private.h (original) +++ tomcat/native/trunk/native/include/ssl_private.h Thu Nov 12 10:29:34 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/trunk/native/src/sslcontext.c URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslcontext.c?rev=835322&r1=835321&r2=835322&view=diff ============================================================================== --- tomcat/native/trunk/native/src/sslcontext.c (original) +++ tomcat/native/trunk/native/src/sslcontext.c Thu Nov 12 10:29:34 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/trunk/native/src/sslnetwork.c URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslnetwork.c?rev=835322&r1=835321&r2=835322&view=diff ============================================================================== --- tomcat/native/trunk/native/src/sslnetwork.c (original) +++ tomcat/native/trunk/native/src/sslnetwork.c Thu Nov 12 10:29:34 2009 @@ -575,6 +575,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 +608,7 @@ } else break; } + con->reneg_state = RENEG_REJECT; if (SSL_get_state(con->ssl) != SSL_ST_OK) { return APR_EGENERAL; Modified: tomcat/native/trunk/native/src/sslutils.c URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslutils.c?rev=835322&r1=835321&r2=835322&view=diff ============================================================================== --- tomcat/native/trunk/native/src/sslutils.c (original) +++ tomcat/native/trunk/native/src/sslutils.c Thu Nov 12 10:29:34 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 --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org