On Mon, Nov 9, 2009 at 10:47 AM, Costin Manolache <cos...@gmail.com> wrote:

>
>
> On Mon, Nov 9, 2009 at 8:04 AM, Konstantin Kolinko <knst.koli...@gmail.com
> > wrote:
>
>> 2009/11/9 Mark Thomas <ma...@apache.org>:
>> > Summarising the information gathered so far from various channels
>> > (thanks to Bill B., Bill W. & Rainer who have done most of the actual
>> > work to find the info below).
>> >
>> > BIO/NIO connectors using JSSE.
>> > Vulnerable when renegotiation is triggered by the client or server.
>> > We could prevent server initiated renegotiation (and probably break the
>> > majority of configurations using CLIENT-CERT).
>> > We can't do anything to prevent client initiated renegotiation.
>> >
>> > APR/native connector using OpenSSL
>> > It is vulnerable when renegotiation is triggered by the client or by the
>> > server.
>> > Client triggered negotiation is supported.
>> > Server triggered negotiation will be supported from 1.1.17 onwards.
>> >
>> > OpenSSL 0.9.8l disables negotiation by default
>> >
>> >
>> > In terms of what this means for users:
>> >
>> > BIO/NIO
>> > - There isn't anything we can do in Tomcat to stop client
>> >  initiated renegotiation so it is a case of waiting for the JVM
>> >  vendors to respond.
>> >
>> > APR/native
>> > - Re-building their current version with 0.9.8l will protect
>> >  users at the risk of breaking any configurations that
>> >  require renegotiation.
>> > - We can release 1.1.17 with the binaries built with 0.9.8l. This
>> >  will also protect users at the risk of breaking any
>> >  configurations that require renegotiation. Mladen is doing this
>> >  now.
>> > - Supporting renegotiation whilst avoiding the vulnerability will
>> >  require a protocol fix. In the meantime, we could port port
>> >  r833582 from httpd which would disable client triggered
>> >  renegotiation for OpenSSL < 0.9.8l (which may help some users
>> >  who can't easily change their OpenSSl version and release 1.1.18
>> >  with this fix
>> > - Once the protocol is fixed, release 1.1.next bundled with the
>> >  appropriate version of OpenSSL
>> >
>> >
>> > Have I got my facts right above? If so, any objections to posting the
>> > above to the users@ and announce@ lists along with adding something to
>> > the security pages?
>> >
>> > Mark
>> >
>>
>> +1
>>
>> s/negotiation/renegotiation/
>> s/port port/port/
>>
>> A question:
>> My understanding of renegotiation is that it changes SSL session. Is
>> it possible to observe changes in the value of SSL sessionId?  I doubt
>> so, but may be?
>>
>
> AFAIK you can reuse the session ID across negotiations ( it's a nice
> optimization BTW, too
> bad we're not using, it can speed up SSL connections a lot ), I'm not sure
> if it changes
> within a renegotation, but AFAIK when you start any negotiation you can
> specify you want
> to reuse the old session id.  But if I understand the exploit correctly -
> they would want a different
> cypher, and if you reuse the session you reuse the old one.
>
>
> Maybe we can modify JSSESupport.Listener to break the connection if
> handshakeCompleted is
> called > once in a connection ? That is besides disabling server-initiated
> handshakes.
>
>

BTW - confirmed that JSSESupport.Listener is called when client does
re-negotiate, but it is not called on the first
negotiation ( it's added too late ).

However it's pretty easy to add a listener earlier, patch attached - it
should break all client re-negotiations, so we don't need
to wait for a JDK fix.

I wrote a small unit test - but I'm can't seem to get jsse client to
re-negotiate for the test, can only do it using command line
openssl. The patch seems to work - but you need so system properties  or
flags if we want to let people
 disable this ( "allowManInTheMiddle" is a good name for a flag ).  Also the
test needs a bit of work.

If anyone has more time, my 20% is getting low ....


Costin



> Costin
>
>
>
>> We read that value once and provide it to our users as
>> "javax.servlet.request.ssl_session" request attribute.
>>
>> Regarding valves (as mentioned in issue 48157):
>> I understand, that that is not sufficient, but if anyone wants to
>> check against malformed headers, they can do so.
>>
>> Best regards,
>> Konstantin Kolinko
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
>> For additional commands, e-mail: dev-h...@tomcat.apache.org
>>
>>
>
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.catalina.startup;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.tomcat.util.buf.ByteChunk;

/**
 * Requires: 
 *  keytool -genkey -alias tomcat -keyalg RSA
 *  pass: changeit 
 *  CN: localhost ( for hostname validation )
 */
public class TestTomcatSSL extends TomcatBaseTest {
    static TrustManager[] trustAllCerts = new TrustManager[] { 
        new X509TrustManager() { 
            public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
                return null;
            }
            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            }
        }
    };

    static {
        //  Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
                    sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

    public void testHandshake() throws Exception {
        Tomcat tomcat = getTomcatInstance();

        File appDir = 
            new File("output/build/webapps/examples");
        // app dir is relative to server home
        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());

        tomcat.getConnector().setSecure(true);
        tomcat.getConnector().setProperty("SSLEnabled", "true");
        tomcat.getConnector().setProperty("sslProtocol",
        "tls");

        tomcat.start();
        ByteChunk res = getUrl("https://localhost:"; + getPort() +
        "/examples/servlets/servlet/HelloWorldExample");
        assertTrue(res.toString().indexOf("<h1>Hello World!</h1>") > 0);
    }

    public void testReHandshake() throws Exception {
        Tomcat tomcat = getTomcatInstance();

        File appDir = 
            new File("output/build/webapps/examples");
        // app dir is relative to server home
        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());

        tomcat.getConnector().setSecure(true);
        tomcat.getConnector().setProperty("SSLEnabled", "true");
        tomcat.getConnector().setProperty("sslProtocol",
        "tls");

        tomcat.start();
        SSLContext sslCtx = SSLContext.getInstance("TLS");
        sslCtx.init(null, trustAllCerts, new java.security.SecureRandom());
        SSLSocketFactory socketFactory = sslCtx.getSocketFactory();
        SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost", getPort());

        socket.addHandshakeCompletedListener(new HandshakeCompletedListener() {

            @Override
            public void handshakeCompleted(HandshakeCompletedEvent event) {
                System.err.println("Handshake done");
            }
            
        });
        OutputStream os = socket.getOutputStream();
        os.write("GET /examples/servlets/servlet/HelloWorldExample HTTP/1.0\n".getBytes());
        
        socket.getSession().invalidate();
        socket.startHandshake();
        
        os.write("Host: localhost\n\n".getBytes());
        
        InputStream is = socket.getInputStream();
        ByteChunk out = new ByteChunk();
        BufferedInputStream bis = new BufferedInputStream(is);
        byte[] buf = new byte[2048];
        int rd = 0;
        while((rd = bis.read(buf)) > 0) {
            out.append(buf, 0, rd);
        }
        assertTrue(out.toString().indexOf("<h1>Hello World!</h1>") > 0);
        
    }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to