Can't consume a SSL protected webservice with Java/Glassfish - java

I'm trying to consume a Webservice hosted under https security.
I'm using Java and glassfish and I'm getting the following error:
INFO: HTTP transport error: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching testdomain.com found
The thing is that this specific server is used for testing and it's using the production certificate (the one with CN=domain.com)
I already added the domain.com certificate to my glassfish domain's cacerts keystore using keytool -importcert and it didn't work.
I also tried creating a self signed certificate with the CN=testdomain.com and adding it to the cacerts keystore and it didn't work either...
So how do I configure Java/Glassfish to consume this Web Service?

The CN of the server certificate should match the domain in URL to which the client connects. If still doesn't work, I would check if the IP maps to this hostname too (reverse DNS). It is the client, who verifies it. If you want to bypass this hostname verification, see the example code in my article: http://jakubneubauer.wordpress.com/2011/09/06/java-webservice-over-ssl/
The priciple is that you provide your own HostnameVerifier to the service client proxy.

THe self-signed certificate needs to be installed in the keystore of the Web service, along with its private key, and imported into the truststore of Glassfish.

the self signed certificate needs to be installed in key store of your java client. and testdomain.com should be resolved using dns.

Related

Wildfly does not pass intermediate certificate to HTTPS client

So I have this certificate chain made of 3 certificates:
Root cert (installed in all clients)
Intermediate cert (installed in my browser, but not in other clients/Java apps accessing webservices)
Domain wildcard certificate
Wildfly is configured to use a keystore that holds intermediate and domain certificates in JKS format, along with the private key for the domain cert. When I send a HTTPS request from my browser, the certificate is validated just fine and everything seems OK. But when the Java client application I am working on tries to establish a connection, it cannot build a valid certificate chain:
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I checked the certificates delivered by Wildfly using openssl (openssl s_client -showcerts -connect <servername>) and confirmed that the intermediate certificate is NOT transmitted even though it is present in the keystore. Now I can work around this in my development environment by adding the intermediate cert to my local trust store, however that is not an acceptable long-term solution for production.
In my Wildfly's standalone.xml I have specified the keystore and the alias of the wildcard certificate.
<server-identities>
<ssl>
<keystore path="/path/to/keytsore.jks" keystore-password="supersecure" alias="*.redacted.com"/>
</ssl>
</server-identities>
Searching through the Wildfly admin docs I saw no mention of intermediate certificates. I tried to add an additional element to the config (same path and password, but alias of the intermediate certificate), but Wildfly would not start up with that.
Any idea how I can get Wildfly to present the intermediate certificate to connecting clients? Does it need to have a specific alias name? Or is there another way to tell Wildfly the alias of any intermediate cert?

Is it possible to disable ssl for https?

Application on java. OkHttp version 2.7.5 is used. A request is made to another service and an error occurs.
SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
I do not have a certificate. It seems there are solutions for the version of okHttp3. But the version can not be changed. How to solve a problem?
Is it possible to disable ssl for https?
Literally, no.
Use of SSL is fundamental to the HTTPS protocol. If you don't want to use SSL at all, configure your server with an HTTP endpoint and use that instead of HTTPS.
Furthermore use of SSL requires a certificate that is (at least) syntactically well-formed. That is also fundamental to the HTTPS protocol.
Now if the problem is that your server certificate has expired, then a possible solution is to use the approach described in:
Make a connection to a HTTPS server from Java and ignore the validity of the security certificate.
And if the problem is that you cannot get a proper certificate for the server (e.g. you can't afford it) then an alternative solution is:
generate a self-signed certificate; see How to generate a self-signed certificate using Java Keytool,
install it on the server side,
configure the client as above to ignore certificate validity.
But note that doing either of those things has security issues.
There is a third solution that is more secure.
generate a self-signed certificate (as above)
install it on the server side,
use Keytool to add the certificate to the client app's keystore as a trusted certificate.

How to debug SSLHandshakeException?

I have a Java desktop application with which I was able to successfully GET data from an API at an https URL. The client had their own PKI, and in my app, they entered their pki password and their path to their truststore and pki to run the app, and system properties (keystore, truststore, etc) were set in the code to accept these values. Everything worked fine.
Now, I'm trying to implement the same thing via ssl using glassfish in a Java web app, but I am getting a javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca (this is the specific exc currently; before debugging, it was "PKIX path building failed...unable to find valid certification path to requested target")
I researched how to debug, including...
1) Java HTTPS client certificate authentication
Solution: Client already has a pkcs12 keystore, but ticket solved by using openssl to re(?)generate pkcs12, then use keytool to generate truststore.
(my comment: My clients already have certs in p12/pfx format, plus a truststore jks file containing trusted entities to use directly, so this solution doesn't seem to fit)
2) Using browser's certificate in java program
Solution: Add server certs to truststore
(my comment: this guidance seems opposite of the one directly below. I assume that these 'server certs' are for the https api servers?. My client truststore contains entries for https api sites to be accessed. It makes sense to me to add them to glassfish truststore since glassfish is server side; however, this is what i'm doing (i.e., -Djavax.net.ssl.trustStore=clientPathTo/truststore.jks in glassfish JVM) and getting exception at bottom)
3) Unable to find valid certification path to requested target - error even after cert imported
Solution: Add client cert to -Djavax.net.ssl.trustStore=${com.sun.aas.instanceRoot}/config/cacerts.jks
(my comment: I have not tried this but does it make sense for a copy of the client cert to be located on the server?
One thing that is confusing is when people say 'server', I can't tell if they mean 'web server' or 'app server'.
Anyway, I ran Glassfish in debug mode and set javax.net.debug==ssl. In the logs, I can see the following:
client HELLO
server HELLO
server presents its certificate chain
server makes a certificate request
glassfish presents a certificate chain
glassfish attempts to generate a session key, data is
exchanged, then it finishes with a data verification fatal ALERT:
unknown ca, session invalidated
javax.net.ssl.SSLHandshakeException...
------UPDATE------
I am running glassfish 4.1.1.
Here is the full Exception
javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
atsun.security.ssl.Alerts.getSSLException(Alerts.java:192)
atsun.security.ssl.Alerts.getSSLException(Alerts.java:154)
atsun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
atsun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
atsun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
atsun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
atsun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
atsun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
atsun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
atsun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546)
atsun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1474)
atsun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
atbeans.ApiReader.sendGet(ApiReader.java:122)
atbeans.SelBeanController.showData(SelBeanController.java:43)
atsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
atjava.lang.reflect.Method.invoke(Method.java:498)
atjavax.el.ELUtil.invokeMethod(ELUtil.java:332)
atjavax.el.BeanELResolver.invoke(BeanELResolver.java:537)
atjavax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
atcom.sun.el.parser.AstValue.invoke(AstValue.java:283)
atsom.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
atcom.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
atjavax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
atcome.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
atjavax.faces.component.UICommand.broadcast(UICommant.java:315)
atjavax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
atjavax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
atcome.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
atcome.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
atcome.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
atjavax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
atorg.apache.cataline.core.StandardWrapper.service(StandardWrapper.java:1682)
atorg.apache.cataline.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
atorg.apache.cataline.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
atorg.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
atorg.apache.cataline.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
atorg.apache.cataline.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
atorg.apache.cataline.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
atorg.apache.cataline.core.StandardContextValve.invoke(StandardContextValve.java:160)
atorg.apache.cataline.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
atorg.apache.cataline.core.StandardPipeline.invoke(StandardPipeline.java:673)
atcom.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
atorg.apache.cataline.core.StandardHostValve.invoke(StandardHostValve.java:174)
atorg.apache.cataline.CoyoteAdapter.doService(CoyoteAdapter.java:416)
atorg.apache.cataline.CoyoteAdapter.service(CoyoteAdapter.java:283)
atcom.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
atcom.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
atorg.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
atorg.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
atorg.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
atorg.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
atorg.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
atorg.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
atorg.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
atorg.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
atorg.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
atorg.glassfish.grizzly.nio.trasport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
atorg.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
atorg.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
atorg.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
atorg.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
atorg.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
atorg.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
atjava.lang.Thread.run(Thread.java:745)

