All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.grinder.tools.tcpproxy.TCPProxySSLSocketFactoryImplementation Maven / Gradle / Ivy

// Copyright (C) 2000 Phil Dawes
// Copyright (C) 2000 - 2008 Philip Aston
// All rights reserved.
//
// This file is part of The Grinder software distribution. Refer to
// the file LICENSE which is part of The Grinder distribution for
// licensing details. The Grinder distribution is available on the
// Internet at http://grinder.sourceforge.net/
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

package net.grinder.tools.tcpproxy;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocketFactory;

import HTTPClient.HTTPConnection;

import net.grinder.common.Closer;
import net.grinder.common.SSLContextFactory.SSLContextFactoryException;
import net.grinder.util.InsecureSSLContextFactory;


/**
 * {@link TCPProxySocketFactory} for SSL connections.
 *
 * 

ARGHH. I hate JSSE.

* *

The JSSE docs rabbit on about being able to create factories * with the required parameters, this is a lie. Where is * "SSL[Server]SocketFactory.setEnabledCipherSuites()"? Hence the need * for our own abstract factories.

* *

We can't install our own TrustManagerFactory without messing * with the security properties file. Hence we create our own * SSLContext and initialise it.

* * - PhilA * * @author Philip Aston * @author Phil Dawes */ public final class TCPProxySSLSocketFactoryImplementation implements TCPProxySSLSocketFactory { private final ServerSocketFactory m_serverSocketFactory; private final SSLSocketFactory m_clientSocketFactory; /** * Construct a TCPProxySSLSocketFactoryImplementation that uses the * specified key store. * * @param keyStoreFile Key store file. * @param keyStorePassword Key store password, or null * if no password. * @param keyStoreType Key store type, or null if the * default keystore type should be used. * @exception IOException If an I/O error occurs. * @exception GeneralSecurityException If a security error occurs. * @exception SSLContextFactoryException If SSLContext could not be created. */ public TCPProxySSLSocketFactoryImplementation(File keyStoreFile, char[] keyStorePassword, String keyStoreType) throws IOException, GeneralSecurityException, SSLContextFactoryException { this(new FileInputStream(keyStoreFile), keyStoreType != null ? keyStoreType : KeyStore.getDefaultType(), keyStorePassword); } /** * Construct a TCPProxySSLSocketFactoryImplementation that uses the * built-in key store. * * @exception IOException If an I/O error occurs. * @exception GeneralSecurityException If a security error occurs. * @exception SSLContextFactoryException If SSLContext could not be created. */ public TCPProxySSLSocketFactoryImplementation() throws IOException, GeneralSecurityException, SSLContextFactoryException { this(TCPProxySSLSocketFactoryImplementation.class.getResourceAsStream( "resources/default.keystore"), "jks", "passphrase".toCharArray()); } private TCPProxySSLSocketFactoryImplementation( InputStream keyStoreInputStream, String keyStoreType, char[] keyStorePassword) throws IOException, GeneralSecurityException, SSLContextFactoryException { try { final InsecureSSLContextFactory sslContextFactory = new InsecureSSLContextFactory(keyStoreInputStream, keyStorePassword, keyStoreType); final SSLContext sslContext = sslContextFactory.getSSLContext(); m_clientSocketFactory = sslContext.getSocketFactory(); m_serverSocketFactory = sslContext.getServerSocketFactory(); } finally { Closer.close(keyStoreInputStream); } } /** * Factory method for server sockets. * * @param localEndPoint Local host and port. * @param timeout Socket timeout. * @return A new ServerSocket. * @exception IOException If an error occurs. */ public ServerSocket createServerSocket(EndPoint localEndPoint, int timeout) throws IOException { final SSLServerSocket socket = (SSLServerSocket)m_serverSocketFactory.createServerSocket( localEndPoint.getPort(), 50, InetAddress.getByName(localEndPoint.getHost())); socket.setSoTimeout(timeout); socket.setEnabledCipherSuites(socket.getSupportedCipherSuites()); socket.setEnabledProtocols(socket.getSupportedProtocols()); return socket; } /** * Factory method for client sockets. * * @param remoteEndPoint Remote host and port. * @return A new Socket. * @exception IOException If an error occurs. */ public Socket createClientSocket(EndPoint remoteEndPoint) throws IOException { final SSLSocket socket; try { socket = (SSLSocket)m_clientSocketFactory.createSocket( remoteEndPoint.getHost(), remoteEndPoint.getPort()); } catch (ConnectException e) { throw new VerboseConnectException(e, "SSL end point " + remoteEndPoint); } socket.setEnabledCipherSuites(HTTPConnection.getSSLCipherSuites()); socket.setEnabledProtocols(HTTPConnection.getSSLProtocols()); return socket; } /** *

Factory method for client sockets that are layered over * existing sockets. Used to establish HTTPS proxy connections.

* *

The SSL socket takes ownership of the existing socket; when * the SSL socket is closed, the existing socket will also be * closed.

* * @param existingSocket The existing socket. * @param remoteEndPoint Remote host and port. Not the proxy. As far as I * can gather, the JSSE does not use this information. * @return A new Socket. * @exception IOException If an error occurs. */ public Socket createClientSocket(Socket existingSocket, EndPoint remoteEndPoint) throws IOException { final SSLSocket socket = (SSLSocket)m_clientSocketFactory.createSocket( existingSocket, remoteEndPoint.getHost(), remoteEndPoint.getPort(), true); socket.setEnabledCipherSuites(HTTPConnection.getSSLCipherSuites()); socket.setEnabledProtocols(HTTPConnection.getSSLProtocols()); return socket; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy