Kotlinify `StatusOkHttpClientFactory.java` (#18318)
This commit converts `android/app/src/main/java/im/status/ethereum/StatusOkHttpClientFactory.java` to `android/app/src/main/java/im/status/ethereum/StatusOkHttpClientFactory.kt`
This commit is contained in:
parent
7af62c04eb
commit
d495bb6b57
|
@ -0,0 +1,88 @@
|
||||||
|
package im.status.ethereum
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import com.facebook.react.modules.network.OkHttpClientFactory
|
||||||
|
import com.facebook.react.modules.network.OkHttpClientProvider
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.tls.HandshakeCertificates
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.lang.RuntimeException
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
import java.security.cert.CertificateFactory
|
||||||
|
import java.security.cert.X509Certificate
|
||||||
|
import im.status.ethereum.module.StatusPackage
|
||||||
|
|
||||||
|
class StatusOkHttpClientFactory : OkHttpClientFactory {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "StatusOkHttpClientFactory"
|
||||||
|
private const val SLEEP_DURATION = 500L // milliseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createNewNetworkModuleClient(): OkHttpClient? {
|
||||||
|
val certPem = getCertificatePem().takeIf { it.isNotEmpty() }
|
||||||
|
?: return logAndReturnNull("Certificate is empty, cannot create OkHttpClient without a valid certificate")
|
||||||
|
|
||||||
|
val cert = try {
|
||||||
|
induceSleep()
|
||||||
|
// Convert PEM certificate string to X509Certificate object
|
||||||
|
CertificateFactory.getInstance("X.509")
|
||||||
|
.generateCertificate(ByteArrayInputStream(certPem.toByteArray())) as? X509Certificate
|
||||||
|
?: return logAndReturnNull("Certificate could not be parsed as non-null")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return logAndReturnNull("Could not parse certificate", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
val clientCertificates = try {
|
||||||
|
induceSleep()
|
||||||
|
// Create HandshakeCertificates object with our certificate
|
||||||
|
HandshakeCertificates.Builder()
|
||||||
|
.addPlatformTrustedCertificates()
|
||||||
|
.addTrustedCertificate(cert)
|
||||||
|
.build()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return logAndReturnNull("Could not build HandshakeCertificates", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return try {
|
||||||
|
OkHttpClientProvider.createClientBuilder()
|
||||||
|
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
||||||
|
.build()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logAndReturnNull("Could not create OkHttpClient", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getCertificatePem(): String {
|
||||||
|
return try {
|
||||||
|
// Create OkHttpClient with custom SSL socket factory and trust manager
|
||||||
|
StatusPackage.getImageTLSCert().takeIf { !it.isNullOrBlank() }
|
||||||
|
?: logAndReturnEmpty("Certificate PEM string is null or empty")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logAndReturnEmpty("Could not getImageTLSCert", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun induceSleep() {
|
||||||
|
try {
|
||||||
|
// induce half second sleep because sometimes a cert is not immediately available
|
||||||
|
// TODO : remove sleep if App no longer crashes on Android 10 devices with
|
||||||
|
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||||
|
Thread.sleep(SLEEP_DURATION)
|
||||||
|
} catch (e: InterruptedException) {
|
||||||
|
Log.e(TAG, "Sleep interrupted", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logAndReturnNull(message: String, e: Exception? = null): Nothing? {
|
||||||
|
Log.e(TAG, message, e)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logAndReturnEmpty(message: String, e: Exception? = null): String {
|
||||||
|
Log.e(TAG, message, e)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
package im.status.ethereum;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.facebook.react.modules.network.OkHttpClientFactory;
|
|
||||||
import com.facebook.react.modules.network.OkHttpClientProvider;
|
|
||||||
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.Interceptor;
|
|
||||||
import okhttp3.tls.HandshakeCertificates;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.RuntimeException;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.security.cert.CertificateFactory;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
|
|
||||||
import im.status.ethereum.module.StatusPackage;
|
|
||||||
|
|
||||||
class StatusOkHttpClientFactory implements OkHttpClientFactory {
|
|
||||||
|
|
||||||
private static final String TAG = "StatusOkHttpClientFactory";
|
|
||||||
|
|
||||||
public OkHttpClient createNewNetworkModuleClient() {
|
|
||||||
X509Certificate cert = null;
|
|
||||||
HandshakeCertificates clientCertificates;
|
|
||||||
String certPem = "";
|
|
||||||
// Get TLS PEM certificate from status-go
|
|
||||||
try {
|
|
||||||
// induce half second sleep because sometimes a cert is not immediately available
|
|
||||||
// TODO : remove sleep if App no longer crashes on Android 10 devices with
|
|
||||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
|
||||||
Thread.sleep(500);
|
|
||||||
certPem = getCertificatePem();
|
|
||||||
} catch(Exception e) {
|
|
||||||
Log.e(TAG, "Could not getImageTLSCert",e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (certPem.isEmpty()) {
|
|
||||||
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert PEM certificate string to X509Certificate object
|
|
||||||
try {
|
|
||||||
// induce half second sleep because sometimes a cert is not immediately available
|
|
||||||
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
|
||||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
|
||||||
Thread.sleep(500);
|
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
|
||||||
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certPem.getBytes()));
|
|
||||||
} catch(Exception e) {
|
|
||||||
Log.e(TAG, "Could not parse certificate",e);
|
|
||||||
}
|
|
||||||
// Create HandshakeCertificates object with our certificate
|
|
||||||
try {
|
|
||||||
// induce half second sleep because sometimes a cert is not immediately available
|
|
||||||
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
|
||||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
|
||||||
Thread.sleep(500);
|
|
||||||
clientCertificates = new HandshakeCertificates.Builder()
|
|
||||||
.addPlatformTrustedCertificates()
|
|
||||||
.addTrustedCertificate(cert)
|
|
||||||
.build();
|
|
||||||
} catch(Exception e) {
|
|
||||||
Log.e(TAG, "Could not build HandshakeCertificates", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create OkHttpClient with custom SSL socket factory and trust manager
|
|
||||||
try {
|
|
||||||
return OkHttpClientProvider.createClientBuilder()
|
|
||||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
|
|
||||||
.build();
|
|
||||||
} catch(Exception e) {
|
|
||||||
Log.e(TAG, "Could not create OkHttpClient", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private String getCertificatePem() {
|
|
||||||
try {
|
|
||||||
String certPem = StatusPackage.getImageTLSCert();
|
|
||||||
if (certPem == null || certPem.trim().isEmpty()) {
|
|
||||||
Log.e(TAG, "Certificate PEM string is null or empty");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return certPem;
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Could not getImageTLSCert", e);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue