I am trying to call a web-service(Which has self signed SSL certificate) in Play Framework Using the following function:
public static play.libs.F.Promise<Result> webcall() {
String feedUrl = "https://10.0.1.1/client/api";
final play.libs.F.Promise<Result> resultPromise = WS.url(feedUrl).get().map(
new Function<WS.Response, Result>() {
public Result apply(WS.Response response) {
return ok("Feed title:" + response.asJson().findPath("title").toString());
}
}
);
return resultPromise;
}
It is throwing the following Error in Logs,
[error] play - Cannot invoke the action, eventually got an error: java.net.ConnectException: General SSLEngine problem to https://10.0.1.1/client/api
[error] application -
! @6fpimpnp6 - Internal server error, for (GET) [/webcall] ->
play.api.Application$$anon$1: Execution exception[[ConnectException: General SSLEngine problem to https://10.0.1.1/client/api]]
at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10.jar:2.2.0]
at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10.jar:2.2.0]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$2$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:261) [play_2.10.jar:2.2.0]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$2$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:261) [play_2.10.jar:2.2.0]
at scala.Option.map(Option.scala:145) [scala-library.jar:na]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$2.applyOrElse(PlayDefaultUpstreamHandler.scala:261) [play_2.10.jar:2.2.0]
java.net.ConnectException: General SSLEngine problem to https://10.0.1.1/client/api
at com.ning.http.client.providers.netty.NettyConnectListener.operationComplete(NettyConnectListener.java:103) ~[async-http-client.jar:na]
at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultChannelFuture.java:427) ~[netty.jar:na]
at org.jboss.netty.channel.DefaultChannelFuture.notifyListeners(DefaultChannelFuture.java:413) ~[netty.jar:na]
at org.jboss.netty.channel.DefaultChannelFuture.setFailure(DefaultChannelFuture.java:380) ~[netty.jar:na]
at org.jboss.netty.handler.ssl.SslHandler.setHandshakeFailure(SslHandler.java:1417) ~[netty.jar:na]
at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1293) ~[netty.jar:na]
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1362) ~[na:1.7.0_40]
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:513) ~[na:1.7.0_40]
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:790) ~[na:1.7.0_40]
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:758) ~[na:1.7.0_40]
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[na:1.7.0_40]
at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1225) ~[netty.jar:na]
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[na:1.7.0_40]
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1683) ~[na:1.7.0_40]
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:278) ~[na:1.7.0_40]
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) ~[na:1.7.0_40]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) ~[na:1.7.0_40]
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) ~[na:1.7.0_40]
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) ~[na:1.7.0_40]
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[na:1.7.0_40]
at sun.security.validator.Validator.validate(Validator.java:260) ~[na:1.7.0_40]
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) ~[na:1.7.0_40]
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:283) ~[na:1.7.0_40]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:138) ~[na:1.7.0_40]
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) ~[na:1.7.0_40]
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) ~[na:1.7.0_40]
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ~[na:1.7.0_40]
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[na:1.7.0_40]
at sun.security.validator.Validator.validate(Validator.java:260) ~[na:1.7.0_40]
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) ~[na:1.7.0_40]
If I call the service using HttpsURLConnection its working fine by adding
TrustManager[] trustAllcerts = new TrustManager[]{
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
}};
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
sc.init(null, trustAllcerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return false;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
How to Trust all Selfsigned / Untrusted ssl certificates in Play Framework?
Please don't accept all certificates -- you can use the trust manager with your custom certificates, and then fall back to the default trust store.
See http://www.playframework.com/documentation/2.3.x/ExampleSSLConfig for more details.
Try adding the following code to
conf/application.conf
fileThis will work if you are using the
Promise
class. But won't work if you are calling the service through other HttpClients.UPDATE: As of Play Framework 2.5, you should use the following -
You can do this in development environment, but you should never do this in Production environment, as it can prove as a security threat. In production, instead install the certificates of the client in your keystore.
You can try to set these parameters
when starting your app. Here is the list of all parameters: https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html
Just install the certificate you're trying to trust in your trust store.
Don't accept all certificates blindly. This makes your application vulnerable to MITM attacks.
Even if it's just for development, that's the kind of code and settings that people forget to remove when it's deadline day.
The next problem you might have is host name matching. You're using an IP address in
https://10.0.1.1/
, so your certificate should have a SAN entry for this IP address, not just that IP address in its CN. More details here. Don't use theHostnameVerifier
you've set up in your code (for the same reasons).