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: [email protected]
For additional commands, e-mail: [email protected]