Android application doesn't trust certificate - android

I have a certificate to secure my site, certified by: Thawte DV SSL CA, Thawte, Inc.
Now I made an android application that connects to a webservice from this site.
It used to work fine when just going for http://www.myserver.com.
But now that it's secured, and going for https://www.myserver.com I'm having some issues.
I use 2 phones to test my application.
HTC Desire S with Android 2.3.3 (has SD card)
Huawei Ideos X5 with Android 2.2.1 (no SD card)
The HTC does not have any problem connecting to the https.
The Huawei however gives a "Not trusted certificate exception".
The code I used to try and connect is the following:
public String performRequest(String message, String url, Context context) throws IOException {
AndroidHttpClient hc = AndroidHttpClient.newInstance("Android",context);
Log.d(MobileConnectorApplication.APPLICATION_TAG, "NETWORK - Message to send: "+ message);
HttpPost p = new HttpPost(url);
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setSoTimeout(httpParams, threeMinutes );
p.setParams(httpParams);
try{
if (message != null)
p.setEntity(new StringEntity(message, "UTF8"));
}catch(Exception e){
e.printStackTrace();
}
p.setHeader("Content-type", "application/json");
String response = "";
HttpContext httpcontext = new BasicHttpContext();
httpcontext.setAttribute(ClientContext.COOKIE_STORE, MobileConnectorApplication.COOKIE_STORE);
try{
HttpResponse resp = hc.execute(p,httpcontext);
InputStream is = resp.getEntity().getContent();
response = convertStreamToString(is);
int httpResponsecode = resp.getStatusLine().getStatusCode() ;
checkResponse(url, message, response, httpResponsecode);
Log.d(MobileConnectorApplication.APPLICATION_TAG, String.format("NETWORK - Response %s : %s", httpResponsecode, response.length() > 150 ? response.subSequence(0, 150): response));
} finally{
hc.close();
}
return response;
}
This part of the code was made by someone else a few months ago and he isn't around to change it and my knowledge about these connections isn't so great.
could someone help me out? Thanks in advance!

Related

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate on HttpClient but works fine with HttpUrlConnection

Previously,I used HttpClient for a http post request and it was working fine, until I believe the server team made some changes. Then I kept getting
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate Exception.
Then, after alot of scratching my head, I tried HttpUrlConnection and it works fine, but still I can't figure out why I got that exception while using HttpClient.
Before code was :
public String postDataAndGetStringResponse( List<NameValuePair> nameValuePairs ) {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost( link );
try {
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
InputStream is = response.getEntity().getContent();
String result = "";
if (is != null) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
String l = "";
while ((l = reader.readLine()) != null) {
result += l;
}
reader.close();
}
is.close();
return result;
} catch (Exception e) {
Logger.printStackTrace(e);
return ServerUnrechable;
}
}
I did check the server using https://www.sslshopper.com and everything is ticked, it would be very helpful if anybody could tell me the cause to this issue.
One of the most likely causes is that the server you're trying to use now relies on Server Name Indication.
SNI support was added a to HttpsURLConnection in Android, but not to the Apache HTTP Client bundled (now deprecated/removed). See this related question for details.

android why sending information to server works with WIFI only?

