From 3d7ae6e2fe78a0387c42df53d6b48f6ba380f9f9 Mon Sep 17 00:00:00 2001 From: costin Date: Tue, 10 Nov 2009 01:04:13 +0000 Subject: [PATCH] Test case for the MITM/ssl re-negotiation, also a unit test for a simple ssl request ( to check the fix didn't broke anything and ssl still works ) git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@834290 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/catalina/startup/TestTomcatSSL.java | 153 +++++++++++++++++++++ test/org/apache/catalina/startup/test.keystore | Bin 0 -> 1369 bytes 2 files changed, 153 insertions(+) create mode 100644 test/org/apache/catalina/startup/TestTomcatSSL.java create mode 100644 test/org/apache/catalina/startup/test.keystore diff --git a/test/org/apache/catalina/startup/TestTomcatSSL.java b/test/org/apache/catalina/startup/TestTomcatSSL.java new file mode 100644 index 000000000..4248e1a72 --- /dev/null +++ b/test/org/apache/catalina/startup/TestTomcatSSL.java @@ -0,0 +1,153 @@ +/* + * 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.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.net.ssl.HandshakeCompletedEvent; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +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 test.keystore (checked in), generated with: + * 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) { + } + } + }; + + private void initSsl(Tomcat tomcat) { + tomcat.getConnector().setSecure(true); + tomcat.getConnector().setProperty("SSLEnabled", "true"); + tomcat.getConnector().setProperty("sslProtocol", + "tls"); + // test runs in output/tmp + tomcat.getConnector().setAttribute("keystore", + "../../test/org/apache/catalina/startup/test.keystore"); + } + + + public void testSimpleSsl() throws Exception { + // Install the all-trusting trust manager so https:// works + // with unsigned certs. + + // TODO: cleanup ? + 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(); + } + + Tomcat tomcat = getTomcatInstance(); + + File appDir = + new File("output/build/webapps/examples"); + tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); + initSsl(tomcat); + + tomcat.start(); + ByteChunk res = getUrl("https://localhost:" + getPort() + + "/examples/servlets/servlet/HelloWorldExample"); + assertTrue(res.toString().indexOf("

Hello World!

") > 0); + } + + boolean handshakeDone = false; + + 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()); + + initSsl(tomcat); + + 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) { + handshakeDone = true; + } + }); + + OutputStream os = socket.getOutputStream(); + os.write("GET /examples/servlets/servlet/HelloWorldExample HTTP/1.0\n".getBytes()); + os.flush(); + + InputStream is = socket.getInputStream(); + + // Doesn't seem to work.. + socket.getSession().invalidate(); + socket.startHandshake(); + handshakeDone = false; + byte[] b = new byte[0]; + int maxTries = 60; // 60 * 1000 = example 1 minute time out + socket.setSoTimeout(1000); + for (int i = 0; i < maxTries; i++) { + try { + is.read(b); + } catch (IOException e) { + // timeout + } + if (handshakeDone) { + break; + } + } + SSLSession session = socket.getSession(); + os = socket.getOutputStream(); + + try { + os.write("Host: localhost\n\n".getBytes()); + } catch (IOException ex) { + // success - connection closed + return; + } + + fail("Re-negotiation worked"); + + } +} diff --git a/test/org/apache/catalina/startup/test.keystore b/test/org/apache/catalina/startup/test.keystore new file mode 100644 index 0000000000000000000000000000000000000000..8491841b71078688eb98184d964698d12db0e28c GIT binary patch literal 1369 zcmezO_TO6u1_mY|W&~rllKkA{#1bG^<+H8z0j9N^BjEt-d zEKN*{V?XqsDagF~Ds8*^>8JnpyC^$NNjTZH_qedD_^;%3B8jJ`>GQS~ct<|n^OB7% z@$~V(J9BoWy_$1%;xp?_2khdljL*E{Vg9{yuh{?ov=uEy{|i25ymaUK*CG=5F_*z? z<{Xx3rL4tAKbdU2bpPRLw@q_X+^bG~6g@lX)qzN}>7j<7Lp=^}WpcZHeCq#?1$2i0-D#C$f6I&Ys2uY%m#k%tIbvL9;TbVWvTq+f zkx{Gq@Rs*NNJb`O`_txQ4cRwx1$!bV@H|+1zu=PK+YPN(tXFNc*FIAG?@e9r%ZbN% z+0&<&8n$lBc2t|>w_@1>DbMvjTnZC1AB*hTuZbkzIKmlkLH{h2hGPD^}_|Hfay z^L9#VE$=zDC6g@#WpB(ZyWA}J@BXr47oIZ19i8SZW%ZtaC-Xlj)!Y?$TuO~Kj%~K{ zI_a${b?Z#~&6=iIJp7jZ!rjpL)lM;O^<*cj`B%KMWzVmYD425J{ZrIphn$7CGz@rF zRY?||x~P69wcyoD`55j1^<9@7B0t>=tNoYKRWK*Oz~$_9u^+`-d@9+C4B3*Z?M^eT zp0~=c?!MTIDaU0G2|j%(vC-0}Z_8=ct$ZtFUS)H5p4c`ys@c3gezjkrS97U$=VvF8 zK=$^#%d2J_>Yci@vhaSIa*b1?=_k4&C9>E+q~2J&t7hDl4gz2Gc~XTrsQy7 zN)9$?V%)QUnTe5!iN)(jgSP=M8>d#AN85K^V6tXqFvv3$0H$^3P!={}_RzfSy!>*w z2nU7;JBA1sh6p!8M94q@WHPfbXHI@{VopYWafyMPIIn@Fp`n4Lk%5V&p=p#juc3i~ zk%2jsOLzA)&PNUrU`}Ul>}4=$>||?;Baq z%UTISb?gtNPi04X2nnq__y3%&(T1W;N-LGVoc$=jX=0oJ2T#z9MkMEVS&ilE9wH(=^-em?qtQp;dE4GuNZv_PvDv zk|mZ~tl#{KRS5m=xPSiQMQ>T3u^pPULS~Bel)0{A8~t8CC}Y$Os1Z|~bo%zsQx83( zm3ee#iZOmjI4@c{r<%!5c=@_hLF_Mf<+Clgq*hmojn@wqws(I$QL$0wz&-%ZHY`E_ literal 0 HcmV?d00001 -- 2.11.0