SSL Handshake failed Android 5.1 - java

Since Android 5.0.2 or 5.1.1 on Samsung devices my Android app receive error message when connecting web interface of old router "FRITZ!Box 7170".
javax.net.ssl.SSLProtocolException: SSL handshake aborted:
ssl=0xaecc7e00: Failure in SSL library, usually a protocol error
error:14082174:SSL routines:SSL3_CHECK_CERT_AND_ALGORITHM:got Channel
ID before a ccs (external/openssl/ssl/s3_clnt.c:3632
0xaf0e1679:0x00000000)
If I connect same interface with Firefox Browser:
ssl_error_weak_server_ephemeral_dh_key
I think it is because of unsafe Diffie-Hellman key length?
How to avoid this? I am using HTTPClient to make the connection.

I have a same problem.
The reason was a samsung security update, which has change a default cipher suite array given by SSLSocketFactory. Apropos if you take a nexus device with android M on it, you will see this error message
ssl_error_weak_server_ephemeral_dh_key
On samsung devices it is a
SSL3_CHECK_CERT_AND_ALGORITHM
The solution for me was to override cipher suites array. Here is my SSLSocketFactory, which I use to create ssl sockets.
public class SpeedportSSLSocketFactory extends SSLSocketFactory {
private final static Logger logger = Logger.getLogger(SpeedportSSLSocketFactory.class);
/**
* the order of ciphers in this list is important here e.g. TLS_DHE_* must not stay above TLS_RSA_*
*/
private static final String[] APPROVED_CIPHER_SUITES = new String[]{
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_AES_128_GCM_SHA256",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
};
private SSLSocketFactory factory;
public SpeedportSSLSocketFactory() {
try {
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[]{
// accepts certs with valid but expired key chain (incl. root cert)
new ExpiredSpeedportTrustManager()}, new java.security.SecureRandom());
factory = sslcontext.getSocketFactory();
} catch (Exception ex) {
logger.error("Cannot create SpeedportSSLSocketFactory", ex);
}
}
// dirty
private void injectHostname(InetAddress address, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(address, host);
} catch (Exception ignored) {
logger.error("Cannot inject hostName");
}
}
public static SocketFactory getDefault() {
return new SpeedportSSLSocketFactory();
}
public Socket createSocket() throws IOException {
return factory.createSocket();
}
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return factory.createSocket(socket, host, port, autoClose);
}
public Socket createSocket(InetAddress addr, int port, InetAddress localAddr, int localPort) throws IOException {
return factory.createSocket(addr, port, localAddr, localPort);
}
public Socket createSocket(InetAddress inaddr, int i) throws IOException {
return factory.createSocket(inaddr, i);
}
public Socket createSocket(String host, int port, InetAddress localAddr, int localPort) throws IOException {
return factory.createSocket(host, port, localAddr, localPort);
}
public Socket createSocket(String host, int port) throws IOException {
InetAddress addr = InetAddress.getByName(host);
injectHostname(addr, host);
Socket socket = factory.createSocket(addr, port);
((SSLSocket) socket).setEnabledCipherSuites(getSupportedCipherSuites());
return socket;
}
#Override
public String[] getDefaultCipherSuites() {
return APPROVED_CIPHER_SUITES;
}
#Override
public String[] getSupportedCipherSuites() {
return APPROVED_CIPHER_SUITES;
}
}
Last two methods override default cipher suite. I am not sure, what you need override both.
The order in cipher suites array is also very important

Related

Configure Apache HttpClient 4.5 as a transport sender in Axis2 stub

