Android rest client with SSL to specific certificate - android

I'am trying to connect to SSL rest service from Android. The server uses a SSL cert that is not from a common CA (Thawte, Verisign...)
I'have used this example to proceed: http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/
However, although I've done all the steps mentioned (create a BKS provider, create a a custom SchemeRegistry) I have still the error: "No peer certificate".
The code to call the service (from an AsyncTask):
DefaultHttpClient client = new MyHttpClient(mainActivity[0].getApplicationContext());
HttpGet get = new HttpGet("<url of the service>");
get.addHeader("Autorization","Basic YW5kcm9pZDo=");
// Execute the GET call and obtain the response
HttpResponse getResponse;
try {
getResponse = client.execute(get);
....
The code of the MyHttpClient is the same of the blog example. Doing the client.execute(get) crashes with the execption:
01-06 21:47:03.615: W/System.err(19289): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
01-06 21:47:03.625: W/System.err(19289): at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:137)
01-06 21:47:03.630: W/System.err(19289): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
01-06 21:47:03.635: W/System.err(19289): at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
01-06 21:47:03.640: W/System.err(19289): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
01-06 21:47:03.645: W/System.err(19289): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-06 21:47:03.645: W/System.err(19289): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-06 21:47:03.645: W/System.err(19289): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-06 21:47:03.650: W/System.err(19289): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
01-06 21:47:03.650: W/System.err(19289): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
01-06 21:47:03.650: W/System.err(19289): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
01-06 21:47:03.650: W/System.err(19289): at validatedid.helloworldandroid.DownloadDevicePendingDocsTask.doInBackground(DownloadDevicePendingDocsTask.java:41)
01-06 21:47:03.650: W/System.err(19289): at validatedid.helloworldandroid.DownloadDevicePendingDocsTask.doInBackground(DownloadDevicePendingDocsTask.java:1)
01-06 21:47:03.655: W/System.err(19289): at android.os.AsyncTask$2.call(AsyncTask.java:264)
01-06 21:47:03.655: W/System.err(19289): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-06 21:47:03.655: W/System.err(19289): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-06 21:47:03.655: W/System.err(19289): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
01-06 21:47:03.660: W/System.err(19289): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-06 21:47:03.660: W/System.err(19289): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-06 21:47:03.660: W/System.err(19289): at java.lang.Thread.run(Thread.java:856)
In some places say it could be an error from the server but I don't know how to check that. Any help would be really apreciated.
Thanks in advance.

Looking more into stackoverflow I find the solution to the problem.
Looks like using the code from http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/ is not enough (at least for me).
SSLSocketFactory needs to be subclassed. Full explanation in: Trusting all certificates using HttpClient over HTTPS
I leave here the answer in case anybody arrives here.
I hope in next versions of Android it will be a easier way to acces rest services with https because is a common task and currently is not very easy.

I used ->this<- to make my Https Self-Signed Certificate connections, without disabling certificate or host validation, so it's REALLY secure from SSL pov.
In resume, need to create a Custom Keystore on your app so you can validate your server HTTP against the app KeyStore.
It's dissapointing to see that too much people consider disabling SSL validations a correct answer to this type of questions, when in fact, the whole point of SSL is Security and Validations. If you intend to avoid any validation, just stick to plain HTTP
Please refer to this answer i've recently made on another question

Related

How can I tell the worklight hybrid client to used a specific certificate that was downloaded to the device?

