mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
* Fixes #3320 * Added SSL certificate for commons beta * Asked OKHTTP client to use SSLContext from beta certificate * Probable Fix of #3345 * Use ConfigUtils to verify flavor
This commit is contained in:
parent
fe56cefdbc
commit
df426f7c42
4 changed files with 113 additions and 8 deletions
BIN
app/src/main/assets/*.wikimedia.beta.wmflabs.org.cer
Normal file
BIN
app/src/main/assets/*.wikimedia.beta.wmflabs.org.cer
Normal file
Binary file not shown.
|
|
@ -8,6 +8,8 @@ import org.wikipedia.dataclient.okhttp.HttpStatusException;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import fr.free.nrw.commons.di.SslUtils;
|
||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
|
@ -29,13 +31,17 @@ public final class OkHttpConnectionFactory {
|
|||
|
||||
@NonNull
|
||||
private static OkHttpClient createClient() {
|
||||
return new OkHttpClient.Builder()
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||
.cookieJar(SharedPreferenceCookieManager.getInstance())
|
||||
.cache(NET_CACHE)
|
||||
.addInterceptor(getLoggingInterceptor())
|
||||
.addInterceptor(new UnsuccessfulResponseInterceptor())
|
||||
.addInterceptor(new CommonHeaderRequestInterceptor())
|
||||
.build();
|
||||
.addInterceptor(new CommonHeaderRequestInterceptor());
|
||||
|
||||
if(ConfigUtils.isBetaFlavour()){
|
||||
builder.sslSocketFactory(SslUtils.INSTANCE.getSslContextForCertificateFile(CommonsApplication.getInstance(), "*.wikimedia.beta.wmflabs.org.cer").getSocketFactory());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static HttpLoggingInterceptor getLoggingInterceptor() {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
|
@ -31,6 +33,7 @@ import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
|||
import fr.free.nrw.commons.mwapi.UserInterface;
|
||||
import fr.free.nrw.commons.review.ReviewInterface;
|
||||
import fr.free.nrw.commons.upload.UploadInterface;
|
||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
||||
import fr.free.nrw.commons.wikidata.WikidataInterface;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.HttpUrl;
|
||||
|
|
@ -58,14 +61,20 @@ public class NetworkingModule {
|
|||
public OkHttpClient provideOkHttpClient(Context context,
|
||||
HttpLoggingInterceptor httpLoggingInterceptor) {
|
||||
File dir = new File(context.getCacheDir(), "okHttpCache");
|
||||
return new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
|
||||
.writeTimeout(60, TimeUnit.SECONDS)
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
|
||||
.writeTimeout(60, TimeUnit.SECONDS)
|
||||
.addInterceptor(httpLoggingInterceptor)
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
.cache(new Cache(dir, OK_HTTP_CACHE_SIZE))
|
||||
.build();
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
.cache(new Cache(dir, OK_HTTP_CACHE_SIZE));
|
||||
|
||||
if(ConfigUtils.isBetaFlavour()){
|
||||
builder.sslSocketFactory(SslUtils.INSTANCE.getSslContextForCertificateFile(context, "*.wikimedia.beta.wmflabs.org.cer").getSocketFactory());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public HttpLoggingInterceptor provideHttpLoggingInterceptor() {
|
||||
|
|
|
|||
90
app/src/main/java/fr/free/nrw/commons/di/SslUtils.kt
Normal file
90
app/src/main/java/fr/free/nrw/commons/di/SslUtils.kt
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
package fr.free.nrw.commons.di
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import java.security.KeyManagementException
|
||||
import java.security.KeyStore
|
||||
import java.security.NoSuchAlgorithmException
|
||||
import java.security.SecureRandom
|
||||
import java.security.cert.Certificate
|
||||
import java.security.cert.CertificateException
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.net.ssl.*
|
||||
|
||||
object SslUtils {
|
||||
|
||||
fun getSslContextForCertificateFile(context: Context, fileName: String): SSLContext {
|
||||
try {
|
||||
val keyStore = SslUtils.getKeyStore(context, fileName)
|
||||
val sslContext = SSLContext.getInstance("SSL")
|
||||
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
trustManagerFactory.init(keyStore)
|
||||
sslContext.init(null, trustManagerFactory.trustManagers, SecureRandom())
|
||||
return sslContext
|
||||
} catch (e: Exception) {
|
||||
val msg = "Error during creating SslContext for certificate from assets"
|
||||
e.printStackTrace()
|
||||
throw RuntimeException(msg)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getKeyStore(context: Context, fileName: String): KeyStore? {
|
||||
var keyStore: KeyStore? = null
|
||||
try {
|
||||
val assetManager = context.assets
|
||||
val cf = CertificateFactory.getInstance("X.509")
|
||||
val caInput = assetManager.open(fileName)
|
||||
val ca: Certificate
|
||||
try {
|
||||
ca = cf.generateCertificate(caInput)
|
||||
Log.d("SslUtilsAndroid", "ca=" + (ca as X509Certificate).subjectDN)
|
||||
} finally {
|
||||
caInput.close()
|
||||
}
|
||||
|
||||
val keyStoreType = KeyStore.getDefaultType()
|
||||
keyStore = KeyStore.getInstance(keyStoreType)
|
||||
keyStore!!.load(null, null)
|
||||
keyStore.setCertificateEntry("ca", ca)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return keyStore
|
||||
}
|
||||
|
||||
fun getTrustAllHostsSSLSocketFactory(): SSLSocketFactory? {
|
||||
try {
|
||||
// Create a trust manager that does not validate certificate chains
|
||||
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
|
||||
|
||||
override fun getAcceptedIssuers(): Array<X509Certificate> {
|
||||
return arrayOf()
|
||||
}
|
||||
|
||||
@Throws(CertificateException::class)
|
||||
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
|
||||
}
|
||||
|
||||
@Throws(CertificateException::class)
|
||||
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
|
||||
}
|
||||
})
|
||||
|
||||
// Install the all-trusting trust manager
|
||||
val sslContext = SSLContext.getInstance("SSL")
|
||||
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
|
||||
// Create an ssl socket factory with our all-trusting manager
|
||||
|
||||
return sslContext.socketFactory
|
||||
} catch (e: KeyManagementException) {
|
||||
e.printStackTrace()
|
||||
return null
|
||||
} catch (e: NoSuchAlgorithmException) {
|
||||
e.printStackTrace()
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue