Okhttp android Websocket and Jetty Server connection with SSL - java

I have my okhttpclient android websocket and jetty stand-alone server given below. I have to enable strong security for the communication between the android client and jetty server. I am facing issue on client side which is given below.
Server Side
package com.wss.okhttp;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.servlet.ServletException;
import javax.websocket.DeploymentException;
import javax.websocket.server.ServerContainer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
public class JettySSLServer {
public static void main(String[] args) throws IOException {
JettyEndpoint endpoint = new JettyEndpoint();
Server webServer = new Server();
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
webServer.setHandler(context);
// --------------------SSL-Connection Start---------------------------//
KeyStore keyStore = null;
Certificate mPinnedCertificate = null;
try {
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, new char[] {});
mPinnedCertificate = readPinnedCertificate();
keyStore.setCertificateEntry("ca", mPinnedCertificate);
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SslContextFactory contextFactory = new SslContextFactory();
contextFactory.setIncludeProtocols("TLSv1.2");
contextFactory.setKeyStore(keyStore);
contextFactory.setKeyStorePassword("MIIEpAIBAAKCAQEAtzc9IK4U2YkfgASQ51v3IdjZUKABXw1RzUd+SxS8phI6O7Rb\r\n"
+ "RL+/KDQGPAtdrML2qDzaANIYa8rZ9jAyTnFAHpuykD8ByHf7RhogjPhJEvQDZkiX\r\n"
+ "r0hFS9A0ypqWn3fRWVXTREZTNGKgs0TQMNCY4Lm2H/lrgxNubaROn0KffLt+c5rK\r\n"
+ "7e3NXOcUUTP/tlkeC2JyHVIT8Cv2acaYJDD3PfHY5MSbvIORelVTp67eJkCSM+xF\r\n"
+ "spEi1SRuvRoBT+LMALNiIpi8nYBtNKlyDwmK2w38n11216g5DP3ipfZRHypk6048\r\n"
+ "vCO0qbgfwGfaep54twh94QJ4rjNi9X7f0F0qzCex7vmpJMpJ4gRl02mzni1DanOy\r\n"
+ "ExJB8ImpS3Il2jh2kVSbfLSg66UW33yAMKyCRCXypTSLgMGHetVDS+gHwcyFcE/M\r\n"
+ "nAY/k60CgYEA3ccY7AYSz10czJC0Y2ZPnw6NzESBNlWBgFIODQyKE5J2FKezJsR8\r\n"
+ "+LPRtEn+JeYI5+Q/jZZBR5qMXGaI+tprOlZKTSVcH4PQKOr7Ogd7v9leyH6zrfAe\r\n"
+ "k37acLaLtQE54tIyQVRLZW0dxzCiJ/tobJy+1f4TfWnpuRd4Y9xCnvMCgYEA03zT\r\n"
+ "aQLxW0ZBNbcz9ivDdbjy5kK2m1vA7Rq9LzawR0K9W05WOKUH7T1Ybp/idNTZfjKo\r\n"
+ "k+G2DV9ts/vQEL//3PthWo/FWZ8hsA5P1J+cT0RrwKKgWjCPNArp2l/T4vEdkGdM\r\n"
+ "GBbB6KZe5Wsn+HKPBszU35A8K2pD5PpebV0RGNcCgYBSEMmFFR5Cw2bTv7wwh/xw\r\n"
+ "lBcefj7+FxfrnvF6HKi/Y1P0grXFY7IG6atwtmyoI34qKQjnYLFZSLQlwP9xK/+/\r\n"
+ "v4yRDYEQXFtbuNAsAfbl4A61zES62X7G/4rfaH08Bm8gIr3b9NBNgNojCjkG6H4U\r\n"
+ "qs/nKbSWlOmaxzeSZD/2xwKBgQCJOlz/rc4ouLyFe1v3J0yMLbdHHBDbXD0iXRBW\r\n"
+ "+3iEtNSj03/0/3jWQtEH7y0FPDvoPDzQwEvd/4bym7nVtI/0txTjq5iV38D/OTop\r\n"
+ "sGu/r5jvhVbhTtMNJOu7LCUUA/p4Ad8JXnLyYEoBOXfVKZiPBAg5DKFOVoS5po/x\r\n"
+ "DMuUPwKBgQCa4cym/jJnK6r7h2xzE5bHLcniuud0F1DgCMkW/x026z4owpGtSCyK\r\n"
+ "BEQn/PY0rnSioRkcNjm5leGb1oOaFcT/QBgGhVpm09TyA/v8tj96pP631fYayzZh\r\n"
+ "lBEvszx6LOLEBbIioiXFtp1JhmWzkxvbuB114S3ChK+IKVrgZYTjvQ==");
contextFactory.setIncludeCipherSuites("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
contextFactory.setTrustAll(true);
SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(contextFactory,
org.eclipse.jetty.http.HttpVersion.HTTP_1_1.toString());
ServerConnector sslConnector = new ServerConnector(webServer, sslConnectionFactory);
sslConnector.setPort(8443);
webServer.addConnector(sslConnector);
ServerConnector wsConnector = new ServerConnector(webServer);
wsConnector.setPort(50055);
webServer.addConnector(wsConnector);
// --------------------SSL-Connection End---------------------------//
ServerContainer container;
try {
container = WebSocketServerContainerInitializer.configureContext(context);
container.addEndpoint(endpoint.getClass());
WebSocketServerContainerInitializer.configureContext(context);
webServer.start();
} catch (ServletException servEx) {
System.out.println(servEx.getMessage());
} catch (DeploymentException depEx) {
System.out.println(depEx.getMessage());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
private static Certificate readPinnedCertificate() throws CertificateException, IOException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new FileInputStream(System.getProperty("user.dir") + "/assets/va_cert.pem");
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
return ca;
}
}
Server Side Log
2018-04-26 18:33:51.049:INFO::main: Logging initialized #190ms
2018-04-26 18:33:51.229:INFO:oejs.Server:main: jetty-9.3.z-SNAPSHOT
2018-04-26 18:33:51.596:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler#4e7dc304{/,null,AVAILABLE}
2018-04-26 18:33:51.606:INFO:oejus.SslContextFactory:main: x509=X509#396f6598(ca,h=[],w=[]) for SslContextFactory#394e1a0f(null,null)
2018-04-26 18:33:51.630:INFO:oejs.ServerConnector:main: Started ServerConnector#458c1321{SSL,[ssl]}{0.0.0.0:8443}
2018-04-26 18:33:51.635:INFO:oejs.ServerConnector:main: Started ServerConnector#11438d26{HTTP/1.1,[http/1.1]}{0.0.0.0:50055}
2018-04-26 18:33:51.636:INFO:oejs.Server:main: Started #777ms
Client Side
package com.example.myapplication;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.TlsVersion;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
public class MainActivity extends AppCompatActivity {
private Button start;
private TextView output;
private OkHttpClient client;
private Certificate mPinnedCertificate;
private final class EchoWebSocketListener extends WebSocketListener {
private static final int NORMAL_CLOSURE_STATUS = 1000;
#Override
public void onOpen(WebSocket webSocket, Response response) {
output("Sending----------");
webSocket.send("Hello, Friend");
webSocket.send("USA");
webSocket.send(ByteString.decodeHex("Hi"));
webSocket.close(NORMAL_CLOSURE_STATUS, "Goodbye !");
}
#Override
public void onMessage(WebSocket webSocket, String text) {
output("Receiving : " + text);
}
#Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
output("Receiving bytes : " + bytes.hex());
}
#Override
public void onClosing(WebSocket webSocket, int code, String reason) {
webSocket.close(NORMAL_CLOSURE_STATUS, null);
output("Closing : " + code + " / " + reason);
}
#Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
output("Error : " + t.getMessage());
Log.i("Connection Error ",t.getMessage());
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.start);
output = (TextView) findViewById(R.id.output);
prepareOkHttpClient();
// client = new OkHttpClient();
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
start();
}
});
}
private void start() {
Request request = new Request.Builder().url("wss://localhost:50055/sample").build();
EchoWebSocketListener listener = new EchoWebSocketListener();
WebSocket ws = client.newWebSocket(request, listener);
client.dispatcher().executorService().shutdown();
}
private void output(final String txt) {
runOnUiThread(new Runnable() {
#Override
public void run() {
output.setText(output.getText().toString() + "\n\n" + txt);
}
});
}
private void prepareOkHttpClient() {
try {
ConnectionSpec wssSpecs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
.build();
mPinnedCertificate = readPinnedCertificate("va_cert.der");
// Create a KeyStore containing our trusted CAs
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, new char[]{});
keyStore.setCertificateEntry("ca", mPinnedCertificate);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = null;
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, tmf.getTrustManagers(), null);
Log.i("Protocol : ",sslContext.getProvider()+" **** " + sslContext.getProtocol());
TrustManager[] trustManagers = tmf.getTrustManagers();
client = new OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(wssSpecs))
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0])
.connectTimeout(15000, TimeUnit.MILLISECONDS)
.build();
} catch (NoSuchAlgorithmException | CertificateException
| KeyStoreException | KeyManagementException | IOException e) {
Log.i("SSL Exception ",e.getMessage());
}
}
/**
* Reads SSL certificate from App Assets folder.
*
* #param certAssetName File name of the SSL certificate.
* #return Certificate object.
* #throws CertificateException Certificate is invalid exception.
* #throws IOException File does not exist.
*/
private Certificate readPinnedCertificate(final String certAssetName)
throws CertificateException, IOException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
AssetManager assManager = this.getApplicationContext().getAssets();
InputStream caInput = assManager.open(certAssetName);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
return ca;
}
}
Client Side Error
Connection Error: Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256], tlsVersions=[TLS_1_2], supportsTlsExtensions=true)], supported protocols=[TLSv1, TLSv1.1, TLSv1.2]
Dont know how to fix this issue. Breaking my head for the past one week. Any help

new SslConnectionFactory(contextFactory,
org.eclipse.jetty.http.HttpVersion.HTTP_2.toString());
WebSocket over HTTP/2 doesn't exist (yet).
https://daniel.haxx.se/blog/2016/06/15/no-websockets-over-http2/
The concept of WebSocket over HTTP/2 is brand new, the draft specs have only been talked about in the past few months.
https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-h2-websockets-01

Related

JAVA - SSL Client - Key managers not used

I implemented a custom key manager, in order to choose which alias use when i need a ssl handshake.
The problem is that none of the methods of my custom key manager gets called, although it's correctly instantiated.
With a keystore containing just ONE alias, communication is fine and the code works, but the aim here is to have the possibility to change aliases during runtime.
Here is the full code of my implementation. Any Help is appreciated.
package ssl;
import java.net.Socket;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509KeyManager;
public class AliasSelectorKeyManager extends X509ExtendedKeyManager {
private X509KeyManager sourceKeyManager = null;
private String alias;
public AliasSelectorKeyManager(X509KeyManager keyManager, String alias) {
this.sourceKeyManager = keyManager;
this.alias = alias;
}
#Override
public String chooseEngineClientAlias(String[] paramArrayOfString, Principal[] paramArrayOfPrincipal, SSLEngine paramSSLEngine) {
return chooseClientAlias(paramArrayOfString, paramArrayOfPrincipal, null);
}
#Override
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
boolean aliasFound = false;
//Get all aliases from the key manager. If any matches with the managed alias,
//then return it.
//If the alias has not been found, return null (and let the API to handle it,
//causing the handshake to fail).
for (int i = 0; i < keyType.length && !aliasFound; i++) {
String[] validAliases = sourceKeyManager.getClientAliases(keyType[i], issuers);
if (validAliases != null) {
for (int j = 0; j < validAliases.length && !aliasFound; j++) {
if (validAliases[j].equals(alias)) {
aliasFound = true;
}
}
}
}
if (aliasFound) {
return alias;
} else {
return null;
}
}
}
All this does is simply override each method calling the specific sourceKeyManager implementation. The customization comes into the two methods:
chooseEngineClientAlias;
chooseClientAlias
This is my SSL client main:
package ssl;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
public class SSLClientV2 {
public static void main(String[] args) {
String keyStoreType = "PKCS12";
String keyManagementAlgorithm = "SunX509";
String keyStorePassword = "password";
String keyStoreFileName = "C:/keystore.p12";
String protocolVersion = "TLSv1.2";
System.out.println("Key store File name.......: " + keyStoreFileName);
System.out.println("Key store type............: " + keyStoreType);
System.out.println("Key store Password........: " + keyStorePassword);
System.out.println("SSL Protocol..............: " + protocolVersion);
System.out.println("Key Management Algorithm..: " + keyManagementAlgorithm);
System.out.println(System.lineSeparator());
KeyStore keyStore = null;
KeyManagerFactory keyManagerFactory = null;
SSLContext sslContext = null;
try (FileInputStream keyStoreFile = new FileInputStream(keyStoreFileName)) {
System.out.println("Loading keystore...");
keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(keyStoreFile, keyStorePassword.toCharArray());
System.out.println("Keystore loaded successfully.");
} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
System.out.println("ERROR: Could not load keystore.");
e.printStackTrace();
}
System.out.print(System.lineSeparator());
if (keyStore != null) {
try {
System.out.println("Initializing Key Manager Factory...");
keyManagerFactory = KeyManagerFactory.getInstance(keyManagementAlgorithm);
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
System.out.println("Key Manager Factory initialized successfully.");
} catch (NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException e) {
System.out.println("ERROR: Could not initialize Key Manager Factory.");
e.printStackTrace();
}
}
System.out.print(System.lineSeparator());
if (keyManagerFactory != null) {
try {
System.out.println("Initializing SSL Context...");
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
TrustManager[] trustManagers = new TrustManager[] {
new X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException {
}
#Override
public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException {
}
}
};
for (int i = 0; i < keyManagers.length; i++) {
if (keyManagers[i] instanceof X509KeyManager) {
keyManagers[i] = new AliasSelectorKeyManager((X509KeyManager) keyManagers[i], "my.custom.alias");
System.out.println("Custom Key Manager loaded (#" + (i + 1) + ", class: " + keyManagers[i].getClass().getName() + ")");
}
}
sslContext = SSLContext.getInstance(protocolVersion);
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextInt();
sslContext.init(keyManagers, trustManagers, secureRandom);
System.out.println("SSL Context initialized successfully.");
} catch (KeyManagementException | NoSuchAlgorithmException e) {
System.out.println("ERROR: Could not initialize SSL Context.");
e.printStackTrace();
}
}
System.out.print(System.lineSeparator());
if (sslContext != null) {
try (SSLSocket socket = (SSLSocket) sslContext.getSocketFactory().createSocket("192.168.10.10", 1443)) {
System.out.println("Communication initialized, starting handshake...");
socket.startHandshake();
System.out.println("Handshake completed successfully.");
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String m = null;
System.out.print(System.lineSeparator());
String content = "Hello World";
System.out.println("Sending: " + content);
w.write(content);
w.flush();
System.out.println("Message received: ");
while ((m = r.readLine()) != null) {
System.out.println(m);
}
w.close();
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
please override also this method:
X509KeyManager::getClientAliases(String keyType, Principal[] issuers)
Has the needClientAuth flag been turned on the server side?
https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLEngine.html#setNeedClientAuth(boolean)
The server asks the client’s authentication during the handshake only if the flag is turned on.

Client certificate authentication with com.sun.net.httpsserver

I have combined client-certificate-with-com-sun-net-httpserver-httpsserver
with simple-java-https-server but I always get the error message
SSL-Peer could not be verified.
I call setWantClientAuth(true) and verify Authentification by calling
Certificate[] peerCerts = pHttpsExchange.getSSLSession().getPeerCertificates();
The server is running with JDK 1.8 and the client is running on Android. The server Code is:
package de.org.vnetz;
import java.io.*;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import com.sun.net.httpserver.*;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import javax.net.ssl.SSLContext;
import javax.security.auth.x500.X500Principal;
import java.security.cert.Certificate;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class clsHTTPSServer {
final static String SERVER_PWD = "xxxxxx";
final static String KST_SERVER = "server.jks";
final static String TST_SERVER = "servertrust.jks";
private static final int PORT = 9999;
public static class MyHandler implements HttpHandler {
// whether to use client cert authentication
private final boolean useClientCertAuth = true;
private List<LdapName> allowedPrincipals = new ArrayList<LdapName>();
private final boolean extendedClientCheck = true;
private static final String CLIENTAUTH_OID = "1.3.6.1.5.5.7.3.2";
#Override
public void handle(HttpExchange t) throws IOException {
String response = "Hallo Natalie!";
HttpsExchange httpsExchange = (HttpsExchange) t;
boolean auth;
try
{
checkAuthentication(httpsExchange);
auth = true;
}
catch (Exception ex)
{
response = ex.getMessage();
auth = false;
}
boolean res = httpsExchange.getSSLSession().isValid();
if (res) {
String qry = httpsExchange.getRequestURI().getQuery();
if (qry!=null && qry.startsWith("qry=")) {
httpsExchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
httpsExchange.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
else
{
httpsExchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*");
httpsExchange.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write((response + " no query!").getBytes());
os.close();
}
}
}
// Verify https certs if its Https request and we have SSL auth enabled. Will be called before
// handling the request
protected void checkAuthentication(HttpExchange pHttpExchange) throws SecurityException {
// Cast will always work since this handler is only used for Http
HttpsExchange httpsExchange = (HttpsExchange) pHttpExchange;
if (useClientCertAuth) {
checkCertForClientUsage(httpsExchange);
checkCertForAllowedPrincipals(httpsExchange);
}
}
// Check the cert's principal against the list of given allowedPrincipals.
// If no allowedPrincipals are given than every principal is allowed.
// If an empty list as allowedPrincipals is given, no one is allowed to access
private void checkCertForClientUsage(HttpsExchange pHttpsExchange) {
try {
String host = pHttpsExchange.getSSLSession().getPeerHost();
//Principal p = pHttpsExchange.getSSLSession().getPeerPrincipal();
String pr = pHttpsExchange.getSSLSession().getProtocol();
Certificate[] peerCerts = pHttpsExchange.getSSLSession().getPeerCertificates();
if (peerCerts != null && peerCerts.length > 0) {
X509Certificate clientCert = (X509Certificate) peerCerts[0];
// We required that the extended key usage must be present if we are using
// client cert authentication
if (extendedClientCheck &&
(clientCert.getExtendedKeyUsage() == null || !clientCert.getExtendedKeyUsage().contains(CLIENTAUTH_OID))) {
throw new SecurityException("No extended key usage available");
}
}
} catch (ClassCastException e) {
throw new SecurityException("No X509 client certificate");
} catch (CertificateParsingException e) {
throw new SecurityException("Can't parse client cert");
} catch (SSLPeerUnverifiedException e) {
throw new SecurityException("SSL Peer couldn't be verified");
}
}
private void checkCertForAllowedPrincipals(HttpsExchange pHttpsExchange) {
if (allowedPrincipals != null) {
X500Principal certPrincipal;
try {
certPrincipal = (X500Principal) pHttpsExchange.getSSLSession().getPeerPrincipal();
Set<Rdn> certPrincipalRdns = getPrincipalRdns(certPrincipal);
for (LdapName principal : allowedPrincipals) {
for (Rdn rdn : principal.getRdns()) {
if (!certPrincipalRdns.contains(rdn)) {
throw new SecurityException("Principal " + certPrincipal + " not allowed");
}
}
}
} catch (SSLPeerUnverifiedException e) {
throw new SecurityException("SSLPeer unverified");
} catch (ClassCastException e) {
throw new SecurityException("Internal: Invalid Principal class provided " + e);
}
}
}
private Set<Rdn> getPrincipalRdns(X500Principal principal) {
try {
LdapName certAsLdapName =new LdapName(principal.getName());
return new HashSet<Rdn>(certAsLdapName.getRdns());
} catch (InvalidNameException e) {
throw new SecurityException("Cannot parse '" + principal + "' as LDAP name");
}
}
}
/**
* #param args
*/
public static void main(String[] args) throws Exception {
try {
// setup the socket address
InetSocketAddress address = new InetSocketAddress(PORT);
// initialise the HTTPS server
HttpsServer httpsServer = HttpsServer.create(address, 0);
SSLContext sslContext = SSLContext.getInstance("TLS");
// initialise the keystore
// char[] password = "password".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream(KST_SERVER);// ("testkey.jks");
ks.load(fis, SERVER_PWD.toCharArray());// password);
// setup the key manager factory
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, SERVER_PWD.toCharArray());
// setup the trust manager factory
// TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
// tmf.init(ks);
KeyStore ts = KeyStore.getInstance("JKS");
ts.load(new FileInputStream(TST_SERVER), SERVER_PWD.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
// setup the HTTPS context and parameters
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLParameters sslp = sslContext.getSupportedSSLParameters();
//sslp.setNeedClientAuth(true);
sslp.setWantClientAuth(true);
httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext) {
public void configure(HttpsParameters params) {
try {
// initialise the SSL context
SSLContext c = SSLContext.getDefault();
SSLEngine engine = c.createSSLEngine();
//params.setNeedClientAuth(true);
params.setWantClientAuth(true);
params.setCipherSuites(engine.getEnabledCipherSuites());
params.setProtocols(engine.getEnabledProtocols());
// get the default parameters
SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();
SSLParameters sslParams = sslContext.getDefaultSSLParameters();
//sslParams.setNeedClientAuth(true);
sslParams.setWantClientAuth(true);
params.setSSLParameters(defaultSSLParameters);
} catch (Exception ex) {
System.out.println("Failed to create HTTPS port");
}
}
});
httpsServer.createContext("/test", new MyHandler());
httpsServer.setExecutor(
new ThreadPoolExecutor(4, 80, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000))); // creates
// a
// default
// executor
httpsServer.start();
} catch (Exception exception) {
System.out.println("Failed to create HTTPS server on port " + 62112 + " of localhost");
exception.printStackTrace();
}
}
}
The client code is:
package vnetz.de.org.vnetz;
import android.content.Context;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class clsHTTPS {
private static final String MYURL = "https://localhost:9999/test?qry=test";
static String NO_KEYSTORE = "";
static String UNAUTH_KEYSTORE = "unauthclient.bks"; // Doesn't exist in server trust store, should fail authentication.
static String AUTH_KEYSTORE = "authclient.bks"; // Exists in server trust store, should pass authentication.
static String TRUSTSTORE = "clienttrust.bks";
static String CLIENT_PWD = "xxxxxx";
private static Context context = null;
public clsHTTPS(Context context) {
this.context = context;
}
public static void main(String[] args) throws Exception {
}
public String connect(String jksFile) {
try {
String https_url = MYURL;
URL url;
url = new URL(https_url);
HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(getSSLFactory(jksFile));
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setUseCaches(false);
// Print response
//SSLContext context = SSLContext.getInstance("TLS");
//context.init(null, new X509TrustManager[]{new NullX509TrustManager()}, new SecureRandom());
//HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
BufferedReader bir = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sbline = new StringBuilder();
String line;
while ((line = bir.readLine()) != null) {
System.out.println(line);
sbline.append(line);
}
bir.close();
conn.disconnect();
return sbline.toString();
} catch (SSLHandshakeException | SocketException e) {
System.out.println(e.getMessage());
System.out.println("");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static SSLSocketFactory getSSLFactory(String jksFile) throws Exception {
// Create key store
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
KeyManager[] kmfs = null;
if (jksFile.length() > 0) {
keyStore.load(context.getAssets().open(jksFile), CLIENT_PWD.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, CLIENT_PWD.toCharArray());
kmfs = kmf.getKeyManagers();
}
// create trust store (validates the self-signed server!)
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(context.getAssets().open(TRUSTSTORE), CLIENT_PWD.toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmfs, trustFactory.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
private class NullHostNameVerifier implements HostnameVerifier
{
#Override
public boolean verify(String s, SSLSession sslSession)
{
return s.equalsIgnoreCase("localhost");
}
}
private class NullX509TrustManager implements X509TrustManager
{
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
{
}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
{
}
#Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}
}
'Peer not verified' in a server means that the client didn't send a certificate, which probably means that its signer isn't in your server's truststore. When the server requests the client certificate, it supplies a list of acceptable signers, and the client must not send a certificate that isn't signed by one of those.
Or else the server didn't ask for a client certificate at all. Doesn't apply in this case.
In your case it would be a lot simpler to use needClientAuth, as that will just fail the handshake without you having to get as a far as getPeerCertificates().
NB:
The SSLSession is valid, otherwise you wouldn't have an SSL connection. The only way it becomes invalid is if you call invalidate(), which causes a full re-handshake on the next I/O. You're testing the wrong thing.
Checking for allowed principals is authorization, not authentication.

Curl to java Rest client Jersy

I am using a rest service which requires authentication, Below curl command is used to achieve this
curl -v --insecure --request POST "https://ip:port/login" -d IDToken1="username" -d "password" --cookie-jar cookie.txt
After authentication it creates a cookie file.
Can someone helps in creating the corresponding rest client using java.
I have used
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target = client
.target("http://hilweb05:8080/login");
Form form = new Form().param("IDToken1", "username").param("IDToken2", "password");
Response jsonAnswer = target.request()
.accept(MediaType.APPLICATION_JSON).post(Entity.form(form));
if (jsonAnswer.getStatus() != 200) {
throw new RuntimeException("Not reachable "
+ jsonAnswer.getStatus());
}
List<SomeDataClass> matList = jsonAnswer.readEntity(new GenericType<List<SomeDataClass>>() {});
for (SomeDataClass m : matList) {
System.out.println(m.getF1() + " " + m.getF2() + " "
+ m.getF3());
}
But its not working
I switched to Apache http client, with the below piece of code I am able to get the cookie.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.SSLContext;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
public class ApacheHttpClient {
public static void main(String[] args) throws ClientProtocolException, IOException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial((chain, authType) -> true).build();
SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext, new String[]
{"SSLv2Hello", "SSLv3", "TLSv1","TLSv1.1", "TLSv1.2" }, null,
NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
try {
HttpPost httpPost = new HttpPost("url/login");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("IDToken1", name));
nvps.add(new BasicNameValuePair("IDToken2", password));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse response2 = httpclient.execute(httpPost);
try {
System.out.println("Status -->>> "+ response2.getStatusLine().getStatusCode());
Header[] cookieInf = response2.getHeaders("Set-Cookie");
StringBuilder strBf = new StringBuilder();
for(Header header : cookieInf)
{
strBf.append(header.getValue());
}
System.out.println("Data is "+ strBf);
HttpEntity entity2 = response2.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity2);
} finally {
response2.close();
}
} finally {
httpclient.close();
}
}
}
Now I need to write the cookie in a text file, so I need help in parsing the cookie information so that it matches the cookie file generated by curl command.
With the below piece of code it works
public class JerseyClientPost {
public static void main(String[] args) {
try {
Client client = Client.create(configureClient());
final com.sun.jersey.api.client.WebResource webResource = client
.resource("https://wtc2e3enm.eng.mobilephone.net:443/login");
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("IDToken1", name);
formData.add("IDToken2", password);
try {
ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED)
.accept(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, formData);
String x = response.getEntity(String.class);
System.out.println("Response String is "+ x);
} catch (com.sun.jersey.api.client.ClientHandlerException che) {
che.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static ClientConfig configureClient() {
TrustManager[] certs = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
} };
SSLContext ctx = null;
try {
ctx = SSLContext.getInstance("SSL");
ctx.init(null, certs, new SecureRandom());
} catch (java.security.GeneralSecurityException ex) {
}
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
ClientConfig config = new DefaultClientConfig();
try {
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
new HTTPSProperties(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}, ctx));
} catch (Exception e) {
}
return config;
}
}
but I am not able to get the cookies from response, if I use curl I am able to get the cookie by using --cookie-jar argument. Can somebody help in getting the cookie

