Android Question Doing offline self signed TLS/SSL

Timm

Member
Please I have been stuck for some days doing offline self signed cert in B4A with chatgpt, since I could not get such a code in the forum. Can anybody with such knowledge help with simple code that does that.
E.g https://192.168.43.244:5000/login
I will be connecting this to flask backend.

If __name__ == "__main__":
app.run(host="0.0.0.0", port=4433, ssl_context=("server.crt", "server.key"))

Thank you.
 

Timm

Member
Thank you for response. But am doing production grade offline b4a app to flask(SQLite) on rpi. What I want is self signed cert with keystore as you explain in

[B4X] Client certificates with OkHttpUtils2 SSLContext-Kickstart. Here you said the code you gave work well when the instructions is followed.​

What I have are:
server.pem or crt
server.key both for offline flask server
keystore.pfk converted to keystore.pkcs12 added to b4A file manager.
My challenge now is how do I call Sub SetSslFactory (.......) code attached in my
Job.PostString("https://192.168.43.244:4433/api/login", json). How do they go together for sail through handshake. Can somebody please explain or put me through.



Self signed SSL validation:
'

Press Ctrl + B and add HU2_PUBLIC as a conditional symbol!
Private Sub SetSSLFactory (StoreDir As String, StoreFile As String, StorePassword As String)
    Dim hc As OkHttpClient = HttpUtils2Service.hc
    Dim builder As JavaObject = hc.As(JavaObject).RunMethod("sharedInit", Array("hc"))
    Dim sslfactoryBuilder As JavaObject
    sslfactoryBuilder = sslfactoryBuilder.InitializeStatic("nl.altindag.sslcontext.SSLFactory").RunMethod("builder", Null)
    Dim in As InputStream = File.OpenInput(StoreDir, StoreFile)
    Dim keystore As JavaObject
    keystore.InitializeStatic("java.security.KeyStore")
    Dim password As Object = StorePassword.As(JavaObject).RunMethod("toCharArray", Null) 'ignore
    Dim store As JavaObject = keystore.RunMethodJO("getInstance", Array("pkcs12"))
    store.RunMethod("load", Array(in, password)) 'ignore
 
    sslfactoryBuilder.RunMethod("withIdentityMaterial", Array(store, password))
    sslfactoryBuilder.RunMethod("withTrustMaterial", Array(store, password))
    'uncomment if need to disable http 2.
'    Dim protocol As JavaObject
'    protocol = protocol.InitializeStatic("okhttp3.Protocol").RunMethod("valueOf", Array("HTTP_1_1"))
'    Dim protocols As List = Array(protocol)
'    builder.RunMethod("protocols", Array(protocols))
 
    Dim sslfactory As JavaObject = sslfactoryBuilder.RunMethod("build", Null)
    Dim socketfactory As JavaObject = sslfactory.RunMethodJO("getSslContext", Null).RunMethod("getSocketFactory", Null)
    Dim trustmanager As JavaObject = sslfactory.RunMethodJO("getTrustManager", Null)
    builder.RunMethod("sslSocketFactory", Array(socketfactory, trustmanager.RunMethod("get", Null)))
    builder.RunMethod("hostnameVerifier", Array(sslfactory.RunMethod("getHostnameVerifier", Null)))
    hc.As(JavaObject).SetField("client", builder.RunMethod("build", Null))
End Sub
 
Upvote 0

Timm

Member
Am sorry about the duplicate post.
Dim hc As OkHttpClient = HttpUtils2Service.hc ---- this line saying hc is not a member
 
Upvote 0

Timm

Member
Thank you for you response. Am having this issue:

Cannot get methods of class: nl.altindag.sslcontext.SSLFactory$Builder, disabling cache.
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/nio/file/Path;
at java.lang.Class.getDeclaredMethodInternal(Native Method)
at java.lang.Class.getPublicMethodRecursive(Class.java:1988)
at java.lang.Class.getMethod(Class.java:1976)
at java.lang.Class.getMethod(Class.java:1637)
at anywheresoftware.b4j.object.JavaObject$MethodCache.getMethod(JavaObject.java:346)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:120)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:5638)
at android.view.View$PerformClick.run(View.java:22430)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6176)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:893)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.nio.file.Path" on path: DexPathList[[zip file "/data/app/b4a.example-2/base.apk"],nativeLibraryDirectories=[/data/app/b4a.example-2/lib/x86_64, /system/lib64, /vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
 
Upvote 0

Timm

Member
Thank you and thank you for your time. I have spent more than five days looking for solution, but wow, with your instructions Custom SSL applied successfully when I didn't use emulator and my token from flask server worked now
 
Upvote 0

Timm

