SunCertPathBuilderException: unable to find valid certification path to requested target in CN1 app
Solution 1
It is now working.
(On cloud tomcat) I made sure the root certificate and the intermediary certificate were in my keystore (as per the links i previously included). I included my .ca-bundle in the keystore for good measure.
(On cloud tomcat) And i noticed i was using an older version of the Apache configuration (lesson learned about relying on older forum posts). Needed to have SSLCACertificateFile pointing to my .ca-bundle file, rather than using SSCertificateChainFile, in my apache .conf file.
It still error on my simulator but works on my iphone, which points (as Shai says) to differing JDK's i expect, so upgraded my laptop to the higher JDK 1.8.171. This didn't in itself make a difference but probably required.
-
Through digging around i realised that simulators on my laptop needed the above also. So i ended up running the statements below, in command prompt as Administrator, and now my simulator is working.
cd %java_home%\jre\lib\security
path=%java_home\bin
keytool -import -alias comodo -keystore cacerts -file C:\path\ComodoRoot.cer
keytool -import -alias comodo_intermediate -keystore cacerts -file C:\path\ComodoInter.cer
keytool -import -alias purchased_cert -keystore cacerts -file C:\path\my_purchased_cert.crt
Solution 2
This happens if the signing authority isn't recognized by the underlying JDK. Assuming you purchased your certificate from a valid source it's possible that it uses a relatively new root which means you need to use the latest version of JDK 8.
E.g. letsencrypt was only added in JDK 8 update 101.
Think.Smart
Mobile App Development start-up, using the awesome codenameone
Updated on May 16, 2020Comments
-
Think.Smart almost 4 years
Please can you help. I have a Codenameone app that issues a GET request to a cloud Tomcat 8 server, and expects back some response JSON. Importantly this is a HTTPS call.
When i run the request in Postman it works fine:
https://www.mydomain.co.uk:8443/MyProject/v1/generate_token
The same URL through my browser works and shows as 'Secure' and i can see my certificate details. I have bought a certificate for my SSL/TLS configuration, and seems to function fine in the logs on startup.
In the simulator i get back the following error at the point of reading the response back from the URL call - which i guess must be encrypted:
Exception: javax.net.ssl.SSLHandshakeException - sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target javax.net.ssl.SSLHandshakeException: 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.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker.process_record(Handshaker.java:961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347) at com.codename1.impl.javase.JavaSEPort.getResponseCode(JavaSEPort.java:7591) at com.codename1.io.ConnectionRequest.performOperation(ConnectionRequest.java:702) at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:282) at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
Why should the app be any different to Postman making the call (the Network Monitor window confirms the same URL call) ?
None of the logs are being updated after my call, so nothing to check there. I haven't made any changes to my app (which was working) since moving from http to https.
Here is the CN1 code making the call:
public String fetchTokenIntoStorage(String userName, String password) { ConnectionRequest r = new ConnectionRequest(); r.setUrl(Constants.URL_HOST_PORT + "/MyProject" + Constants.LIVE_OR_TEST + "/v1/generate_token"); r.addRequestHeader("Content-Type", "application/json"); r.addRequestHeader("userName", userName); r.addRequestHeader("password", password); r.setHttpMethod("GET"); r.setFailSilently(false); r.setPost(false); // show spinning dialog while connecting InfiniteProgress prog = new InfiniteProgress(); Dialog dlg = prog.showInifiniteBlocking(); r.setDisposeOnCompletion(dlg); NetworkManager.getInstance().setTimeout(10000); // NetworkManager.getInstance().addErrorListener(new ActionListener() { // // @Override // public void actionPerformed(ActionEvent evt) { // MessageBox.showDialogMessage("Unable to connect to server. Please // retry later."); // } // }); // NetworkManager.getInstance().updateThreadCount(2); NetworkManager.getInstance().addToQueueAndWait(r); if (r.getResponseData() != null) { JSONParser parser = new JSONParser(); Map<String, Object> json = null; try { json = parser.parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (json.get("error") != null) { return String.valueOf(json.get("error")); } JwtRecord record = new JwtRecord(); record.userId = Integer.parseInt(String.valueOf(json.get("userId"))); record.jsonWebToken = (String) json.get("jwt"); record.theme = "LIGHT"; Storage.getInstance().writeObject("MyToken", record); return ""; } if (!r.getResponseErrorMessage().equalsIgnoreCase("")) { return r.getResponseErrorMessage(); } else { return "Unable to connect to server. Please check connection."; } }
Stepping through the code it seems to error just after
NetworkManager.getInstance().addToQueueAndWait(r);
The r.getResponseData() and r.getResponseErrorMessage() are null.
Many thanks