in my application I am trying to do a HTTPS POST request to my server.
However, I keep getting SSLHandshakeException - Chain chain validation failed, all the time. I tried to send a request using POSTMAN and I got a response from the server. What can be causing this error when I try to send the request from the application?
Here a code snippet where I try to send the post request:
public static JSONObject getDataLibConfiguration(Context context) throws HttpRequestException {
int statusCode = 0;
JSONObject commonInformation;
HttpsURLConnection connection = null;
try {
commonInformation = ConfigurationProcessor.getCommonInformation(context);
if (commonInformation == null) {
return null;
}
URL url = new URL(BuildConfig.SERVER_CONFIG_URL);
if (BuildConfig.DEBUG) {
LogUtils.d(TAG, "url = " + url.getPath());
}
connection = getHttpsConnection(url);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Content-Encoding", "gzip");
byte[] gzipped = HttpUtils.gzip(commonInformation.toString());
cos = new CountingOutputStream(connection.getOutputStream()); //<-- This is where I get the exception
cos.write(gzipped);
cos.flush();
statusCode = connection.getResponseCode();
// More code her
}
private static HttpsURLConnection getHttpsConnection(URL url) throws IOException, GeneralSecurityException {
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
MatchDomainTrustManager myTrustManager = new MatchDomainTrustManager(url.getHost());
TrustManager[] tms = new TrustManager[]{myTrustManager};
sslContext.init(null, tms, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
connection.setSSLSocketFactory(sslSocketFactory);
} catch (AssertionError ex) {
if (BuildConfig.DEBUG) {
LogFileUtils.e(TAG, "Exception in getHttpsConnection: " + ex.getMessage());
}
LogUtils.e(TAG, "Exception: " + ex.toString());
}
return connection;
}
In my case it was wrong date on phone.
Fixing date resolved an issue
If you're using an emulated device it may solve the problem if you just 'Cold Boot' it.
Sometimes the date on those things can get stuck if you let them run for some time, which results in this expired-certificate-problem.
The problem was that the certificate was expired.
In my case, I fetch this issue on Android Emulator.
When I clear emulator cache has resolved the issue.
My date and time were correct, but I didn't have "Use Network Provided Time checked" in my system settings.
I fixed this issue by going to Settings > Date and Time > Check "Use network-provided time" and also check "Use network-provided time zone".
Then this error went away.
In my case, the issue was with the phone date. So please check it, set to automatic.
public static void trustEveryone() {
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
public boolean verify(String hostname, SSLSession session) {
return true;
}});
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[]{new X509TrustManager(){
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}}}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(
context.getSocketFactory());
} catch (Exception e) { // should never happen
e.printStackTrace();
}
}
or check system date of your device - I had this Exception when I tried to connect with wrong date!..
If anyone come across this issue pertaining to specific device, then the reason should be because of incorrect date set in the device.
I fixed this error by resetting my emulator date and time. My server is working fine just I changed the date and time of my emulator as current server time zone.
#Yash Bhardwaj in the comment on #Vadim answer said that the problem was in Glide framework. I faced the same problem: Https requests to server using Ktor framework were all successful, but when Glide tried to load image from the same server, it faced the SSLHandshakeException.
To solve this issue you should look here: Solve Glide SSLHandshakeException.
To make a deal with #GlideModule annotation you should import kapt plugin and add these dependencies into your app build.gradle:
implementation 'com.github.bumptech.glide:okhttp3-integration:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
If you use android emulator, you can wipe data and run again, it works
Related
I am trying to make a https request using this code:
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
request = new Request<String>(Request.Method.GET,"https://devblahblahblah.com/service/etc",errListener);
but I am getting this error:
com.android.volley.NoConnectionError:
javax.net.ssl.SSLHandshakeException:
java.security.cert.CertPathValidatorException: Trust anchor for
certification path not found.
Two points to be noted:
The HTTPS cert is valid. Easily opens without any warning on browser.
The above code works fine with HTTP links.
I actually need to know if there are any switches/options in the Android Volley framework by using which I'll successfully hit a HTTPS URL?
Warning: The following code should not be used in production because it is vulnerable to SSL attacks
Probably these codes below will be helpful for you:
1.Create a HttpsTrustManager class that implements X509TrustManager:
public class HttpsTrustManager implements X509TrustManager {
private static TrustManager[] trustManagers;
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}
public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return _AcceptedIssuers;
}
public static void allowAllSSL() {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[]{new HttpsTrustManager()};
}
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());
}
}
2.Add HttpsTrustManager.allowAllSSL() before you make a https request:
HttpsTrustManager.allowAllSSL();
String tag_string_req = "string_req";
StringRequest strReq = new StringRequest(Request.Method.POST,
your_https_url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "response :"+response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
}){
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("username", "max");
params.put("password", "123456");
return params;
}
};
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
you can add this class and execut it from onCreate method
new NukeSSLCerts().nuke();
it will make volley to Trust all SSL certificates.
So far the only answer talk about adding an untrusted certificate as the solution, but since your browser doesn't complain it usually means Volley can't find the intermediate certificate that does complete the full trusted chain.
It happened to me with LetsEncrypt certificates. Most browsers already have that intermediate certs so on browser everything looks fine, but Volley was apparently missing something.
The solution
Add the intermediate certificate to your webserver config. For Apache you can follow this reference:
https://access.redhat.com/solutions/43575
For LetsEncrypt it specifically is this file: /etc/letsencrypt/live/your.website.com/chain.pem
So besides your CertificateFile and KeyFile you should already have working you now have this third line:
SSLCertificateChainFile /etc/letsencrypt/live/your.website.com/chain.pem
Just adding that line, restarting apache and Volley doesn't complain anymore and you didn't introduce any security vulnerabilities!
If you are using volley and want to HTTPS request or SSL Certified service then you can choose this easiest way : -->
Step --> 1. keep .cer file into res/raw/ folder.
Step --> 2. Use this method and replace .cer file name with your .cer file and replace your host name also.
private SSLSocketFactory getSocketFactory() {
CertificateFactory cf = null;
try {
cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.cert_name);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.e("CERT", "ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
Log.e("CipherUsed", session.getCipherSuite());
return hostname.compareTo("10.199.89.68")==0; //The Hostname of your server.
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
SSLContext context = null;
context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
SSLSocketFactory sf = context.getSocketFactory();
return sf;
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
Step --> 3. Replace this line "RequestQueue queue = Volley.newRequestQueue(this);" with "RequestQueue queue = Volley.newRequestQueue(this, new HurlStack(null, getSocketFactory()));" in request of volley.
I couldn't open the link provided by #Ogre_BGR,but while browsing the net I found the actual implementation done in following smanikandan14 Github.Look upon his SSl-connection explanation to understand more about it.
This can happen for several reasons, including:
The CA that issued the server certificate was unknown
The server certificate wasn't signed by a CA, but was self signed
The server configuration is missing an intermediate CA
Official doc from android
Solution:
you can provide a certificate file within the request
For anyone who will come up against a problem like this and you use Letsencrypt for your SSL and node.js for webserver, try this. Assuming you have something like this. I fixed this by adding the line const chain = fs... Hope this helps
...
const app = express();
const privateKey = fs.readFileSync('ssl/privkey.pem', 'utf8');
const certificate = fs.readFileSync('ssl/cert.pem', 'utf8');
const chain = fs.readFileSync('ssl/chain.pem', 'utf8');
const credentials = {key: privateKey, cert: certificate, ca: chain};
...
var httpsServer = https.createServer(credentials, app);
I got the same problem when I add ssl to the domain, After 2 days gone, I found the solution the URL is getting wrong . I was using https://example.com but when I add ssl into domain the url will be change
https://www.example.com
And POST is working fine
got this error when i turned off proxy from cloudflare
check image here
the best solution for this problem is you can turn on proxy back and also add a full secure access on ssl certificate.
If anyone is using nginx and SSL certificates from letsencrypt, the solution is to simply use the certificate from file fullchain.pem instead of cert.pem:
ssl_certificate /.../fullchain.pem;
This file includes the concatenation of your certificate and the CA's.
I am doing a HTTPS request using a HttpsURLConnection.
The server I'm trying to contact has a self-signed certificate, so this logically causes the request to fail.
However, the failure isn't signaled to my program by an exception. It just fails and I can see why in the logcat.
03-22 17:54:35.203: W/System.err(21147): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
03-22 17:54:35.203: W/System.err(21147): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:381)
Here is the code I use for the request:
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setAllowUserInteraction(false);
connection.connect();
Ideally, I'd like my program to react like browser do: popup a dialog indicating that the certificate is not trusted and possibly add it to some key-store and retry the request.
But since I can't figure out a way of getting the exception, I really don't know what to do here.
Any clue ?
While huge is correct that you need to implement a custom TrustManager, you should absolutely not just blindly accept all SSL certificates.
Nikolay Elenikov has an excellent blog post describes how to set up a custom TrustManager to validate such certificates
You can do it like this:
SSLContext sc = SSLContext.getInstance("TLS");
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return;
}
#Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return;
}
} };
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpURLConnection = connection = endPoint.openConnection();
This is where I got the socketIO files from.
https://github.com/Gottox/socket.io-java-client/tree/master/src/io/socket
I am on the client side.
I know connecting works when the server does not need authentication.
But when it needs authentication (Username and password), I get a handshaking error message.
How do I get passed authentication?? Could it be a server side error? Would the server side of things change if authentication was added?
This is the function that throws an error...I did not write it.
This line is the one causing problems: InputStream stream = connection.getInputStream();
It says it is caused by: java.io.FileNotFoundException: url:80/socket.io/1/
private void handshake() {
URL url;
String response;
URLConnection connection;
try {
setState(STATE_HANDSHAKE);
url = new URL(IOConnection.this.url.toString() + SOCKET_IO_1);
connection = url.openConnection();
if (connection instanceof HttpsURLConnection) {
((HttpsURLConnection) connection)
.setSSLSocketFactory(sslContext.getSocketFactory());
}
connection.setConnectTimeout(connectTimeout);
connection.setReadTimeout(connectTimeout);
/* Setting the request headers */
for (Entry<Object, Object> entry : headers.entrySet()) {
connection.setRequestProperty((String) entry.getKey(),
(String) entry.getValue());
}
InputStream stream = connection.getInputStream();
Scanner in = new Scanner(stream);
response = in.nextLine();
String[] data = response.split(":");
sessionId = data[0];
heartbeatTimeout = Long.parseLong(data[1]) * 1000;
closingTimeout = Long.parseLong(data[2]) * 1000;
protocols = Arrays.asList(data[3].split(","));
} catch (Exception e) {
error(new SocketIOException("Error while handshaking", e));
}
}
Problem solved (sort of), here: Android developpement, Gottox socket.io-java-client: file not fount Exception /socket.io/1/
(try using an earlier version of socket.io - by first deleting socket.io folder from node_modules and then install an older version, e.g., 0.9.16, using this command: npm install socket.io#0.9.16)
I've looked around at several different questions/answers here on SO regarding the XmlPullParserException in Android using KSOAP2 but so far nothing has helped me figure out what's wrong. I'm starting to port over my iOS App to Android, and right now I'm stuck on this part of getting the app to communicate with a .Net Web Service. Below is the code in question, most of which was pieced together from various different questions/blogs/sites since I also have a self signed certificate on the Web Service. If anyone has any tips or can point me in the direction of some reading that will help me figure this out that would be great since there are several other areas of the app the use the Web Service and I know I'm going to need to know how to debug this better than what I'm getting now.
String URL = "https://online.ensinet.com/Services/ENSIMobileservice.asmx";
String SOAP_ACTION = "http://ensinet.com/VerifyRep";
String NAMESPACE = "http://ensinet.com/";
String METHOD_NAME = "VerifyRep";
String SERVER = "online.ensinet.com";
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//PropertyInfo usernamePI = new PropertyInfo();
//usernamePI.setName("RepLogin");
//usernamePI.setValue(username);
//usernamePI.setType(String.class);
request.addProperty("RepLogin", username);
//PropertyInfo passPI = new PropertyInfo();
//passPI.setName("RepPass");
//passPI.setValue(passphrase);
//passPI.setType(String.class);
request.addProperty("RepPass",passphrase);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
try
{
allowAllSSL();
HttpsTransportSE androidHttpTransport = new HttpsTransportSE(SERVER,443, URL, 1000);
androidHttpTransport.call(SOAP_ACTION,envelope);
SoapObject response=(SoapObject) envelope.getResponse();
Log.i("Message", "the response contains: " + response.toString());
}
catch(Exception e)
{
Log.i("Message", "there was an error: " + e);
}
Okay so here's a little bit more information. First the allowAllSSL() is a method I found in another forum to bypass the credential manager of a self signed certificate since I don't have the credentials and the information that is being gathered by the mobile device isn't sensitive like the Web Application where all the Web Services are hosted. Below is the method in detail that sets up a fake credential manager
private static TrustManager[] trustManagers;
public static class _FakeX509TrustManager implements
javax.net.ssl.X509TrustManager {
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public boolean isClientTrusted(X509Certificate[] chain) {
return (true);
}
public boolean isServerTrusted(X509Certificate[] chain) {
return (true);
}
public X509Certificate[] getAcceptedIssuers() {
return (_AcceptedIssuers);
}
}
public static void allowAllSSL() {
javax.net.ssl.HttpsURLConnection
.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
javax.net.ssl.SSLContext context = null;
if (trustManagers == null) {
trustManagers = new javax.net.ssl.TrustManager[] { new _FakeX509TrustManager() };
}
try {
context = javax.net.ssl.SSLContext.getInstance("SSL");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
Log.e("allowAllSSL", e.toString());
} catch (KeyManagementException e) {
Log.e("allowAllSSL", e.toString());
}
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context
.getSocketFactory());
}
}
Also, I took a look at the requestDump and I noticed that in the request there's a <Header /> tag that isn't part of the actual Web Service request so I think this is being added by KSOAP2, and so far I haven't seen a way to remove it which may be part of the START TAG erro that I'm getting. I think I'm going to have the build the SOAP request manually, which I will try later tonight to see if that works.
Okay so I was able to figure out the problem. It looks like the android side is a bit more specific than the iOS side since the problem was the URL that I was using. In the code above I was using the URL of the complete list of Operations that are available for the Mobile Application like in the iOS code, but I needed to use the actual URL of the Operation I was calling (so I needed to add ?op=VerifyRep to the end of the URL string above). Now I'm getting the right responses, so it's off to the next step and trying to figure out how the parse out the data needed.
Below is the URL I send to the WS after the handshake is done
"https://ekp.truefriend.com/COVIWeb/gate/AutoAuthentication.aspx?UserID=DP0001&BackUrl=http%3a%2f%2fgw.truefriendtest.com%2fCOVIWeb%2fApproval%2fForms%2fForm.aspx%3fmobileyn%3dY%26piid%3d96482621-6cc4-401c-a6f9-5ba6cb7ce26f%26wiid%3d425a9bc9-8607-4898-9158-ed9170da1d89%26fmpf%3dWF_A_DRAFT_PAPER01%26fmrv%3d0%26fiid%3d749526BE-B208-4987-B751-2DD0FC03F0F6%26fmid%3d24f6765d-69d1-429f-b0da-b540a064f0e2%26scid%3ddc4378f1-7edd-4d69-8fe4-5867ed32c8b9"
What it should do is redirecting the browser to BackUrl page given in the url. It display correct result in IE8 despite the certificate problem. In PC version of Chrome it display some code of the HTML. In Android, I get 403 Forbidden error.
HTTP/1.1 403 Forbidden ( The server denied the specified Uniform Resource Locator (URL). Contact the server administrator. )
I use this method to stream data
try{
URL url = new URL(urlString);
HttpsURLConnection.setDefaultHostnameVerifier(new FakeHostVerifier());
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
Log.d("SSLDemo", "getAcceptedIssuers");
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
Log.d("SSLDemo", "Check Client Trusted");
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
Log.d("SSLDemo", "Check Server Trusted");
}
}
};
SSLContext sc = SSLContext.getInstance("TLS"); //"TLS"
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
int port = 443;
SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory();
socket = (SSLSocket)factory.createSocket(url.getHost(), port);
socket.startHandshake();
/**
* Connection Method
*/
String method = "GET";
String os = method + " "+urlString+" HTTP/1.0\r\n";
os += "Content-Length: 0";
os += "\r\n\r\n";
((SSLWeb)this.caller).updateRequest(urlString, method);
Log.i("TESTWEB", os);
BufferedWriter wout = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
wout.write(os);
wout.flush();
wout.close();
rd = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//********* Not using thread
StringBuffer buff = new StringBuffer();
char[] buffer = new char[1024];
while(rd.read(buffer) > -1) {
buff.append(buffer);
Log.i("TESTWEB", "read buffer :" + String.valueOf(buffer));
}
Log.i("TESTWEB", "read line :" + buff.toString());
//**********
}catch(Exception e){
Log.e("TESTWEB", "Connecting error", e);
e.printStackTrace();
}
Is there something wrong with my code? I thought the problem was with the URL parameter, but it work in browser :(
I've been finding a way around the problem for the last three days now, no luck so far.
EDIT: This is FakeHostVerifier class that used to skip the certificate validation process. Isn't this correct?
public class FakeHostVerifier implements HostnameVerifier {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
As I was saying in a comment to another answer, this has nothing to do with trusting the server's certificate or not. If you get an HTTP response, even if it's a 403, that means that the HTTP connection was established, which also means that the underlying SSL/TLS connection was established. If your client doesn't trust the server certificate, the SSL/TLS connection will close before any HTTP traffic happens.
I'd try a few things:
Remove the Content-Length header. It's a GET request, so it doesn't have an entity. Implying a 0-length entity might confuse the server.
Try to set a User-Agent header to simulate the request as coming from a browser.
More generally, look at the headers a browser that work would send and try to reproduce them. (Try Accept header as well, that might be the cause of your problem with Chrome.)
EDIT: (other potential problem, more likely to be the cause)
If you urlstring variable really contains "https://ekp.truefriend.com/COVIWeb/gate/...", that's where the problem comes from.
When you send an HTTP GET the request should be like this:
GET /COVIWeb/gate/... HTTP/1.1
Host: ekp.truefriend.com
Not:
GET https://ekp.truefriend.com/COVIWeb/gate/... HTTP/1.1
(that's only for requests via a proxy, and doesn't apply to the HTTPS requests anyway.)
If you're using HTTP 1.0, you won't use the Host header, but it shouldn't really matter (unless that host serves multiple virtual hosts, which it can do, even over HTTPS). Consider using HTTP/1.1 if you can, although you may have to deal with closing the connection (content-length or chunked encoding perhaps).
Your question contains the answer. Upon trying to access the URL you specified in Chrome, you get a big red warning "The site's security certificate is not trusted!". While you can manually override in a browser and ignore the warning, your code treats this as a security problem and a dead end. It even recommends you contact the server administrator.
If you are the server's admin, change the SSL cert to a valid one. if not, ask the admin to do it. Failing that, try accessing the HTTP (non-SSL) version of the site.