Android Question Android 4 and SSL Problem

Status
Not open for further replies.

mw71

Active Member
Licensed User
hi

i download a file with this Code


B4X:
Sub Process_Globals
    Dim hl As OkHttpClient
End Sub

Sub Service_Create
    hl.InitializeAcceptAll("hl")
End Sub

Public Sub StartDownload
Dim req As OkHttpRequest
req.InitializeGet(GPX_Target)
hl.Execute(req,1)   
end sub

hl_Response.......

on "New" Device (Android 5?) it works Fine
on older Device (Android 4.x.x) i get en error wirh the SSL:
javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x65a77d40: Failure in SSL library, usually a protocol error
error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version (external/openssl/ssl/s23_clnt.c:741 0x41d0f77a:0x00000000)
 

Semen Matusovskiy

Well-Known Member
Licensed User
1) Include Google Play services

a) In manifest
B4X:
'    required manifest entry required for Google Play Services
AddApplicationText (<meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />)
b) In main Activity
B4X:
#AdditionalJar: com.google.android.gms:play-services-base)

2. Update Google Play Services on your phone (this is very important)

3. In Starter service
a) call ActivateSSL inside Service_Create
b) add following subroutines (de-facto, written by Erel):

B4X:
Sub ActivateSSL

    Dim javaobjectContext                                                       As JavaObject
    Dim javaobjectInstance                                                      As JavaObject
    Dim objectListener                                                          As Object
    Dim phoneInstance                                                           As Phone

    Try
        Select Case phoneInstance.SdkVersion
            Case 16, 17, 18, 19, 20 ' Android 4.1 - 4.4
            Case Else
                Return
        End Select
        javaobjectInstance.InitializeStatic ("com.google.android.gms.security.ProviderInstaller")
        javaobjectContext.InitializeContext
        DisableStrictMode
        objectListener = javaobjectInstance.CreateEventFromUI ("com.google.android.gms.security.ProviderInstaller.ProviderInstallListener", "objectListener", Null)
        javaobjectInstance.RunMethod ("installIfNeededAsync", Array (javaobjectContext, objectListener))
        Wait For objectListener_Event (stringMethodName As String, objectArguments () As Object)
        ' If stringMethodName = "onProviderInstalled" Then [ Provider installed successfully ] Else [ Error installing provider (objectArguments (0)) ]
    Catch
    End Try

End Sub

Sub DisableStrictMode

    Dim javaobjectInstance                                                      As JavaObject
    Dim javaobjectPolicy                                                        As JavaObject
    Dim javaobjectStrictMode                                                    As JavaObject

    Try
        javaobjectInstance.InitializeStatic ("android.os.Build.VERSION")
        If javaobjectInstance.GetField ("SDK_INT") > 9 Then
            javaobjectPolicy = javaobjectPolicy.InitializeNewInstance ("android.os.StrictMode.ThreadPolicy.Builder", Null)
            javaobjectPolicy = javaobjectPolicy.RunMethodJO ("permitAll", Null). RunMethodJO ("build", Null)
            javaobjectStrictMode.InitializeStatic ("android.os.StrictMode"). RunMethod ("setThreadPolicy", Array (javaobjectPolicy))
        End If
    Catch
    End Try

End Sub
 
Last edited:
Upvote 0

Rubsanpe

Active Member
Licensed User
1) Include Google Play services

a) In manifest
B4X:
'    required manifest entry required for Google Play Services
AddApplicationText (<meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />)
b) In main Activity
B4X:
#AdditionalJar: com.google.android.gms:play-services-base)

2. Update Google Play Services on your phone (this is very important)

3. In Starter service
a) call ActivateSSL inside Service_Create
b) add following subroutines (de-facto, written by Erel):

B4X:
Sub ActivateSSL

    Dim javaobjectContext                                                       As JavaObject
    Dim javaobjectInstance                                                      As JavaObject
    Dim objectListener                                                          As Object
    Dim phoneInstance                                                           As Phone

    Try
        Select Case phoneInstance.SdkVersion
            Case 16, 17, 18, 19, 20 ' Android 4.1 - 4.4
            Case Else
                Return
        End Select
        javaobjectInstance.InitializeStatic ("com.google.android.gms.security.ProviderInstaller")
        javaobjectContext.InitializeContext
        DisableStrictMode
        objectListener = javaobjectInstance.CreateEventFromUI ("com.google.android.gms.security.ProviderInstaller.ProviderInstallListener", "objectListener", Null)
        javaobjectInstance.RunMethod ("installIfNeededAsync", Array (javaobjectContext, objectListener))
        Wait For objectListener_Event (stringMethodName As String, objectArguments () As Object)
        ' If stringMethodName = "onProviderInstalled" Then [ Provider installed successfully ] Else [ Error installing provider (objectArguments (0)) ]
    Catch
    End Try

End Sub

Sub DisableStrictMode

    Dim javaobjectInstance                                                      As JavaObject
    Dim javaobjectPolicy                                                        As JavaObject
    Dim javaobjectStrictMode                                                    As JavaObject

    Try
        javaobjectInstance.InitializeStatic ("android.os.Build.VERSION")
        If javaobjectInstance.GetField ("SDK_INT") > 9 Then
            javaobjectPolicy = javaobjectPolicy.InitializeNewInstance ("android.os.StrictMode.ThreadPolicy.Builder", Null)
            javaobjectPolicy = javaobjectPolicy.RunMethodJO ("permitAll", Null). RunMethodJO ("build", Null)
            javaobjectStrictMode.InitializeStatic ("android.os.StrictMode"). RunMethod ("setThreadPolicy", Array (javaobjectPolicy))
        End If
    Catch
    End Try

End Sub

Thank you, with this solution I have corrected the problem with 4.x devices.

Greetings


Ruben
 
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
This code does absolutelly nothing under Android 8. So it can't "not work".

Take a look this fragment.
B4X:
Select Case phoneInstance.SdkVersion
            Case 16, 17, 18, 19, 20 ' Android 4.1 - 4.4
            Case Else
                Return
        End Select
Meanwhile according my experiments it's possible to call Google provider under Android 5+ also. So you can replace this fragment to
B4X:
If phoneInstance.SdkVersion < 16 Then Return
 
Upvote 0

udg

Expert
Licensed User
Hi Semen,

I'm experiencing a very similar error (so it may be unuseful to start a new thread). The error seems to relate to SSL v.3:

ResponseError. Reason: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x78dc9170: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x73a3c830:0x00000000), Response:
javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x78dc9170: Failure in SSL library, usually a protocol error

Would the solution in post #2 above cover this case too? Is this link correct about the explanation (see the UPDATE section in the answer, please)?

TIA
 
Upvote 0

OliverA

Expert
Licensed User
Would the solution in post #2 above cover this case too?
I don't think so. The solution posted in post #2 (and the link you provide) is to enable newer protocols on older devices. In your case, you are attempting to connect to a site that uses an older protocol (sslv3) that your device refuses to connect to. Therefore, if you absolutely need to connect to that site, you need to find a way to enable your device to connect to an older protocol. If you do happen to make that change, then please only allow it for that site, since there is a reason that older protocols are blocked from working out of the gate on newer devices.

Update: That may have been a dumb answer, since you never mentioned what version of Android you are using. As of Oreo, Android should be blocking sslv3 (see https://www.thesslstore.com/blog/android-8-0-oreo-drops-support-sslv3/).
 
Last edited:
Upvote 0

udg

Expert
Licensed User
Thanks Oliver.
The site we're talking about is under my full control (VPS, CentOS 7). I use a Let's Encrypt certificate in conjunction with a B4J's JServer-based program to which I use to PostBytes or JSON strings. The sending device is an Android 4.4.2 smartphone.
An Android 7.0 device works ok.

So, if I understand correctly your post, I've to somewhat upgrade my server (OS, Jetty, certificate?). Any hint about what I should look for to begin with? Thanks again.
 
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
Even cheapest certificates ($3-4/per year) support TLS 1.3 and less. I'd recommend to look, what talks https://www.ssllabs.com/ssltest/index.html about your site.

In Android 4, as I read, the default protocol was exactly SSL v3 (which many IT turn off like insecure). Google Services fixed this problem, but it was relative to old devices.
I don't think that Google Services will be useful in Android 8. Since Android 5 the default protocol is TLS 1.1/1.2.
 
Upvote 0

OliverA

Expert
Licensed User
So, if I understand correctly your post, I've to somewhat upgrade my server (OS, Jetty, certificate?). Any hint about what I should look for to begin with? Thanks again.
In your case (since you are using 4.4.2), the issue is the same as the original poster of this thread. Updating the Google play services on the older device should do the trick. If this thread alone does not help, there are several more on this forum. For later devices (8 and up) your site will be inaccessible if it does not provide a different means of security. BTW, ninja'd by @Semen Matusovskiy.
 
Upvote 0

udg

Expert
Licensed User
For later devices (8 and up) your site will be inaccessible if it does not provide a different means of security
I used Let's Encript but I don't have to. If the problem arises from that it's kind of no problem.
What sounds strange anyway is that an older device doesn't connect to a "risky" protocol while a newer one shows no problem. Shouldn't it be just the opposite?
BTW, using a B4J app running on my PC it connects flawalessly too.

ps: I tried the sslabs test. First row (IP6 I guess) reports a grade T while second one shows no result. There's a message though : Inconsistent server configuration (whatever it could mean).
pps: there's nothing listening on ports 80 and 443. I use my own dedicated ports for both http and https.

https://www.b4x.com/android/forum/threads/jserver-v2-80-enabling-tlsv1-1.81704/#content
explains how to reactivate TLS 1.1 for jetty. I'd rather avoid it, but if it could be a temporary solution just to have this specific 4.4 device working for a few days, I could accept it.
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
I used Let's Encript but I don't have to. If the problem arises from that it's kind of no problem.
It's not. Looks like Jetty is allowing SSLv3 connections. If you are setting up jServer's SSL via ConfigureSSL found here (https://www.b4x.com/android/forum/threads/server-ssl-connections.40130/#content), then try adding the following code before the call to srvr.SetSslConfiguration.
B4X:
Dim jo As JavaObject = ssl
jo.RunMethod("addExcludedProtocols", Array(Array As String("SSLv3")))
Note: Code not tested
Sources used:
https://stackoverflow.com/a/26388531
https://www.b4x.com/android/forum/threads/jserver-v2-80-enabling-tlsv1-1.81704/
 
Upvote 0

OliverA

Expert
Licensed User
I'd rather avoid it, but if it could be a temporary solution just to have this specific 4.4 device working for a few days, I could accept it.
You have two options: 1) Upgrade Google play services on device as mentioned here and on other threads in this forum or 2) downgrade the security on your server.
 
Upvote 0

udg

Expert
Licensed User
Thanks to all.
I'm a bit confused so, please, help me better understand the topic along with the suggested code snippets.

1) Jetty and JServer.
Does it need the snippet in post #12 to be made more secure excluding SSLv3 protocol from what appear to be its current default?
Should I think that it was kept for backward compatibility but sooner or later that protocol, will be removed anyway?

2) Device Android 4.4.2
Tried Erel's code but that leads to error "Error installing provider: 2"
The device currently doesn't allow an upgrade of Google Play Services (maybe it's just a matter of time since I started a factory rebuild yesterday)

3) Device Android 7.0
How can I verify that it's using TLS 2.1 or anything "secure" rather than the old SSLv3?

My goal is obviously an as secure setup as possible. So only the strongest protocols at the server and any good measure to let devices to login and use https instead of http (being it JSON of packets of bytes). If that means the old or very old devices would be out of game that's ok (after all they weren't designed or buoilt to work forever..).

Update: updating GMail, that in turns got the update of Google Play Services and Erel's code worked as expected. No changes done at the server.
 
Last edited:
Upvote 0

udg

Expert
Licensed User
Ok, Erel.
So I take this as a confirmation that no specific action is to be taken at the server level (in my case), in particular that I don't need to apply the snippet at post #12 above since the old protocol is already disabled.

Meanwhile, updating GMail it caused Google Play Services to update itself and now your code leads to a successful https connection and data exchange on my old Android 4.4.2 device.

Let me thank you, Oliver and Semen for your comments, hints and help.
 
Upvote 0
Status
Not open for further replies.
Top