I copied the client certificate to the device, save to local storage, then install certificate from storage. I'm using DataPower to terminate the SSL and validate the certificate before forwarding requests to Worklight.
When I try to connect, it fails with log message stating "establisheSSLClientAuth isCertificateExists: false" and an SSLHandshakeException.
I assume this means the client is not sending the client certificate. This all happens under the covers with Worklight, so I'm trying to figure out how to tell it to use a specific certificate.
02-11 12:29:23.147: D/NONE(5995): wlclient init success
02-11 12:29:23.147: D/NONE(5995): establishSSLClientAuth isCertificateExists: false
02-11 12:29:23.157: D/NONE(5995): Request [/apps/services/api/MyMobileApp/android/init]
02-11 12:29:23.237: D/HttpPostRequestSender(5995): WLHybridRequestSender.run in WLHybridRequestSender.java:47 :: Sending request https://10.75.29.27/MQTTClient/apps/services/api/MyMobileApp/android/init
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): WLNativeXHRPlugin$NativeXHRPostListener.onException in WLNativeXHRPlugin.java:154 :: onException
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x784e3468: Failure in SSL library, usually a protocol error
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1256 0x7849ae90:0x00000003)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:468)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at android.net.SSLCertificateSocketFactory.verifyHostname(SSLCertificateSocketFactory.java:232)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at android.net.SSLCertificateSocketFactory.createSocket(SSLCertificateSocketFactory.java:481)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:382)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at com.worklight.wlclient.WLHybridRequestSender.run(WLHybridRequestSender.java:63)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at java.lang.Thread.run(Thread.java:841)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x784e3468: Failure in SSL library, usually a protocol error
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1256 0x7849ae90:0x00000003)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:425)
02-11 12:29:23.477: E/com.worklight.androidgap.plugin.WLNativeXHRPlugin(5995): ... 13 more
02-11 12:29:23.497: E/NONE(5995): [/apps/services/api/MyMobileApp/android/init] Host is not responsive. Try to manually access the URL through the android emulator browser to verify connectivity.
02-11 12:29:23.507: I/NONE(5995): Failed connecting to Worklight Server.
02-11 12:29:28.102: E/ViewRootImpl(5995): sendUserActionEvent() mView == null
The problem is we need to be able to specify what Client Certificate to use on the WL.CLient instead of WL.Server pushing the the Client Certificate to the WL.Client. I saw an Android demo of using credentials obtained from an NFC card using a custom created Cordova plugin and ChallengeHandlers. While a plugin could be created to get the credentials, I don't think it solves the problem when you add DataPower into the mix.
Worklight will only use a certificate that it has provisioned unto the device, not one that you place there manually.
Worklight's User Cert Auth feature can use your PKI of choice, to provision the client device with a x509 client certificate. However, it first takes care to validate device, app and user has authenticated before the certificate is installed for future use.
To learn more about Worklight's User Certificate Authentication feature visit:
http://www-01.ibm.com/support/knowledgecenter/?lang=en#!/SSHS8R_6.3.0/com.ibm.worklight.monitor.doc/monitor/c_user_CA.html
Another option is to have Datapower do one way SSL. Meaning it can accept but not require a client certificate.

PhoneGap/Cordova Application with Google Analytics Plugin error on Android only

I am using PhoneGap version 3.3.0-0.18.0
I am using this plugin:
https://github.com/phonegap-build/GAPlugin
It works great for iOS, however on Android I cannot seem to log any events, I get the following come up in Eclipse when running on my Android device:
01-06 11:36:23.705: E/GAV2(3478): Thread[GAThread,5,main]: Error on GAThread: java.lang.SecurityException: ConnectivityService: Neither user 10132 nor current process has android.permission.ACCESS_NETWORK_STATE.
01-06 11:36:23.705: E/GAV2(3478): at android.os.Parcel.readException(Parcel.java:1425)
01-06 11:36:23.705: E/GAV2(3478): at android.os.Parcel.readException(Parcel.java:1379)
01-06 11:36:23.705: E/GAV2(3478): at android.net.IConnectivityManager$Stub$Proxy.getActiveNetworkInfo(IConnectivityManager.java:667)
01-06 11:36:23.705: E/GAV2(3478): at android.net.ConnectivityManager.getActiveNetworkInfo(ConnectivityManager.java:458)
01-06 11:36:23.705: E/GAV2(3478): at com.google.analytics.tracking.android.SimpleNetworkDispatcher.okToDispatch(SimpleNetworkDispatcher.java:69)
01-06 11:36:23.705: E/GAV2(3478): at com.google.analytics.tracking.android.PersistentAnalyticsStore.dispatch(PersistentAnalyticsStore.java:483)
01-06 11:36:23.705: E/GAV2(3478): at com.google.analytics.tracking.android.GAServiceProxy.dispatchToStore(GAServiceProxy.java:245)
01-06 11:36:23.705: E/GAV2(3478): at com.google.analytics.tracking.android.GAServiceProxy.sendQueue(GAServiceProxy.java:216)
01-06 11:36:23.705: E/GAV2(3478): at com.google.analytics.tracking.android.GAServiceProxy.access$000(GAServiceProxy.java:27)
01-06 11:36:23.705: E/GAV2(3478): at com.google.analytics.tracking.android.GAServiceProxy$2.run(GAServiceProxy.java:198)
01-06 11:36:23.705: E/GAV2(3478): at com.google.analytics.tracking.android.GAThread.run(GAThread.java:520)
01-06 11:36:23.705: E/GAV2(3478): Thread[GAThread,5,main]: Google Analytics is shutting down.
From reading the error messages it seems as though the application does not have permission to send GA data, is there a way round this?
Add below permission to your manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
This permission are required to add in every phonegap project. as our html file will run on browser & some of our stylesheet & js needs to check the current state of network. so it can detect that is there any network connection available or not & then it can proceed. To check the state android has the permission <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
.

