Skip to content

Commit e511b8e

Browse files
* Added SSL certificate for commons beta * Asked OKHTTP client to use SSLContext from beta certificate * Probable Fix of commons-app#3345
1 parent fe56cef commit e511b8e

File tree

4 files changed

+111
-8
lines changed

4 files changed

+111
-8
lines changed
Binary file not shown.

app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.io.File;
99
import java.io.IOException;
1010

11+
import fr.free.nrw.commons.di.SslUtils;
1112
import okhttp3.Cache;
1213
import okhttp3.Interceptor;
1314
import okhttp3.OkHttpClient;
@@ -29,13 +30,17 @@ public final class OkHttpConnectionFactory {
2930

3031
@NonNull
3132
private static OkHttpClient createClient() {
32-
return new OkHttpClient.Builder()
33+
OkHttpClient.Builder builder = new OkHttpClient.Builder()
3334
.cookieJar(SharedPreferenceCookieManager.getInstance())
3435
.cache(NET_CACHE)
3536
.addInterceptor(getLoggingInterceptor())
3637
.addInterceptor(new UnsuccessfulResponseInterceptor())
37-
.addInterceptor(new CommonHeaderRequestInterceptor())
38-
.build();
38+
.addInterceptor(new CommonHeaderRequestInterceptor());
39+
40+
if(BuildConfig.FLAVOR.equals("beta")){
41+
builder.sslSocketFactory(SslUtils.INSTANCE.getSslContextForCertificateFile(CommonsApplication.getInstance(), "*.wikimedia.beta.wmflabs.org.cer").getSocketFactory());
42+
}
43+
return builder.build();
3944
}
4045

4146
private static HttpLoggingInterceptor getLoggingInterceptor() {

app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.java

+13-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import javax.inject.Named;
2020
import javax.inject.Singleton;
21+
import javax.net.ssl.SSLContext;
22+
import javax.net.ssl.SSLSocketFactory;
2123

2224
import dagger.Module;
2325
import dagger.Provides;
@@ -58,14 +60,20 @@ public class NetworkingModule {
5860
public OkHttpClient provideOkHttpClient(Context context,
5961
HttpLoggingInterceptor httpLoggingInterceptor) {
6062
File dir = new File(context.getCacheDir(), "okHttpCache");
61-
return new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
62-
.writeTimeout(60, TimeUnit.SECONDS)
63+
OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
64+
.writeTimeout(60, TimeUnit.SECONDS)
6365
.addInterceptor(httpLoggingInterceptor)
64-
.readTimeout(60, TimeUnit.SECONDS)
65-
.cache(new Cache(dir, OK_HTTP_CACHE_SIZE))
66-
.build();
66+
.readTimeout(60, TimeUnit.SECONDS)
67+
.cache(new Cache(dir, OK_HTTP_CACHE_SIZE));
68+
69+
if(BuildConfig.FLAVOR.equals("beta")){
70+
builder.sslSocketFactory(SslUtils.INSTANCE.getSslContextForCertificateFile(context, "*.wikimedia.beta.wmflabs.org.cer").getSocketFactory());
71+
}
72+
return builder.build();
6773
}
6874

75+
76+
6977
@Provides
7078
@Singleton
7179
public HttpLoggingInterceptor provideHttpLoggingInterceptor() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package fr.free.nrw.commons.di
2+
3+
import android.content.Context
4+
import android.util.Log
5+
import java.security.KeyManagementException
6+
import java.security.KeyStore
7+
import java.security.NoSuchAlgorithmException
8+
import java.security.SecureRandom
9+
import java.security.cert.Certificate
10+
import java.security.cert.CertificateException
11+
import java.security.cert.CertificateFactory
12+
import java.security.cert.X509Certificate
13+
import javax.net.ssl.*
14+
15+
object SslUtils {
16+
17+
fun getSslContextForCertificateFile(context: Context, fileName: String): SSLContext {
18+
try {
19+
val keyStore = SslUtils.getKeyStore(context, fileName)
20+
val sslContext = SSLContext.getInstance("SSL")
21+
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
22+
trustManagerFactory.init(keyStore)
23+
sslContext.init(null, trustManagerFactory.trustManagers, SecureRandom())
24+
return sslContext
25+
} catch (e: Exception) {
26+
val msg = "Error during creating SslContext for certificate from assets"
27+
e.printStackTrace()
28+
throw RuntimeException(msg)
29+
}
30+
}
31+
32+
private fun getKeyStore(context: Context, fileName: String): KeyStore? {
33+
var keyStore: KeyStore? = null
34+
try {
35+
val assetManager = context.assets
36+
val cf = CertificateFactory.getInstance("X.509")
37+
val caInput = assetManager.open(fileName)
38+
val ca: Certificate
39+
try {
40+
ca = cf.generateCertificate(caInput)
41+
Log.d("SslUtilsAndroid", "ca=" + (ca as X509Certificate).subjectDN)
42+
} finally {
43+
caInput.close()
44+
}
45+
46+
val keyStoreType = KeyStore.getDefaultType()
47+
keyStore = KeyStore.getInstance(keyStoreType)
48+
keyStore!!.load(null, null)
49+
keyStore.setCertificateEntry("ca", ca)
50+
} catch (e: Exception) {
51+
e.printStackTrace()
52+
}
53+
54+
return keyStore
55+
}
56+
57+
fun getTrustAllHostsSSLSocketFactory(): SSLSocketFactory? {
58+
try {
59+
// Create a trust manager that does not validate certificate chains
60+
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
61+
62+
override fun getAcceptedIssuers(): Array<X509Certificate> {
63+
return arrayOf()
64+
}
65+
66+
@Throws(CertificateException::class)
67+
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
68+
}
69+
70+
@Throws(CertificateException::class)
71+
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
72+
}
73+
})
74+
75+
// Install the all-trusting trust manager
76+
val sslContext = SSLContext.getInstance("SSL")
77+
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
78+
// Create an ssl socket factory with our all-trusting manager
79+
80+
return sslContext.socketFactory
81+
} catch (e: KeyManagementException) {
82+
e.printStackTrace()
83+
return null
84+
} catch (e: NoSuchAlgorithmException) {
85+
e.printStackTrace()
86+
return null
87+
}
88+
89+
}
90+
}

0 commit comments

Comments
 (0)