how to enable trust for chain certs in weblogic or java

I have an Oracle service Bus domain running on weblogic 10.3.6 with 2 managed servers in cluster.
We have a proxy service deployed on this domain which goes to an external Business service for validating address. This Business Service is listening on SSL port and SSL cert has EntrustCACert>IntermidateCert1>IntermidateCert2>ServerCert
Issue: Getting below error during connectivity testing -
General runtime error: [Security:090548]The certificate chain received from ws2.site1.com - 197.109.80.xxx contained a V3 CA certificate which was missing the basic constraints.
Solutions i have tried:
1) added JAVA_OPTIONS="${JAVA_OPTIONS} -Dweblogic.security.SSL.enforceConstraints=off " in the startup script and it resolve the issue. But i was told this is not the prefered way and use trust keystore to implement.
2)to implement trust, I copied all the 4 certs in following reverse order EntrustCACert>IntermidateCert1>IntermidateCert2>ServerCert in one file named DSperian.pem and imported in Jrockit cacerts file( /apps/Oracle/jrockit-jdk1.6.0_31-R28.2.3-4.1.0/jre/lib/security/cacerts ) using below command but getting the same above error.
keytool -import -alias DSperian -trustcacerts -file DSperian.pem -keystore cacerts
Question:
Please let me know if im doing the right way to import cert to create trust. so my OSB domain will blindly trust the Business service ( web-service) and ignore
the "basic constraints" error. Do i need to utilize weblogic specific trust keystore file but this OSB weblogic is running on non-ssl port ?
are there any other options available ? Asking Business-service to update their cert to include "basic constraints" is not an option.
There is actually a problem with your certificate.
Security certificates have a set of constraints that allow them to perform certain functions (or restrict them to certain functions).
Have a look at each of the certificates and ensure that they have constraints assigned to them that are suitable for the task.
To get more details on the error enable SSL debugging in your web logic server add the following to your server startup script
-Dssl.debug=true -Dweblogic.StdoutDebugEnabled=true
More information in Configure SSL in WebLogic server
Use the following command to validate your keystone
java utils.ValidateCertChain -jks my key mykeystore
Then, whoever provided the root certificate needs to fix up your issues.

How can a Java app accepts a server certificate seamlessly?

Most Web browsers that support SSL have a list of CAs whose certificates they will automatically accept. If a browser encounters a certificate whose authorizing CA is in the list, the browser will automatically accept the certificate, and establish a SSL connection to the site.
There is a Java 1.6 client, running on JBoss 7, which is required to make SSL connection to LDAP server. Since the client is on production, if the LDAP server updates its certificate without notifying me to update the certificate accordingly on JBoss, the client will fail. My question is: how can I securely connect(ssl) to LDAP in a similar way the browser “accepts” the certificate seamlessly?
I don’t know if this is feasible in Java. But, any thoughts and feedbacks are all welcome.
Java has a default truststore that contains all the trusted certificates. This is under %JRE_HOME%\lib\security\cacert and has all the trusted CA certificates (Verisign etc).
So if your client https application tries to connect to a server that deploys a certificate signed by these issuers you would have no issue (same as happens with your browser).
Now to your problem. You don't mention enough information about your LDAP server.
I can think of the following:
The LDAP server deploys a certificate signed by some CA (not one of
the known ones).
The LDAP server deploys a self-signed certificate
For case (1) all you need to do is add the certificate of the signer to your truststore (i.e. the certificate of the issure that signed the certificate of your LDAP server). If the LDAP server changes certificate, you would be unaffected provided that it gets the certificate from the same CA which you would have set now as trusted. This trusted certificate could be added in cacerts but the recommended solution is to use your own separate truststore, import it and set it in JVM to override the default cacerts. Plenty of example in Google.
For case (2) this is a really bad setup and are in trouble as you would need to actually update the truststore manually each time the LDAP server changes certificate.
But in any case I can only assume that the certificate changes due to expiration? I can't think of another reason (except compromise of private key but this is not the problem here from your description)

Categories