Member
Thank you for the help I have received so far.
I have read wide on the b4x forum to look for working mqtt handshake b4a/b4j code without error using ca.crt, client.crt, client.key and username/password but to no available. Since I must use the above certificate parameters.
Can anybody who is familiar with above, help me to convert the below trustall certificate to a working ca/client/password code or if there is anyway to get me going. Thank you

Doing mqtt with ssl handshake:
    Dim mo As MqttConnectOptions
   mo.Initialize("aa", "bb")
   Dim jo As JavaObject = mo
   jo.RunMethod("setSocketFactory", Array(CreateTrustAllSSLSocketFactory))
 'Use Mqtt.Connect2(mo)

Sub CreateTrustAllSSLSocketFactory As Object
   Dim tm As CustomTrustManager
   tm.InitializeAcceptAll
   Dim SSLContext As JavaObject
   SSLContext = SSLContext.InitializeStatic("javax.net.ssl.SSLContext").RunMethod("getInstance", Array("TLS"))
   SSLContext.RunMethod("init", Array(Null, tm, Null))
   Dim Factory As JavaObject = SSLContext.RunMethod("getSocketFactory", Null)
   Return Factory
End Sub
 
Upvote 0

Timm

Member
My question is centers on self signed certificate using mosquito.conf/broker, hence I must present the client certificate from b4a/b4j clients code.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

Timm

Member
Thank you for your response.This is another question entirely, I have resolved the server/client SSL/TLS(b4a app and flask server) issue I was having before as indicated above.

What I mean is this: mosquito broker/client SSL/TLS implementation

Mosquito.conf inside mosquito broker have this:
listener 8883
cafile /path/to/ca.crt
certfile /path/to/server.crt
keyfile /path/to/server.key
require_certificate true
tls_version tlsv1.2
allow_anonymous false
password_file /path/to/passfile

Hence, my b4a/b4j mqtt client must present it's client.crt, client.key and username/password for error free connection to the mosquito broker.
This is the part of the code am seeking help for since trustall certificate code does not work here, throwing certificate required error.
 
Upvote 0

Timm

Member
the below b4j code is working perfectly connecting to mosquitto broker
according to question in context.
b4j trust with cert:
Sub TrustWithCerts(mo As MqttConnectOptions)

    ' Paths in Files folder
'    Dim p12File As String = File.Combine(File.DirAssets, "client.p12")
    Dim p12File As String = "C:\Users\Timm\Documents\B4X\jMQTTstrange\MQTTstrange\Files\client.p12"
'    Dim caFile As String = File.Combine(File.DirAssets, "ca.crt")
    Dim caFile As String = "C:\Users\Timm\Documents\B4X\jMQTTstrange\MQTTstrange\Files\ca.crt"
    Dim p12Password As String = "xxxxxxx" ' password used when exporting client.p12

    Dim jc As JavaObject
    jc.InitializeStatic("java.security.KeyStore")
    .
    .
    .
    .
    pwdJO.InitializeNewInstance("java.lang.String", Array(p12Password))
    Dim pwdCharArray As JavaObject = pwdJO.RunMethod("toCharArray", Null)

    ' Load client PKCS12 keystore
    Dim keyStore As JavaObject = jc.RunMethod("getInstance", Array("PKCS12"))
    Dim fis As JavaObject
    fis.InitializeNewInstance("java.io.FileInputStream", Array(p12File))
    keyStore.RunMethod("load", Array(fis, pwdCharArray))
    fis.RunMethod("close", Null)


    ' Load empty trustStore for CA certs
    Dim trustStore As JavaObject = jc.RunMethod("getInstance", Array("JKS"))
    trustStore.RunMethod("load", Array(Null, Null))
    .
    .
    .

but when i try to adapt the working b4j code to b4a as seen below, is throwing
underneth error:
b4a trust with cert:
Sub TrustWithCerts(mo As MqttConnectOptions)

    ' Paths in Files folder
'    Dim p12File As String = File.Combine(File.DirAssets, "client.p12")
    Dim p12File As String = "C:\Users\Timm\Documents\B4X\jMQTTstrange\MQTTstrange\Files\client.p12"
'    Dim caFile As String = File.Combine(File.DirAssets, "ca.crt")
    Dim caFile As String = "C:\Users\Timm\Documents\B4X\jMQTTstrange\MQTTstrange\Files\ca.crt"
    Dim p12Password As String = "xxxxxxx" ' password used when exporting client.p12

    Dim jc As JavaObject
    jc.InitializeStatic("java.security.KeyStore")
    .
    .
    .
    .
    pwdJO.InitializeNewInstance("java.lang.String", Array(p12Password))
    Dim pwdCharArray As JavaObject = pwdJO.RunMethod("toCharArray", Null)

    ' Load client PKCS12 keystore
    Dim keyStore As JavaObject = jc.RunMethod("getInstance", Array("PKCS12"))
    Dim fis As JavaObject
    fis.InitializeNewInstance("java.io.FileInputStream", Array(p12File))
    keyStore.RunMethod("load", Array(fis, pwdCharArray))
    fis.RunMethod("close", Null)


    ' Load empty trustStore for CA certs
    Dim trustStore As JavaObject = jc.RunMethod("getInstance", Array("JKS"))
    trustStore.RunMethod("load", Array(Null, Null))
    .
    .
    .


