feat: ignore tls certificate #66

Merged
PeterCxy merged 4 commits from septs/OpenEUICC:ignore-tls-certificate into master 2024-11-17 03:43:40 +01:00
9 changed files with 69 additions and 10 deletions

View file

@ -42,7 +42,8 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
port,
context.preferenceRepository.verboseLoggingFlow
),
context.preferenceRepository.verboseLoggingFlow
context.preferenceRepository.verboseLoggingFlow,
context.preferenceRepository.ignoreTLSCertificateFlow,
).also {
Log.i(DefaultEuiccChannelManager.TAG, "Is OMAPI channel, setting MSS to 60")
it.lpa.setEs10xMss(60)
@ -72,7 +73,8 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
bulkOut,
context.preferenceRepository.verboseLoggingFlow
),
context.preferenceRepository.verboseLoggingFlow
context.preferenceRepository.verboseLoggingFlow,
context.preferenceRepository.ignoreTLSCertificateFlow,
)
}

View file

@ -11,14 +11,15 @@ class EuiccChannelImpl(
override val type: String,
override val port: UiccPortInfoCompat,
apduInterface: ApduInterface,
verboseLoggingFlow: Flow<Boolean>
verboseLoggingFlow: Flow<Boolean>,
ignoreTLSCertificateFlow: Flow<Boolean>
) : EuiccChannel {
override val slotId = port.card.physicalSlotIndex
override val logicalSlotId = port.logicalSlotIndex
override val portId = port.portIndex
override val lpa: LocalProfileAssistant =
LocalProfileAssistantImpl(apduInterface, HttpInterfaceImpl(verboseLoggingFlow))
LocalProfileAssistantImpl(apduInterface, HttpInterfaceImpl(verboseLoggingFlow, ignoreTLSCertificateFlow))
override val valid: Boolean
get() = lpa.valid

View file

@ -75,6 +75,9 @@ class SettingsFragment: PreferenceFragmentCompat() {
findPreference<CheckBoxPreference>("pref_developer_experimental_download_wizard")
?.bindBooleanFlow(preferenceRepository.experimentalDownloadWizardFlow, PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD)
findPreference<CheckBoxPreference>("pref_ignore_tls_certificate")
?.bindBooleanFlow(preferenceRepository.ignoreTLSCertificateFlow, PreferenceKeys.IGNORE_TLS_CERTIFICATE)
}
override fun onStart() {

View file

@ -20,13 +20,19 @@ val Fragment.preferenceRepository: PreferenceRepository
get() = requireContext().preferenceRepository
object PreferenceKeys {
// ---- Profile Notifications ----
val NOTIFICATION_DOWNLOAD = booleanPreferencesKey("notification_download")
val NOTIFICATION_DELETE = booleanPreferencesKey("notification_delete")
val NOTIFICATION_SWITCH = booleanPreferencesKey("notification_switch")
// ---- Advanced ----
val DISABLE_SAFEGUARD_REMOVABLE_ESIM = booleanPreferencesKey("disable_safeguard_removable_esim")
val VERBOSE_LOGGING = booleanPreferencesKey("verbose_logging")
// ---- Developer Options ----
val DEVELOPER_OPTIONS_ENABLED = booleanPreferencesKey("developer_options_enabled")
val EXPERIMENTAL_DOWNLOAD_WIZARD = booleanPreferencesKey("experimental_download_wizard")
val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate")
}
class PreferenceRepository(context: Context) {
@ -57,6 +63,9 @@ class PreferenceRepository(context: Context) {
val experimentalDownloadWizardFlow: Flow<Boolean> =
dataStore.data.map { it[PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD] ?: false }
val ignoreTLSCertificateFlow: Flow<Boolean> =
dataStore.data.map { it[PreferenceKeys.IGNORE_TLS_CERTIFICATE] ?: false }
suspend fun <T> updatePreference(key: Preferences.Key<T>, value: T) {
dataStore.edit {
it[key] = value

View file

@ -123,6 +123,8 @@
<string name="pref_developer">Developer Options</string>
<string name="pref_developer_experimental_download_wizard">Experimental Download Wizard</string>
<string name="pref_developer_experimental_download_wizard_desc">Enable the experimental new download wizard. Note that it is not fully working yet.</string>
<string name="pref_developer_ignore_tls_certificate">Ignore SM-DP+ TLS certificate</string>
<string name="pref_developer_ignore_tls_certificate_desc">Ignore SM-DP+ TLS certificate, allow any RSP</string>
<string name="pref_info">Info</string>
<string name="pref_info_app_version">App Version</string>
<string name="pref_info_source_code">Source Code</string>

View file

@ -55,6 +55,12 @@
app:title="@string/pref_developer_experimental_download_wizard"
app:summary="@string/pref_developer_experimental_download_wizard_desc" />
<CheckBoxPreference
app:iconSpaceReserved="false"
app:key="pref_developer_ignore_tls_certificate"
app:summary="@string/pref_developer_ignore_tls_certificate_desc"
app:title="@string/pref_developer_ignore_tls_certificate" />
</PreferenceCategory>
<PreferenceCategory

View file

@ -35,7 +35,8 @@ class PrivilegedEuiccChannelFactory(context: Context) : DefaultEuiccChannelFacto
tm,
context.preferenceRepository.verboseLoggingFlow
),
context.preferenceRepository.verboseLoggingFlow
context.preferenceRepository.verboseLoggingFlow,
context.preferenceRepository.ignoreTLSCertificateFlow,
)
} catch (e: IllegalArgumentException) {
// Failed

View file

@ -9,10 +9,14 @@ import java.net.URL
import java.security.SecureRandom
import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.TrustManagerFactory
class HttpInterfaceImpl(private val verboseLoggingFlow: Flow<Boolean>) : HttpInterface {
class HttpInterfaceImpl(
private val verboseLoggingFlow: Flow<Boolean>,
private val ignoreTLSCertificateFlow: Flow<Boolean>
) : HttpInterface {
companion object {
private const val TAG = "HttpInterfaceImpl"
}
@ -36,9 +40,6 @@ class HttpInterfaceImpl(private val verboseLoggingFlow: Flow<Boolean>) : HttpInt
}
try {
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustManagers, SecureRandom())
val conn = parsedUrl.openConnection() as HttpsURLConnection
conn.connectTimeout = 2000
@ -47,7 +48,7 @@ class HttpInterfaceImpl(private val verboseLoggingFlow: Flow<Boolean>) : HttpInt
conn.readTimeout = 1000
}
conn.sslSocketFactory = sslContext.socketFactory
conn.sslSocketFactory = getSocketFactory()
conn.requestMethod = "POST"
conn.doInput = true
conn.doOutput = true
@ -79,6 +80,18 @@ class HttpInterfaceImpl(private val verboseLoggingFlow: Flow<Boolean>) : HttpInt
}
}
private fun getSocketFactory(): SSLSocketFactory {
val trustManagers =
if (runBlocking { ignoreTLSCertificateFlow.first() }) {
arrayOf(IgnoreTLSCertificate())
} else {
this.trustManagers
}
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustManagers, SecureRandom())
return sslContext.socketFactory
}
override fun usePublicKeyIds(pkids: Array<String>) {
val trustManagerFactory = TrustManagerFactory.getInstance("PKIX").apply {
init(keyIdToKeystore(pkids))

View file

@ -0,0 +1,22 @@
package net.typeblog.lpac_jni.impl
import android.annotation.SuppressLint
import java.security.cert.X509Certificate
import javax.net.ssl.X509TrustManager
@SuppressLint("CustomX509TrustManager")
class IgnoreTLSCertificate : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager")
override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) {
return
}
@SuppressLint("TrustAllX509TrustManager")
override fun checkServerTrusted(p0: Array<out X509Certificate>?, p1: String?) {
return
}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return emptyArray()
}
}