Setup FTPS Server/Client on Android

I have been trying to setup a FTP Server that supports SSL/TLS, and a FTPS Client that successfully connects to this server. I generated the certificates/keys firstly using this tutorial link: http://callistaenterprise.se/blogg/teknik/2011/11/24/creating-self-signed-certificates-for-use-on-android/
This generated a client.bks, clienttruststore.bks, server.bks, servertruststore.bks (used BouncyCastle). I also created a client.jks, and a clienttruststore.jks to be used on a non-android device just for initial testing without using BouncyCastle.
Everything worked out fine with no errors. For now, I was experimenting with just the server on Android and running the client locally using Java on Netbeans. I put in the respective files to the Client (JKS files) and Server (BKS files). That being said, I am still having issues connecting to the server as I get unable to find valid certification path to requested target errors. I followed multiple tutorials on how to fix this issue (including the InstallCert.java tutorial), but surprisingly to no avail.
Am I setting up my server (used Apache's FTP Server library) or client(using Apache Common's library) wrong?
I have attached my server code below:
package com.example.gurnaaz.ftpsserver;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.format.Formatter;
import android.widget.Toast;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.ssl.SslConfigurationFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.UsernamePasswordAuthentication;
import java.io.File;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 0x11;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE","android.permission.READ_EXTERNAL_STORAGE"};
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE); // without sdk version check
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// save file
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
// set the port of the listener
factory.setPort(3425);
SslConfigurationFactory ssl = new SslConfigurationFactory();
ssl.setKeystoreFile(new File("storage/emulated/0/Pictures/server.bks"));
ssl.setKeystorePassword("abc1234");
ssl.setTruststoreFile(new File("storage/emulated/0/Pictures/servertruststore.bks"));
ssl.setTruststorePassword("abc1234");
factory.setSslConfiguration(ssl.createSslConfiguration());
factory.setImplicitSsl(true);
// replace the default listener
serverFactory.addListener("default", factory.createListener());
// start the server
System.out.println("AFTER I LOADED IT");
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
userManagerFactory.setFile(new File("storage/emulated/0/Pictures/myusers.properties"));
serverFactory.setUserManager(userManagerFactory.createUserManager());
FtpServer server = serverFactory.createServer();
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
System.out.println("THE IP IS " + ip);
try {
server.start();
} catch (FtpException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(), "PERMISSION_DENIED", Toast.LENGTH_SHORT).show();
}
}
}
}
And I have attached my Client code below:
import java.io.*;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import org.apache.commons.net.io.Util;
import org.apache.commons.net.util.TrustManagerUtils;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public final class FTPSExample {
public static void main(String[] args) throws Exception {
System.setProperty("javax.net.debug", "ssl");
String server = "192.168.1.31";
// String username = "USER_TEST";
// String password = "ABCD1234";
String remoteFile = "/Data/Input/PH240819";
String localFile = "PH240819";
String protocol = "SSL"; // TLS / null (SSL)
int port = 3425;
int timeoutInMillis = 5000;
FTPSClient client = new FTPSClient(protocol, true);
client.setNeedClientAuth(true);
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ks2 = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("C:\\Users\\Gurnaaz\\Favorites\\clientnotandroid.jks");
FileInputStream fistrust = new FileInputStream("C:\\Users\\Gurnaaz\\Favorites\\clienttruststorenotandroid.jks");
ks.load(fis, "abc123".toCharArray());
ks2.load(fistrust,"abc123".toCharArray());
fis.close();
fistrust.close();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "abc123".toCharArray());
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(ks2);
client.setKeyManager(kmf.getKeyManagers()[0]);
client.setTrustManager(tmf.getTrustManagers()[0]);
client.setDataTimeout(timeoutInMillis);
client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
System.out.println("################ Connecting to Server ################################");
try {
int reply;
System.out.println("################ Connect Call ################################");
client.connect(server, port);
// client.login(username, password);
System.out.println("################ Login Success ################################");
//client.setFileType(FTP.BINARY_FILE_TYPE);
client.setFileType(FTP.NON_PRINT_TEXT_FORMAT);
client.execPBSZ(0); // Set protection buffer size
client.execPROT("P"); // Set data channel protection to private
client.enterLocalActiveMode();
System.out.println("Connected to " + server + ".");
reply = client.getReplyCode();
System.out.println("AFTER REPLY CODE WHICH IS " + reply);
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
System.err.println("FTP server refused connection.");
System.exit(1);
}
System.out.println("BEFORE retrieved FILEs");
// client.listFiles();
// System.out.println("above is the list of patch");
boolean retrieved = client.retrieveFile(remoteFile, new FileOutputStream(localFile));
System.out.println("Retrieved value: " + retrieved);
} catch (Exception e) {
if (client.isConnected()) {
try {
client.disconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
}
System.err.println("Could not connect to server.");
e.printStackTrace();
return;
} finally {
client.disconnect();
client.logout();
System.out.println("# client disconnected");
}
}
//Helper method from apache: http://commons.apache.org/proper/commons-net/apidocs/index.html?org/apache/commons/net/util/KeyManagerUtils.html
private static KeyStore loadStore(String storeType, File storePath, String storePass)
throws KeyStoreException, IOException, GeneralSecurityException {
KeyStore ks = KeyStore.getInstance(storeType);
FileInputStream stream = null;
try {
stream = new FileInputStream(storePath);
ks.load(stream, storePass.toCharArray());
} finally {
Util.closeQuietly(stream);
}
return ks;
}
}
Any advice on where I may have gone wrong, or any helpful links would be much appreciated!

Configure proxy to Jersey client

I would like to configure a proxy server to my Jersey client.
I don't want to configure the proxy to the whole application (using JVM arguments such as http.proxyHost), and Id'e rather not use Apache client.
I read here that there is an option to do it by providing HttpUrlConnection
via HttpUrlConnectionFactory, but I couldn't find any code example.
Does anyone know how can I do it?
Thanks!
With the help of Luca, I got it done:
Implement HttpURLConnectionFactory, and override the method getHttpURLConnection, my implementation is (thanks to Luca):
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3128));
return new HttpURLConnection(url, proxy);
Before instantiating the Jersey Client, create a new URLConnectionClientHandler, and provide your HttpURLConnectionFactory in its constructor. Then create a new Client, and provide your ClientHandler in the Client constructor. My code:
URLConnectionClientHandler urlConnectionClientHandler = new URLConnectionClientHandler(new MyHttpURLConnectionFactory());
_client = new Client(urlConnectionClientHandler);
Hope that's help.
First of all I created this class
import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
/**
*
* #author Aimable
*/
public class ConnectionFactory implements HttpURLConnectionFactory {
Proxy proxy;
String proxyHost;
Integer proxyPort;
SSLContext sslContext;
public ConnectionFactory() {
}
public ConnectionFactory(String proxyHost, Integer proxyPort) {
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;
}
private void initializeProxy() {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
}
#Override
public HttpURLConnection getHttpURLConnection(URL url) throws IOException {
initializeProxy();
HttpURLConnection con = (HttpURLConnection) url.openConnection(proxy);
if (con instanceof HttpsURLConnection) {
System.out.println("The valus is....");
HttpsURLConnection httpsCon = (HttpsURLConnection) url.openConnection(proxy);
httpsCon.setHostnameVerifier(getHostnameVerifier());
httpsCon.setSSLSocketFactory(getSslContext().getSocketFactory());
return httpsCon;
} else {
return con;
}
}
public SSLContext getSslContext() {
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new SecureTrustManager()}, new SecureRandom());
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE, null, ex);
} catch (KeyManagementException ex) {
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE, null, ex);
}
return sslContext;
}
private HostnameVerifier getHostnameVerifier() {
return new HostnameVerifier() {
#Override
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
return true;
}
};
}
}
then I also create another class called SecureTrustManager
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
*
* #author Aimable
*/
public class SecureTrustManager implements X509TrustManager {
#Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public boolean isClientTrusted(X509Certificate[] arg0) {
return true;
}
public boolean isServerTrusted(X509Certificate[] arg0) {
return true;
}
}
then after creation this class i'm calling the client like this
URLConnectionClientHandler cc = new URLConnectionClientHandler(new ConnectionFactory(webProxy.getWebserviceProxyHost(), webProxy.getWebserviceProxyPort()));
client = new Client(cc);
client.setConnectTimeout(2000000);
replace webProxy.getWeserviceHost by your proxyHost and webProxy.getWebserviceProxyPort() by the proxy port.
This worked for me and it should work also for you. Note that i'm using Jersey 1.8 but it should also work for Jersey 2
Try
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
conn = new URL(url).openConnection(proxy);

Categories