/* * Copyright 1997-2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ import java.io.*; import java.net.Socket; import java.net.SocketException; import javax.net.ssl.*; // // Base connection handler class -- server and client roles are almost // identical, this class holds everything except what's different. // abstract class Handler extends TestThread implements HandshakeCompletedListener { protected SSLSocket s; protected boolean roleIsClient; // generates the stream of test data private Traffic traffic; // for optional use in renegotiation private String renegotiateSuites []; // Test flag: did we pass this test? private boolean pass = false; Handler (String name) { super (name); } public void setRenegotiateSuites (String suites []) { renegotiateSuites = suites; } abstract public void setReverseRole (boolean flag); // XXX override setVerbosity() and pass that to // the traffic generation module public void run () { try { traffic = new Traffic (s.getInputStream (), s.getOutputStream ()); } catch (IOException e) { e.printStackTrace (); return; } if (prng != null) traffic.setPRNG (prng); if (listenHandshake || doRenegotiate) s.addHandshakeCompletedListener (this); try { if (initiateHandshake) s.startHandshake (); // XXX if use client auth ... doTraffic (0); if (doRenegotiate) s.startHandshake (); doTraffic (iterations); // XXX abortive shutdown should be a test option s.close (); // XXX want a close-this-session-down option } catch (IOException e) { String message = e.getMessage (); synchronized (out) { if (message.equalsIgnoreCase ("no cipher suites in common")) { out.println ("%% " + getName () + " " + message); } else { out.println ("%% " + getName ()); e.printStackTrace (out); } } } catch (Throwable t) { synchronized (out) { out.println ("%% " + getName ()); t.printStackTrace (out); } } } public boolean passed () { return pass; } private void doTraffic (int n) throws IOException { try { if (roleIsClient) traffic.initiate (n); else traffic.respond (n); pass = true; } catch (SSLException e) { String m = e.getMessage (); // // As of this writing, self-signed certs won't be accepted // by the simple trust decider. That rules out testing all // of the SSL_DHE_DSS_* flavors for now, and for testers // that don't have a Verisign cert, it also rules out testing // SSL_RSA_* flavors. // // XXX need two things to fix this "right": (a) ability to // let the 'simple trust decider import arbitrary certs, as // exported by a keystore; (b) specialized exceptions, since // comparing message strings is bogus. // if (m.equalsIgnoreCase ("untrusted server cert chain") || m.equalsIgnoreCase ( "Received fatal alert: certificate_unknown")) { System.out.println ("%% " + Thread.currentThread ().getName () + ", " + m); s.close (); } else throw e; } catch (SocketException e) { String m = e.getMessage (); if (m.equalsIgnoreCase ("Socket closed")) System.out.println ("%% " + Thread.currentThread ().getName () + ", " + m); else throw e; } catch (EOFException e) { // ignore } } public void handshakeCompleted (HandshakeCompletedEvent event) { if (verbosity >= 1) { Socket sock = (Socket) event.getSource (); out.println ("%% " + getName () + ", port " + sock.getLocalPort () + " to " + sock.getInetAddress ().getHostName () + ":" + sock.getPort () + ", " + event.getCipherSuite ()); // if more verbosity, give cert chain } } }