B4J Question [SOLVED] Client certificates with OkHttpUtils2 SSLContext-Kickstart - untrusted certificate

rosippc64a

Active Member
Licensed User
Longtime User
Hi All,
I have to connect to a webpage and send some json text. I got a cert file and I have a key file too. This webpage hasn't a login/password method, only the certificate.
The certificate is installed in windows and I can see, that it works. I can use a postman program what can use the same certification, so I think it is good.
I tried Erel's SSLContext - Kickstart example program with mentioned certification, but I can't connect to webpage. I got error message:
B4X:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: None of the TrustManagers trust this certificate chain
In the next code there are a lot of trial and error lines, but no solution yet.
Of course I converted the certificate into pfx and jks too, written in example.
B4X:
    PUBLIC_KEY = File.ReadString(File.DirAssets,"cert.key").Replace(Chr(13),"").Replace(Chr(10),"")
    PRIVATE_KEY = File.ReadString(File.DirAssets,"cert.cer").Replace(Chr(13),"").Replace(Chr(10),"")
    Dim basicAuth As String
    basicAuth = $"${PUBLIC_KEY}:${PRIVATE_KEY}"$ '
    Dim job As HttpJob
    job.Initialize("",Me)
    SetSSLFactory(File.DirAssets,"clientcert.jks","rostasc3")
    job.PostString("https://rms.tesztntak.hu/rms/rendeles-osszesito",tj)
    'job.GetRequest.SetHeader("Authorization", $"Basic ${su.EncodeBase64(basicAuth.GetBytes("ascii"))}:"$)
    job.GetRequest.SetHeader("x-certificate", $"${su.EncodeBase64(basicAuth.GetBytes("ascii"))}:"$)
    'job.GetRequest.SetHeader("x-jws-signature", $"${su.EncodeBase64(PRIVATE_KEY.GetBytes("ASCII"))}:"$)
    job.GetRequest.SetContentType("application/json")
    Wait For (job) JobDone(job As HttpJob)
    Log("Result: " & job.Success)
    If job.Success Then
        Log(job.GetString)
        Dim parser As JSONParser
        parser.Initialize(job.GetString)
        Dim RootMap As Map = parser.NextObject
    Else
        Log(job.ErrorMessage)
    End If
    job.Release
My question is: how can I modify the program to accept this kind of certificate file?

thanks in advance
Steven
 

rosippc64a

Active Member
Licensed User
Longtime User
I could examine and compare my program and postman communication to webpage with wireshark.
Somewhere my original certification changed/lost in the process of converting pfx and jks.
13 5.341077 192.168.0.155 84.206.131.202 TLSv1.2 61 Alert (Level: Fatal, Description: Certificate Unknown)
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
Hi @Erel , thank you for your reply. I called SetSSLFactory in the 7 line at #1. Do I need to make it other mode (other line)?
 
Last edited:
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
I found the code snippet (not in my project) where I got an error. The exception detail:
B4X:
Caused by: java.security.cert.CertificateException: None of the TrustManagers trust this certificate chain
    at nl.altindag.sslcontext.trustmanager.CompositeX509ExtendedTrustManager.checkServerTrusted(CompositeX509ExtendedTrustManager.java:157)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
    ... 32 more
ResponseError. Reason: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: None of the TrustManagers trust this certificate chain, Response:
Result Token: false
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: None of the TrustManagers trust this certificate chain

Here is the code (from here:https://stackoverflow.com/questions/1793979/registering-multiple-keystores-in-jvm/16229909#16229909):
B4X:
  @Override
  public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    for (X509TrustManager trustManager : trustManagers) {
      try {
        trustManager.checkServerTrusted(chain, authType);
        return; // someone trusts them. success!
      } catch (CertificateException e) {
        // maybe someone else will trust them
      }
    }
    throw new CertificateException("None of the TrustManagers trust this certificate chain");
  }
Maybe the server certification is untrusted?
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
Can somehow switch off the ssl certificate verification in SetSSLFactory?
This certificate needs verification off in postman program (windows). So the cert is untrusted or so.
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
Ok, here is the solution to accept any untrusted certificate:

B4X:
'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
     'solution to accept untrusted cert:
    sslfactoryBuilder.RunMethod("withTrustingAllCertificatesWithoutValidation", Null)
    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
Top