Skip to content
This repository has been archived by the owner on Jan 4, 2024. It is now read-only.

Commit

Permalink
Use mozilla included root ca certificates by default
Browse files Browse the repository at this point in the history
  • Loading branch information
nekohasekai committed Jan 6, 2022
1 parent ae68969 commit 88fcbf4
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 23 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ build/
.cxx
local.properties
/app/libs/
/app/src/main/assets/v2ray
/app/src/main/assets/v2ray/
/app/src/main/assets/mozilla_included.pem
/app/src/main/assets/mozilla_included.pem.sha256sum
/service_account_credentials.json
jniLibs/
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ interface ISagerNetService {
int urlTest();
oneway void resetTrafficStats();
boolean getTrafficStatsEnabled();
oneway void updateSystemRoots(boolean useSystem);

}
6 changes: 6 additions & 0 deletions app/src/main/java/io/nekohasekai/sagernet/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ object Key {
const val ALWAYS_SHOW_ADDRESS = "alwaysShowAddress"

const val PROVIDER_TROJAN = "providerTrojan"
const val PROVIDER_ROOT_CA = "providerRootCA"

const val TUN_IMPLEMENTATION = "tunImplementation"
const val ENABLE_PCAP = "enablePcap"
Expand Down Expand Up @@ -209,6 +210,11 @@ object TrojanProvider {
const val TROJAN_GO = 2
}

object RootCAProvider {
const val MOZILLA = 0
const val SYSTEM = 1
}

object IPv6Mode {
const val DISABLE = 0
const val ENABLE = 1
Expand Down
15 changes: 6 additions & 9 deletions app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ import io.nekohasekai.sagernet.ktx.app
import io.nekohasekai.sagernet.ktx.checkMT
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
import io.nekohasekai.sagernet.ui.MainActivity
import io.nekohasekai.sagernet.utils.CrashHandler
import io.nekohasekai.sagernet.utils.DeviceStorageApp
import io.nekohasekai.sagernet.utils.PackageCache
import io.nekohasekai.sagernet.utils.Theme
import io.nekohasekai.sagernet.utils.*
import kotlinx.coroutines.DEBUG_PROPERTY_NAME
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON
import libcore.Libcore
Expand Down Expand Up @@ -85,11 +82,11 @@ class SagerNet : Application(),
Seq.setContext(this)

externalAssets.mkdirs()
Libcore.initializeV2Ray(
filesDir.absolutePath + "/", externalAssets.absolutePath + "/", "v2ray/"
) {
DataStore.rulesProvider == 0
}
Libcore.initializeV2Ray(filesDir.absolutePath + "/",
externalAssets.absolutePath + "/",
"v2ray/",
{ DataStore.rulesProvider == 0 },
{ DataStore.providerRootCA == RootCAProvider.SYSTEM })
Libcore.setenv("v2ray.conf.geoloader", "memconservative")
Libcore.setUidDumper(UidDumper)

Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ class BaseService {
return (data?.proxy?.service as? VpnService)?.getTun()?.trafficStatsEnabled ?: false
}

override fun updateSystemRoots(useSystem: Boolean) {
Libcore.updateSystemRoots(useSystem)
}

override fun close() {
callbacks.kill()
cancel()
Expand All @@ -352,6 +356,7 @@ class BaseService {
fun forceLoad() {
if (DataStore.selectedProxy == 0L) {
stopRunner(false, (this as Context).getString(R.string.profile_empty))
return
}
val s = data.state
when {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import io.nekohasekai.sagernet.RootCAProvider
import io.nekohasekai.sagernet.SagerNet
import io.nekohasekai.sagernet.TrojanProvider
import io.nekohasekai.sagernet.bg.AbstractInstance
Expand Down Expand Up @@ -175,12 +176,20 @@ abstract class V2RayInstance(
@SuppressLint("SetJavaScriptEnabled")
override fun launch() {
val context = if (Build.VERSION.SDK_INT < 24 || SagerNet.user.isUserUnlocked) SagerNet.application else SagerNet.deviceStorage
val useSystemCACerts = DataStore.providerRootCA == RootCAProvider.SYSTEM
val rootCaPem by lazy { File(app.filesDir, "root_ca_certs.pem").canonicalPath }

for ((isBalancer, chain) in config.index) {
chain.entries.forEachIndexed { index, (port, profile) ->
val bean = profile.requireBean()
val needChain = !isBalancer && index != chain.size - 1
val (profileType, config) = pluginConfigs[port] ?: 0 to ""
val env = mutableMapOf<String, String>()
if (!useSystemCACerts) {
env["SSL_CERT_FILE"] = rootCaPem
// disable system directories
env["SSL_CERT_DIR"] = "/dev/null"
}

when {
externalInstances.containsKey(port) -> {
Expand All @@ -203,7 +212,7 @@ abstract class V2RayInstance(
}.path, "--config", configFile.absolutePath
)

processes.start(commands)
processes.start(commands, env)
}
bean is TrojanGoBean || bean is ConfigBean && bean.type == "trojan-go" -> {
val configFile = File(
Expand All @@ -218,7 +227,7 @@ abstract class V2RayInstance(
initPlugin("trojan-go-plugin").path, "-config", configFile.absolutePath
)

processes.start(commands)
processes.start(commands, env)
}
bean is NaiveBean -> {
val configFile = File(
Expand All @@ -234,7 +243,7 @@ abstract class V2RayInstance(
initPlugin("naive-plugin").path, configFile.absolutePath
)

processes.start(commands)
processes.start(commands, env)
}
bean is PingTunnelBean -> {
if (needChain) error("PingTunnel is incompatible with chain")
Expand All @@ -258,7 +267,7 @@ abstract class V2RayInstance(
commands.add(bean.key)
}

processes.start(commands)
processes.start(commands, env)
}
bean is RelayBatonBean -> {
val configFile = File(
Expand All @@ -277,7 +286,7 @@ abstract class V2RayInstance(
configFile.absolutePath
)

processes.start(commands)
processes.start(commands, env)
}
bean is BrookBean -> {
val commands = mutableListOf(initPlugin("brook-plugin").path)
Expand Down Expand Up @@ -307,7 +316,7 @@ abstract class V2RayInstance(
commands.add("--socks5")
commands.add("$LOCALHOST:$port")

processes.start(commands)
processes.start(commands, env)
}
bean is HysteriaBean -> {
val configFile = File(
Expand All @@ -333,7 +342,7 @@ abstract class V2RayInstance(
commands.addAll(0, listOf("su", "-c"))
}

processes.start(commands)
processes.start(commands, env)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
// protocol

var providerTrojan by configurationStore.stringToInt(Key.PROVIDER_TROJAN)
var providerRootCA by configurationStore.stringToInt(Key.PROVIDER_ROOT_CA)

// cache

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,13 @@ import androidx.preference.SwitchPreference
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.takisoft.preferencex.PreferenceFragmentCompat
import com.takisoft.preferencex.SimpleMenuPreference
import io.nekohasekai.sagernet.Key
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.SagerNet
import io.nekohasekai.sagernet.TunImplementation
import io.nekohasekai.sagernet.*
import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.utils.Theme
import io.nekohasekai.sagernet.widget.ColorPickerPreference
import libcore.Libcore
import java.io.File

class SettingsPreferenceFragment : PreferenceFragmentCompat() {
Expand Down Expand Up @@ -158,6 +156,7 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
directDns.isEnabled = !DataStore.useLocalDnsAsDirectDns
useLocalDnsAsDirectDns.setOnPreferenceChangeListener { _, newValue ->
directDns.isEnabled = newValue == false
needReload()
true
}

Expand Down Expand Up @@ -222,6 +221,14 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
val destinationOverride = findPreference<SwitchPreference>(Key.DESTINATION_OVERRIDE)!!
val resolveDestination = findPreference<SwitchPreference>(Key.RESOLVE_DESTINATION)!!
val enablePcap = findPreference<SwitchPreference>(Key.ENABLE_PCAP)!!
val providerRootCA = findPreference<SimpleMenuPreference>(Key.PROVIDER_ROOT_CA)!!
providerRootCA.setOnPreferenceChangeListener { _, newValue ->
val useSystem = (newValue as String) == "${RootCAProvider.SYSTEM}"
Libcore.updateSystemRoots(useSystem)
(requireActivity() as? MainActivity)?.connection?.service?.updateSystemRoots(useSystem)
needReload()
true
}

speedInterval.onPreferenceChangeListener = reloadListener
portSocks5.onPreferenceChangeListener = reloadListener
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/baseline_flight_takeoff_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M2.5,19h19v2h-19V19zM22.07,9.64c-0.21,-0.8 -1.04,-1.28 -1.84,-1.06L14.92,10l-6.9,-6.43L6.09,4.08l4.14,7.17l-4.97,1.33l-1.97,-1.54l-1.45,0.39l2.59,4.49c0,0 7.12,-1.9 16.57,-4.43C21.81,11.26 22.28,10.44 22.07,9.64z" />
</vector>
5 changes: 5 additions & 0 deletions app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -638,4 +638,9 @@
<item>@string/route_profile</item>
</string-array>

<string-array name="root_ca_provider_entry">
<item>@string/root_ca_mozilla</item>
<item>@string/root_ca_system</item>
</string-array>

</resources>
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -497,4 +497,8 @@
<string name="tasker_action_stop_service">Stop service</string>
<string name="tasker_start_current_profile">Current profile</string>
<string name="tasker_blurb_start_profile">Start profile %s</string>

<string name="root_ca_provider">Root CA Certificates Provider</string>
<string name="root_ca_mozilla">Mozilla</string>
<string name="root_ca_system">System</string>
</resources>
10 changes: 10 additions & 0 deletions app/src/main/res/xml/global_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,21 @@

<PreferenceCategory app:title="@string/protocol_settings">
<com.takisoft.preferencex.SimpleMenuPreference
android:icon="@drawable/baseline_flight_takeoff_24"
app:defaultValue="0"
app:entries="@array/trojan_provider_experimental"
app:entryValues="@array/int_array_3"
app:key="providerTrojan"
app:title="@string/trojan_provider"
app:useSimpleSummaryProvider="true" />
<com.takisoft.preferencex.SimpleMenuPreference
android:icon="@drawable/ic_baseline_push_pin_24"
app:defaultValue="0"
app:entries="@array/root_ca_provider_entry"
app:entryValues="@array/int_array_2"
app:key="providerRootCA"
app:title="@string/root_ca_provider"
app:useSimpleSummaryProvider="true" />
</PreferenceCategory>

<PreferenceCategory app:title="@string/cag_dns">
Expand Down Expand Up @@ -207,6 +216,7 @@
app:title="@string/port_local_dns"
app:useSimpleSummaryProvider="true" />
<SwitchPreference
app:defaultValue="true"
app:icon="@drawable/ic_baseline_http_24"
app:key="requireHttp"
app:title="@string/require_http" />
Expand Down
3 changes: 2 additions & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
implementation("com.android.tools.build:gradle-api:$androidPluginVersion")
implementation(kotlin("gradle-plugin", kotlinVersion))
implementation(kotlin("stdlib", kotlinVersion))
implementation("cn.hutool:hutool-http:$hutoolVersion")
implementation("cn.hutool:hutool-crypto:$hutoolVersion")
implementation("org.tukaani:xz:1.9")
implementation("com.github.triplet.gradle:play-publisher:3.6.0")
Expand All @@ -22,4 +23,4 @@ dependencies {
implementation("com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:8.9.1")
implementation("com.google.protobuf:protobuf-gradle-plugin:0.8.17")
implementation("com.github.ben-manes:gradle-versions-plugin:0.39.0")
}
}
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/Helpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ fun Project.setupApp() {
requireFlavor().endsWith("Debug")
}
doLast {
downloadRootCAList()
downloadAssets()
}
}
Expand Down
25 changes: 25 additions & 0 deletions buildSrc/src/main/kotlin/RootCAAsserts.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import cn.hutool.core.text.csv.CsvReadConfig
import cn.hutool.core.text.csv.CsvUtil
import cn.hutool.crypto.digest.DigestUtil
import cn.hutool.http.HttpUtil
import org.gradle.api.Project
import java.io.File

fun Project.downloadRootCAList() {
val assets = File(projectDir, "src/main/assets")
val csv = HttpUtil.get("https://ccadb-public.secure.force.com/mozilla/IncludedCACertificateReportPEMCSV")
val data = CsvUtil.getReader(CsvReadConfig().setContainsHeader(true)).readFromStr(csv)
val list = mutableListOf<String>()
for (row in data) {
// skip China root CA
if (row.getByName("Geographic Focus").contains("China")) continue
if (!row.getByName("Trust Bits").contains("Websites")) continue

val name = row.getByName("Common Name or Certificate Name")
val cert = row.getByName("PEM Info")
list.add("$name\n" + cert.substring(1, cert.length - 1))
}
val pem = File(assets, "mozilla_included.pem")
pem.writeText(list.joinToString("\n\n"))
File(pem.parent, pem.name + ".sha256sum").writeText(DigestUtil.sha256Hex(pem))
}
2 changes: 1 addition & 1 deletion library/core
Submodule core updated 2 files
+58 −7 assets.go
+46 −0 certs.go

0 comments on commit 88fcbf4

Please sign in to comment.