![JAR search and dependency download from the Maven repository](/logo.png)
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