but when i try to adapt the working b4j code to b4a as seen below, is throwing
underneth error:

Sub TrustWithCerts(mo As MqttConnectOptions)
    ' Use absolute paths in B4A (adjust to your real file paths)
'    Dim p12File As String = File.(File.DirAssets, "client.p12") ' <-- Your actual full path here
    Dim p12File As String = CopyAssetToInternalStorage("client.p12")  'or "client.jks"
    Dim caFile As String = CopyAssetToInternalStorage("ca.crt")
    Dim p12Password As String = "1234qwerty"
    .
    .
    .
    .
    .
    ' Prepare password char array
    Dim jcString As JavaObject
    jcString.InitializeStatic("java.lang.String")
    Dim pwdJO As JavaObject
    pwdJO.InitializeNewInstance("java.lang.String", Array(p12Password))
    Dim pwdCharArray As JavaObject = pwdJO.RunMethod("toCharArray", Null)

    ' Load client PKCS12 keystore
    Dim keyStore As JavaObject = jc.RunMethod("getInstance", Array("PKCS12"))
    Dim fis As JavaObject
    fis.InitializeNewInstance("java.io.FileInputStream", Array(p12File))
    keyStore.RunMethod("load", Array(fis, pwdCharArray))
    fis.RunMethod("close", Null)

    ' Load empty trustStore for CA certs
    Dim trustStore As JavaObject = jc.RunMethod("getInstance", Array("JKS"))
    trustStore.RunMethod("load", Array(Null, Null))
    .
    .
    .


    Sub CopyAssetToInternalStorage(FileName As String) As String
        Dim target As String = File.Combine(File.DirInternal, FileName)
        If File.Exists(File.DirInternal, FileName) = False Then
            File.Copy(File.DirAssets, FileName, File.DirInternal, FileName)
        End If
        Return target ' full path for JavaObject
    End Sub



am having this error pointing to this line:
Dim trustStore As JavaObject = jc.RunMethod("getInstance", Array("JKS"))
can somebody help me out.
error:
Error occurred on line: 333 (MQTTManager)
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.keywords.Common.CallSubDebug2(Common.java:1087)
at com.homeproject.chrikinex.b4xpagesmanager._createpageifneeded(b4xpagesmanager.java:1071)
at com.homeproject.chrikinex.b4xpagesmanager._showpage(b4xpagesmanager.java:428)
at com.homeproject.chrikinex.b4xpagesmanager._addpage(b4xpagesmanager.java:248)
at com.homeproject.chrikinex.b4xpagesmanager._addpageandcreate(b4xpagesmanager.java:262)
at com.homeproject.chrikinex.b4xpagesmanager._initialize(b4xpagesmanager.java:168)
at com.homeproject.chrikinex.main._activity_create(main.java:444)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
at com.homeproject.chrikinex.main.afterFirstLayout(main.java:105)
at com.homeproject.chrikinex.main.access$000(main.java:17)
at com.homeproject.chrikinex.main$WaitForLayout.run(main.java:83)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8500)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:640)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1026)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:336)
at anywheresoftware.b4a.debug.Debug.CallSubNew2(Debug.java:285)
... 25 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:318)
... 26 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:132)
at com.homeproject.chrikinex.mqttmanager._trustwithcerts(mqttmanager.java:322)
at com.homeproject.chrikinex.mqttmanager._connectnow(mqttmanager.java:240)
at com.homeproject.chrikinex.mqttmanager._initialize(mqttmanager.java:100)
at com.homeproject.chrikinex.b4xmainpage$ResumableSub_B4XPage_Created.resume(b4xmainpage.java:163)
at com.homeproject.chrikinex.b4xmainpage._b4xpage_created(b4xmainpage.java:85)
... 28 more
Caused by: java.security.KeyStoreException: JKS not found
at java.security.KeyStore.getInstance(KeyStore.java:904)
... 35 more
Caused by: java.security.NoSuchAlgorithmException: JKS KeyStore not available
at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
at java.security.Security.getImpl(Security.java:628)
at java.security.KeyStore.getInstance(KeyStore.java:901)
... 35 more
** Activity (main) Resume **
 
Upvote 0
Top