I am sending information to a server via WIFI and everything works great.Now i want to send information to a server with mobile data too, and i do not know why only works with WIFI, with mobile data trows an exception of failed to connect to server.
this is the part that fail with mobile data; with WIFI works perfectly:
int length=values.length();
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams,9000);
HttpConnectionParams.setSoTimeout(httpParams, 9000);
HttpClient client = new DefaultHttpClient(httpParams);
String url = saveData+"?Length="+length+"&Table="+temp;
HttpPost request = new HttpPost(url);
request.setEntity(new ByteArrayEntity(values.toString().getBytes("UTF8")));
request.setHeader("json", values.toString());
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
Log.d("test 7","test 7 last");
if (entity != null) {
InputStream instream = entity.getContent();
String result = RestClient.convertStreamToString(instream);
Log.d("here",""+result);
if(result.equals("success")&& ReadyOff==false){
Ready=true;
}else{
Ready=false;
ReadyOff=true;
}
Log.d("sent","valor de ready"+Ready);
}
so i am doing something wrong?
`
You cannot contact your server from the device's mobile network unless it is routable from the public Internet.
A server running on your development machine or otherwise behind a NAT/firewall would typically only be accessible from your local network / wifi.

Strange HttpResponse in Android

I am having an unusual problem regarding the following code in an android application.
public InputStream retrieveStream(String url) {
HttpGet request = new HttpGet(url);
HttpParams httpParams = new BasicHttpParams();
int some_reasonable_timeout = (int) (10 * DateUtils.SECOND_IN_MILLIS);
HttpConnectionParams.setConnectionTimeout(httpParams, some_reasonable_timeout);
HttpConnectionParams.setSoTimeout(httpParams, some_reasonable_timeout);
HttpClient client = new DefaultHttpClient(httpParams);
try
{
HttpResponse response = client.execute(request);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK){
HttpEntity getResponseEntity = response.getEntity();
return getResponseEntity.getContent();
}
else
{
Log.w(getClass().getSimpleName(),
"Error " + statusCode + " for URL " + url);
return null;
}
}
catch (ClientProtocolException e)
{
Log.e("Methods", "HTTP Error", e);
return null;
}
catch (IOException e)
{
Log.e("Methods", "Connection Error", e);
return null;
}
}
Within the application I attempt to connect to a localhost.(In an AsyncTask)
InputStream source = retrieveStream("http://10.0.2.2:27080/testdb/_hello")
When running on the emulator, this code works fine and if the localhost is down, "source" is returned as null as expected. Similarly when running the code on a mobile device (HTC Nexus One, Android Version 2.2), the code reports "source" as null as expected.
However when running the same APK on another mobile device (Samsung Galaxy S2, Android Version 4.0.3, samsung release), the status code returned is given as HttpStatus.SC_OK, even though it couldnt possibly be connecting to the localhost. Has anyone encountered a similar problem?
Android > 3.0 does not allow to execute web request on Main UI Thread. you need to use AsyncTask to make web request. IN android > 3.0

Https connection Android

I have an applications that connects to a web service that uses an Entrust valid certificate. The only difference is that it's a wildcard SSL.
The problem is : I get an
ERROR/NoHttpResponseException(5195): org.apache.http.NoHttpResponseException: The target server failed to respond
when I'm on 3G. When on WIFI it works, on simulator it works, tethering the simulator trough my phones 3G works. But the app on my phone from 3G dosen't work at all. Tested on a HTC Legend CM7.0.3(2.3.3) and Nexus S 2.3.3 on 2 different network(Virgin Mobile Canada and Fido).
I have a PCAP dump from my device that show some error, but I don't understand it really well.
Acknowledgement number: Broken TCP. The acknowledge field is nonzero while the ACK flag is not set
I tried the fix on this question this question too. I don't know where else to go.
By the way, the web service work with the browser on 3G.
We are also using basic auth with HttpRequestInterceptor.
I think this is all the details I can give. If something else is needed feel free to ask.
This question is related too, I've tried both fix, none of them work.
Edit
I'm starting to think that this could be better suited for serverfault.com
This is the dump file and the screenshot
Edit 2
This is the code I'm using to connect to the web service in question.
protected HttpEntity sendData(List<NameValuePair> pairs, String method)
throws ClientProtocolException, IOException,
AuthenticationException {
pairs.add(new BasicNameValuePair(KEY_SECURITY, KEY));
pairs.add(new BasicNameValuePair(LANG_KEY, lang));
pairs.add(new BasicNameValuePair(OS_KEY, OS));
pairs.add(new BasicNameValuePair(MODEL_KEY, model));
pairs.add(new BasicNameValuePair(CARRIER_KEY, carrier));
DefaultHttpClient client = getClient();
HttpPost post = new HttpPost();
try {
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
post.setEntity(new UrlEncodedFormEntity(pairs));
} catch (UnsupportedEncodingException e1) {
Log.e("UnsupportedEncodingException", e1.toString());
}
URI uri = URI.create(method);
post.setURI(uri);
client.addRequestInterceptor(preemptiveAuth, 0);
HttpHost target = new HttpHost(host, port, protocol);
HttpContext httpContext = new BasicHttpContext();
HttpResponse response = client.execute(target, post, httpContext);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 401) {
throw new AuthenticationException("Invalid username or password");
}
return response.getEntity();
}
We finally found the problem. It wasn't code related.
It was the reverse DNS that was timing-out. Because I dind't receive any answer from the reverse DNS my apache/ssl session was closed prematurely.
By using Google's DNS on a rooted device it worked.
The only thing left to do now is fix the our reverse DNS.
Here is a workaround : http://code.google.com/p/android/issues/detail?id=13117#c14
Call this method on your DefaultHttpClient or AndroidHttpClient instance. It will prevent the reverse DNS lookup from being made.
private void workAroundReverseDnsBugInHoneycombAndEarlier(HttpClient client) {
// Android had a bug where HTTPS made reverse DNS lookups (fixed in Ice Cream Sandwich)
// http://code.google.com/p/android/issues/detail?id=13117
SocketFactory socketFactory = new LayeredSocketFactory() {
SSLSocketFactory delegate = SSLSocketFactory.getSocketFactory();
#Override public Socket createSocket() throws IOException {
return delegate.createSocket();
}
#Override public Socket connectSocket(Socket sock, String host, int port,
InetAddress localAddress, int localPort, HttpParams params) throws IOException {
return delegate.connectSocket(sock, host, port, localAddress, localPort, params);
}
#Override public boolean isSecure(Socket sock) throws IllegalArgumentException {
return delegate.isSecure(sock);
}
#Override public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException {
injectHostname(socket, host);
return delegate.createSocket(socket, host, port, autoClose);
}
private void injectHostname(Socket socket, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(socket.getInetAddress(), host);
} catch (Exception ignored) {
}
}
};
client.getConnectionManager().getSchemeRegistry()
.register(new Scheme("https", socketFactory, 443));
}
Have you tried the solution mentioned in HttpClient on Android : NoHttpResponseException through UMTS/3G?
Copy below
I finally got rid of this problem : simply a HTTP header that was badly handled by a squid server on the road :
Expect: 100-Continue
It seems to be there by default with DefaultHttpClient on android SDK. To tackle this, simply add that in your code :
HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("year","1980"));
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://example.com/getAllPeopleBornAfter.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "n");
}
is.close();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
refer this code for http connection

Android: Why is HttpPost request not going through proxy?

I've set up a new Access Point on my emulator so that I can view traffic in Fiddler by following the instructions here: http://aurir.wordpress.com/2010/03/22/tutorial-getting-android-emulator-working-with-fiddler-http-proxy-tool/
This works for the browser requests from the Emulator but the HttpPost request in my application is now visible in Fiddler.
Here's the code I'm using:
private InputStream post(String url, Hashtable<String, String> postvariables) {
DefaultHttpClient httpClient = new DefaultHttpClient();
URI uri;
InputStream data = null;
try {
uri = new URI(url);
HttpPost method = new HttpPost(uri);
method.setHeader("Content-Type","application/json");
String param = new String();
Enumeration<String> e = postvariables.keys();
while(e.hasMoreElements())
{
String key = e.nextElement();
param = param + key + "=" + postvariables.get(key);
if(e.hasMoreElements()) {
param = param + "&";
}
}
Log.i("RestClient",url + param);
HttpEntity entity = new StringEntity(param);
method.setEntity(entity);
HttpResponse response = httpClient.execute(method);
data = response.getEntity().getContent();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
Any idea what I'm doing wrong?
I have never tried this explicitly, but have seen many reports that redirecting emulator traffic by changing the APN only affects the Browser. You might have better luck running the emulator instance with the option -http-proxy <proxy>. Look here, under Emulator Startup Options (Network) for more:
http://developer.android.com/guide/developing/tools/emulator.html
$0.02: We use Charles to debug web services and booting up the emulator in this fashion works for all traffic.
Hope that helps!

Categories

Resources