Android device cannot connect to localhost

I am developing an app for Android. I have been happily developing it for a while, connecting the phone to the PC using a USB, using 192.168.x.x as the address the code points to log in, etc.
I started my IDE a couple of hours before, and without changing a single comma anywhere, I receive an Exception:
10-21 17:15:04.177: W/System.err(24232): org.apache.http.conn.ConnectTimeoutException: Connect to /192.168.1.4:8080 timed out
10-21 17:15:04.177: W/System.err(24232): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)
10-21 17:15:04.187: W/System.err(24232): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
10-21 17:15:04.187: W/System.err(24232): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
10-21 17:15:04.197: W/System.err(24232): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
10-21 17:15:04.197: W/System.err(24232): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
10-21 17:15:04.197: W/System.err(24232): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
10-21 17:15:04.197: W/System.err(24232): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
10-21 17:15:04.197: W/System.err(24232): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
10-21 17:15:04.197: W/System.err(24232): at myPackage.CustomHttpClient.executeHttpPost(CustomHttpClient.java:54)
10-21 17:15:04.197: W/System.err(24232): at myPackage.LoginActivity$3$1.run(LoginActivity.java:113)
I have checked the server is up
My phone is connected to the same wifi the PC with the server is
Internet permission is in my manifest
I do have Internet, since I am writing this here
My phone has Internet, since I have been accessing the internet with him, via the same WiFi
Did ipconfig to make sure the IP is correct
i am getting mad... any help? Thank you!
A very weird thing happened. When I did ipconfig I would swear over the most sacred thing on earth i saw 192.168.1.4. I did it more than one time, always saying 192.168.1.4. After posting this question I did it again...and it showed 192.168.1.3. i changed it in the Android app and now i am able to access server.
Is there some time between an IP has changed and the ipconfig shows it? Because im SURE it said 192.168.1.4 the first 3 times I did it...

check my application on tablet with server runs in the network

hi frnds i installed my application on my tablet. which use some web services of my server application. my tablet and PC is connected in same network.
my pc has ip address : 192.168.1.1
and my tablet has ip ; 192.168.1.6
my server application is running. but i cant connect with my server
and my server running in jBoss not in tomcat.
when i run localhost:8080.. in browser it open the jboss community page but when i give <1p address>:8080 it doesn't open the jboss community page
my Log cat :
05-29 09:38:08.045: W/System.err(334): org.apache.http.conn.HttpHostConnectException: Connection to http://192.168.1.1:8080 refused
05-29 09:38:08.081: W/System.err(334): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:178)
05-29 09:38:08.081: W/System.err(334): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
05-29 09:38:08.081: W/System.err(334): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
05-29 09:38:08.081: W/System.err(334): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
05-29 09:38:08.081: W/System.err(334): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
05-29 09:38:08.081: W/System.err(334): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
05-29 09:38:08.081: W/System.err(334): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
You must be using this command to run your server
D:\jboss-5.0.0.CR2\bin>run.bat
But this will only run on localhost not on network.So try this code to run your server
D:\jboss-5.0.0.CR2\bin>run.bat -b 0.0.0.0
And then try using IP Address.I think this will solve your problem.

Use of URLConnection on Samsung Galaxy s2

I am using an instance of URLConnection to download pictures from a web server. This works well on most phones.
I used http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/ as inspiration for doing parallel downloads.
I call both setConnectTimeout(timeout) and setReadTimeout(timeout) so that I can recover from timeouts as I start a number of threads which fetch images in parallel.
On the Samsung Galaxy s2 phone the timeouts are ignored and some of the threads downloading hang for several minutes before an exception is thrown and the download is retried - the download succeeds second time around.
An exception which is thrown looks like this:
DownloadTask, network timeout (attempt #0)
java.net.SocketTimeoutException: failed to connect to host (port 80) after 1000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:150)
libcore.io.IoBridge.connect(IoBridge.java:112)
java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
java.net.Socket.connect(Socket.java:842)
libcore.net.http.HttpConnection.<init>(HttpConnection.java:77)
libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
libcore.net.http.HttpEngine.connect(HttpEngine.java:303)
libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
..
Is this known broken behavior on Samsung Galaxy s2?
Android version: 4.0.4.

Categories

Resources