I am in the process of replacing Apache Httpclient 3.1 to 4.5 version, Our application is using AXIS 2 SOAP Web Service stub which underneath is using HTTPClient 3.1 TransportSender. I need to migrate it to use HttpClient 4.5 version. Below is the complete code that need to be migrated to HttpClient 4.5 version :
import org.apache.commons.httpclient.protocol.Protocol; // 3.1 version
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; // 3.1 version
final Options clientOptions = stub._getServiceClient().getOptions();
clientOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER, new Protocol("https", new TLSSocketFactory(), 443));
public class TLSSocketFactory extends SSLSocketFactory implements SecureProtocolSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.getSocketFactory();
}
#Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
#Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
#Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
#Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
#Override
public Socket createSocket(String s, int i, InetAddress inetAddress, int i1, HttpConnectionParams httpConnectionParams) throws IOException, UnknownHostException, ConnectTimeoutException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, i, inetAddress, i1));
}
#Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
#Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}
I came across this StackOverflow post : How to configure SSL with Axis2 using httpClient4
But its clearly mentioned in the post that it is only compatible upto httpclient 4.4.1.
Axis2 1.7.0 supports Apache HttpClient 4.x in addition to the no
longer maintained Commons HttpClient 3.x. To enable the support for
HttpClient 4.x, use
org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender
instead of org.apache.axis2.transport.http.CommonsHTTPTransportSender
in axis2.xml. Please note that the code was written for HttpClient
4.2.x and should work with 4.3.x and 4.4.x, but is incompatible with 4.5.x.
We are using HttpClient 4.5 and it clearly says it's incompatible with 4.5.x
I am really stuck and need help on migrating the above piece of code to use HttpClient 4.5.
Thanks in advance.
The steps mentioned in the below SO Post works for HttpClient 4.5.x as well.
configure SSL with Axis2 using httpClient4

SSL Handshake exception in Android WebView [duplicate]

My application uses WebViewClient to make SSL connections to the server.
The server is configured to only accept TLSv1.1 and above protocols.
How do I check which SSL protocols are a) Supported and b) Enabled by default when using Android WebViewClient on a device.
How do I enable specific SSL protocols for Android WebViewClient instance used in my application.
On one of the test devices running Android 4.3,
WebViewClient throws onReceivedError callback with the following description:
"Failed to perform SSL handshake"
Chrome logs are as follows:
01-29 15:58:00.073 5486 5525 W chromium_net: external/chromium/net/http/http_stream_factory_impl_job.cc:865: [0129/155800:WARNING:http_stream_factory_impl_job.cc(865)] Falling back to SSLv3 because host is TLS intolerant: 10.209.126.125:443 01-29 15:58:00.083 5486 5525 E chromium_net: external/chromium/net/socket/ssl_client_socket_openssl.cc:792: [0129/155800:ERROR:ssl_client_socket_openssl.cc(792)] handshake failed; returned 0, SSL error code 5, net_error -107
My application also uses HttpClient and HttpsUrlConnection classes to setup SSL Connections. I was able to use SSLSocket API to enable specific protocols when using these classes.
http://developer.android.com/reference/javax/net/ssl/SSLSocket.html#setEnabledProtocols(java.lang.String[])
I need to do the same with WebViewClient.
As per documenation it is NOT possible to support TLS 1.0 in WebView in Android < 4.3. For Android 4.4 it is disabled by default.
Check this chart for support of TLS 1.0 in different browsers: https://en.wikipedia.org/wiki/Transport_Layer_Security#Web_browsers
If your app is using, or you are willing to use, Google Play services, you can use newer security features on older phones by installing their Provider. It is easy to install, only one line (plus exception handling, etc). You will also need to add google play services to your gradle file if you do not already have it. ProviderInstaller is included in the -base package.
try {
ProviderInstaller.installIfNeeded(this);
} catch (GooglePlayServicesRepairableException e) {
// Fix it
} catch (GooglePlayServicesNotAvailableException e) {
// Skip it
}
For a full example, see "Updating Your Security Provider to Protect Against SSL Exploits" from Google.
Actually, I managed to make it work, but you need okHttp library for that.
Try this when you're setting up browser activity:
WebViewClient client = new WebViewClient() {
private OkHttpClient okHttp = new OkHttpClient.Builder().build();
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
Request okHttpRequest = new Request.Builder().url(url).build();
try {
Response response = okHttp.newCall(okHttpRequest).execute();
return new WebResourceResponse(response.header("Content-Type", "plain/text"), response.header("Content-Encoding", "deflate"), response.body().byteStream());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
webView.setWebViewClient(client);
Also, you'll need classic Trust Manager Manipulator, SSL socket factory and its implementation in your Application class:
public class TrustManagerManipulator implements X509TrustManager {
private static TrustManager[] trustManagers;
private static final X509Certificate[] acceptedIssuers = new X509Certificate[] {};
public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}
public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}
public static void allowAllSSL()
{
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[] { new TrustManagerManipulator() };
}
try {
context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(context
.getSocketFactory());
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return acceptedIssuers;
}
}
SSl Socket Factory:
public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
TrustManager[] managers = new TrustManager[] { new TrustManagerManipulator() };
context.init(null, managers, new SecureRandom());
internalSSLSocketFactory = context.getSocketFactory();
}
#Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
#Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
#Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
#Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
#Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
#Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}
App class:
public class App extends Application {
private static App appInstance;
#Override
public void onCreate() {
super.onCreate();
setupSSLconnections();
}
private void setupSSLconnections() {
try {
HttpsURLConnection.setDefaultSSLSocketFactory(new TLSSocketFactory());
} catch (KeyManagementException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
}
it's beause android 4.3 not support TSL 1.1 but only TSL1.0
read this article
https://www.ssllabs.com/ssltest/clients.html
find android 4.3 will see
Protocols
TLS 1.3 No
TLS 1.2 No
TLS 1.1 No
TLS 1.0 Yes
SSL 3 INSECURE Yes
SSL 2 No

How to let Jersey client use the defaultSSLSocketFactory set in HttpsURLConnection?

I have a project in which HttpsURLConnection is configed to use a customized TrustManager as following:
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new MyTrustManager()}, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
There is a REST API client in this project, it uses Jersey client to send HTTP/HTTPS request:
Client client = ClientBuilder.newClient();
However, the HTTPS connection initiated by this Jerset client does not use the defaultSSLSocketFactory I set in HttpsURLConnection and it fails to connect to untrusted HTTPS url.
I need to explicitly set the SslContext on this client to make it work with my TrustManager.
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new MyTrustManager()}, null);
Client client = ClientBuilder.newBuilder().sslContext(sslContext).build();
Is there any way to solve this issue?
Thanks.
The solution I eventually found is to set the SSLSocketFactory provider property to a customized SSLSocketFactory. Hope this can help others who have similar issues.
Call this in beginning of the program:
Security.setProperty("ssl.SocketFactory.provider", MySSLSocketFactory.class.getCanonicalName());
Here is how MySSLSocketFactory looks like (it also sets connection timeout):
public class MySSLSocketFactory extends SSLSocketFactory {
private SSLContext sslContext = SSLContext.getInstance(Const.Ssl.PROTOCOL_SSL);
public MySSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
this.sslContext.init(
null,
new TrustManager[] { new MyTrustManager(false) },
new SecureRandom());
}
#Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException {
socket.connect(new InetSocketAddress(host, port), Const.Ssl.CONNECT_TIMEOUT);
socket.setSoTimeout(Const.Ssl.DATA_TIMEOUT);
return this.sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
#Override
public String[] getDefaultCipherSuites() {
return this.sslContext.getSocketFactory().getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites() {
return this.sslContext.getSocketFactory().getSupportedCipherSuites();
}
#Override
public Socket createSocket(String host, int port)
throws IOException, UnknownHostException {
return this.createSocket(new Socket(), host, port, true);
}
#Override
public Socket createSocket(InetAddress address, int port)
throws IOException {
return this.createSocket(new Socket(), address.getHostAddress(), port, true);
}
#Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
throws IOException, UnknownHostException {
return this.createSocket(new Socket(), host, port, true);
}
#Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
throws IOException {
return this.createSocket(new Socket(), address.getHostAddress(), port, true);
}

SSLSocket of HttpsURLConnection

I have a JEditorPane which loads a website over SSL/TLS. My goal is to get (with reflection) specific information of the SSL connection like the finished message of the SSL handshake. The only thing I get from JEditorPane is the URL and thus the HttpsURLConnection.
But how do I get the SSLSocket of the HttpsURLConnection? Any ideas?
There is no direct way to get it. But you can control the SSL socket used by the HttpsURLConnection. You can set the socket factory in the httppsURLConnection.setSSLSocketFactory().
You can create a custom socket factory which creates your owns decorated sslsocket and return it. This will be the socket used by your HttpsURLConnection.
Note that u need to do this before the connection is established.
SSLSocketFactory sslSktFactory = SSLContext.getInstance("TLS").getSocketFactory();
httpsUrlConnection.setSSLSocketFactory(new CustomSSLSocketFactory(sslSktFactory ));
A sample custom SSL socket factory is below
class CustomSSLSocketFactory extends SSLSocketFactory {
SSLSocketFactory factory = null;
CustomSSLSocketFactory(SSLSocketFactory factory) {
this.factory = factory;
}
#Override
public Socket createSocket(Socket s, String host, int port,
boolean autoClose) throws IOException {
Socket skt = factory.createSocket(s, host, port, autoClose);
return customizeSSLSocket(skt);
}
#Override
public String[] getDefaultCipherSuites() {
return factory.getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites() {
return factory.getSupportedCipherSuites();
}
#Override
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
Socket skt = factory.createSocket(host, port);
return customizeSSLSocket(skt);
}
#Override
public Socket createSocket(InetAddress host, int port) throws IOException {
Socket skt = factory.createSocket(host, port);
return customizeSSLSocket(skt);
}
#Override
public Socket createSocket(String host, int port, InetAddress localHost,
int localPort) throws IOException, UnknownHostException {
Socket skt = factory.createSocket(host, port, localHost, localPort);
return customizeSSLSocket(skt);
}
#Override
public Socket createSocket(InetAddress address, int port,
InetAddress localAddress, int localPort) throws IOException {
Socket skt = factory.createSocket(address, port, localAddress, localPort);
return customizeSSLSocket(skt);
}
private Socket customizeSSLSocket(Socket skt) throws SocketException {
((SSLSocket)skt).addHandshakeCompletedListener(
new HandshakeCompletedListener() {
public void handshakeCompleted(
HandshakeCompletedEvent event) {
System.out.println("Handshake finished!");
System.out.println(
"\t CipherSuite:" + event.getCipherSuite());
System.out.println(
"\t SessionId " + event.getSession());
System.out.println(
"\t PeerHost " + event.getSession().getPeerHost());
System.out.println(
"\t PeerHost " + event.getSession().getProtocol());
}
}
);
return skt;
}

HTTPS POST using HttpClient API opening 2 sockets

After a lot of R&D and googling, not able to troubleshoot my problem.
Environment Setup
Web Server (Tomcat 6.0.20) --> Proxy Server (Windows Server 2007) --> Thirdy part host
We have application, which does online payment transaction, after completion of this transaction, we want to send status of transaction to third party server. So posting data to third part server from our web server is opening 2 sockets for one transaction at proxy server, but when we check at web server it has created only one socket. SO why 2 socket at proxy server.
Below is my sample code
import javax.net.ssl.*;
import javax.net.SocketFactory;
import java.net.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.Hashtable;
import java.math.BigInteger;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.protocol.*;
public class HTTPPostDemo {
private String privateKey;
private String host;
private int port;
private String userName;
private Header[] headers = null;
public class MySSLSocketFactory implements SecureProtocolSocketFactory {
private TrustManager[] getTrustManager() {
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) {
}
}
};
return trustAllCerts;
}
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
TrustManager[] trustAllCerts = getTrustManager();
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
SocketFactory socketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
return socketFactory.createSocket(host, port);
} catch (Exception ex) {
throw new UnknownHostException("Problems to connect " + host + ex.toString());
}
}
public Socket createSocket(Socket socket, String host, int port, boolean flag) throws IOException, UnknownHostException {
TrustManager[] trustAllCerts = getTrustManager();
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
SocketFactory socketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
return socketFactory.createSocket(host, port);
} catch (Exception ex) {
throw new UnknownHostException("Problems to connect " + host + ex.toString());
}
}
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException {
TrustManager[] trustAllCerts = getTrustManager();
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
SocketFactory socketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
return socketFactory.createSocket(host, port, clientHost, clientPort);
} catch (Exception ex) {
throw new UnknownHostException("Problems to connect " + host + ex.toString());
}
}
}
public SslClient(String host, int port, String userName, String privateKey) {
this.host = host;
this.port = port;
this.userName = userName;
this.privateKey = privateKey;
}
protected String md5Sum(String str) {
String sum = new String();
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
sum = String.format("%032x", new BigInteger(1, md5.digest(str.getBytes())));
} catch (Exception ex) {
}
return sum;
}
public String getSignature(String xml) {
return md5Sum(md5Sum(xml + privateKey) + privateKey);
}
public String sendRequest(String xml) throws Exception {
HttpClient client = new HttpClient();
client.setConnectionTimeout(60000);
client.setTimeout(60000);
String response = new String();
String portStr = String.valueOf(port);
Protocol.registerProtocol("https", new Protocol("https", new MySSLSocketFactory(), port));
String signature = getSignature(xml);
String uri = "https://" + host + ":" + portStr + "/";
PostMethod postRequest = new PostMethod(uri);
postRequest.addRequestHeader("Content-Length", String.valueOf(xml.length()));
postRequest.addRequestHeader("Content-Type", "text/xml");
postRequest.addRequestHeader("X-Signature", signature);
postRequest.addRequestHeader("X-Username", userName);
postRequest.setRequestBody(xml);
System.out.println("Sending https request....." + postRequest.toString());
try {
client.executeMethod(postRequest);
} catch (Exception ex) {
throw new TaskExecuteException("Sending post got exception ", ex);
}
response = postRequest.getResponseBodyAsString();
headers = postRequest.getRequestHeaders();
return response;
}
public String getPrivateKey() {
return privateKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Header[] getHeaders() {
return headers;
}
public void setHeaders(Header[] headers) {
this.headers = headers;
}
public static void main(String[] args) {
String privateKey = "your_private_key";
String userName = "your_user_name";
String host = "demo.site.net";
int port = 55443;
String xml =
"<?xml version='1.0' encoding='UTF-8' standalone='no' ?>"
+ "<!DOCTYPE OPS_envelope SYSTEM 'ops.dtd'>"
+ "<OPS_envelope>"
+ "<header>"
+ "<version>0.9</version>"
+ "<msg_id>2.21765911726198</msg_id>"
+ "<msg_type>standard</msg_type>"
+ "</header>"
+ "<body>"
+ "<data_block>"
+ "<dt_assoc>"
+ "<item key='attributes'>"
+ "<dt_assoc>"
+ "<item key='domain'>test-1061911771844.com</item>"
+ "<item key='pre-reg'>0</item>"
+ "</dt_assoc>"
+ "</item>"
+ "<item key='object'>DOMAIN</item>"
+ "<item key='action'>LOOKUP</item>"
+ "<item key='protocol'>XCP</item>"
+ "</dt_assoc>"
+ "</data_block>"
+ "</body>"
+ "</OPS_envelope>";
SslClient sslclient = new SslClient(host, port, userName, privateKey);
try {
String response = sslclient.sendRequest(xml);
System.out.println("\nResponse is:\n" + response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
As in a day we are processing 10,000 + transactions, so number of socket at proxy are getting increased, so after 2-3 days, we need to do hard reboot of web server to free all the open sockets with proxy server.
Does HTTPClient, opens one socket for SSL Handshake and another for actual data post ? I don't think so. Then it should be at Web server and not at Proxy Server
For checking sockets and open ports at web server we are using netstat command.
For checking sockets and open ports at proxy server we are using proxy tool
when we check at web server it has created only one socket.
Because there is only one inbound connection to it.
SO why 2 socket at proxy server.
Because you are connecting to two different servers via the proxy server?
number of socket at proxy are getting increased, so after 2-3 days, we need to do hard reboot of web server to free all the open sockets with proxy server.
That doesn't make sense. It's the proxy server that has the dual connections, not the web server. You said that above. If the web server is running out of sockets, somebody isn't closing their connections correctly: the client, the proxy server, or the web server. Possibly your socket factory needs to override equals() and maybe hashCode() too, to enable whatever connection pooling HttpClient may do, I'm not an expert on that.
BUT your TrustManager is radically insecure. If you have this deployed in production, you have already committed a major security breach. This is currently a much bigger problem that running out of sockets every few days.
When socket ports run out, transaction timeouts occur. The solution to this problem is to tune the TIMEWAIT-related Windows registry parameters:
TcpTimedWaitDelay
MaxUserPort
StrictTimeWaitSeqCheck
The TIMEWAIT-related Windows registry parameters control how long a socket port remains unavailable after it is closed and how many ports are available for use.
By setting these windows registry parameters, I have solved this problem, but don't know, weather it is a correct solution to implement or not.

Categories

Resources