Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ actual fun createPlatformHttpClient(proxyConfig: ProxyConfig): HttpClient =
HttpClient(OkHttp) {
engine {
config {
// Trust OS-installed root certificates in addition to the
// JVM cacerts bundle. Lets users behind TLS-intercepting
// tools (Watt Toolkit, Fiddler, corporate MITM) keep using
// the app without manually injecting certs into the JDK.
// Silently skipped on platforms where no OS keystore is
// available — default trust still applies.
buildOsTrustChainOrNull()?.let { chain ->
sslSocketFactory(chain.socketFactory, chain.trustManager)
}

// Reset any inherited global SOCKS authenticator before
// deciding what this client needs — prevents a stale
// Authenticator from a previous [ProxyConfig.Socks] client
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package zed.rainxch.core.data.network

import java.security.KeyStore
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager

internal data class OsTrustChain(
val socketFactory: SSLSocketFactory,
val trustManager: X509TrustManager,
)

internal fun buildOsTrustChainOrNull(): OsTrustChain? {
val managers = buildList {
defaultTrustManagerOrNull()?.let { add(it) }
osTrustManagerOrNull()?.let { add(it) }
}
if (managers.size < 2) return null
val composite = CompositeX509TrustManager(managers)
return try {
val ctx = SSLContext.getInstance("TLS").apply {
init(null, arrayOf(composite), null)
}
OsTrustChain(ctx.socketFactory, composite)
} catch (_: Throwable) {
null
}
}

private fun defaultTrustManagerOrNull(): X509TrustManager? = trustManagerFromKeyStore(null)

private fun osTrustManagerOrNull(): X509TrustManager? {
val osName = System.getProperty("os.name").orEmpty().lowercase()
val keyStore = when {
osName.contains("windows") -> loadKeyStore("Windows-ROOT")
osName.contains("mac") || osName.contains("darwin") -> loadKeyStore("KeychainStore")
else -> null
} ?: return null
return trustManagerFromKeyStore(keyStore)
}

private fun loadKeyStore(type: String): KeyStore? = try {
KeyStore.getInstance(type).apply { load(null, null) }
} catch (_: Throwable) {
null
}

private fun trustManagerFromKeyStore(keyStore: KeyStore?): X509TrustManager? = try {
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
tmf.init(keyStore)
tmf.trustManagers.filterIsInstance<X509TrustManager>().firstOrNull()
} catch (_: Throwable) {
null
}

private class CompositeX509TrustManager(
private val delegates: List<X509TrustManager>,
) : X509TrustManager {
override fun checkClientTrusted(chain: Array<out X509Certificate>, authType: String) {
var lastError: Throwable? = null
for (tm in delegates) {
try {
tm.checkClientTrusted(chain, authType)
return
} catch (t: Throwable) {
lastError = t
}
}
throw lastError ?: java.security.cert.CertificateException("No trust manager accepted the chain")
}

override fun checkServerTrusted(chain: Array<out X509Certificate>, authType: String) {
var lastError: Throwable? = null
for (tm in delegates) {
try {
tm.checkServerTrusted(chain, authType)
return
} catch (t: Throwable) {
lastError = t
}
}
throw lastError ?: java.security.cert.CertificateException("No trust manager accepted the chain")
}

override fun getAcceptedIssuers(): Array<X509Certificate> =
delegates.flatMap { it.acceptedIssuers.toList() }.toTypedArray()
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"Multi-source downloads no longer clobber each other's APK file.",
"Shizuku-fallback installs no longer flip rows to \"installed\" prematurely.",
"Self-update no longer leaves apps stuck on \"Preparing to install\"."
"Self-update no longer leaves apps stuck on \"Preparing to install\".",
"Desktop now trusts OS-installed root certificates — Watt Toolkit, FastGithub, Fiddler, and corporate MITM proxies just work without keytool gymnastics."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"تنزيلات المصادر المتعددة لم تعد تطمس ملفات APK الخاصة ببعضها.",
"تثبيتات Shizuku الاحتياطية لم تعد تُعلّم التطبيقات بأنها «مثبّتة» قبل الأوان.",
"التحديث الذاتي لم يعد يترك التطبيقات معلّقة على «التحضير للتثبيت»."
"التحديث الذاتي لم يعد يترك التطبيقات معلّقة على «التحضير للتثبيت».",
"تطبيق سطح المكتب يثق الآن بشهادات الجذر المثبَّتة في النظام — Watt Toolkit و FastGithub و Fiddler ووكلاء MITM للشركات تعمل دون الحاجة إلى استخدام keytool."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"মাল্টি-সোর্স ডাউনলোড আর একে অপরের APK ফাইল ওভাররাইট করে না।",
"Shizuku-ফলব্যাক ইনস্টল আর অ্যাপগুলোকে আগেভাগে 'ইনস্টল হয়েছে' হিসেবে চিহ্নিত করে না।",
"সেলফ-আপডেট আর অ্যাপগুলোকে 'ইনস্টলের জন্য প্রস্তুত হচ্ছে' অবস্থায় আটকে রাখে না।"
"সেলফ-আপডেট আর অ্যাপগুলোকে 'ইনস্টলের জন্য প্রস্তুত হচ্ছে' অবস্থায় আটকে রাখে না।",
"ডেস্কটপ এখন OS-এ ইনস্টল করা রুট সার্টিফিকেটগুলোকে বিশ্বাস করে — Watt Toolkit, FastGithub, Fiddler আর কর্পোরেট MITM প্রক্সি keytool ছাড়াই কাজ করে।"
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"Las descargas multi-origen ya no se sobrescriben entre sí.",
"Las instalaciones con respaldo Shizuku ya no marcan apps como «instaladas» antes de tiempo.",
"La auto-actualización ya no deja apps atascadas en «Preparando para instalar»."
"La auto-actualización ya no deja apps atascadas en «Preparando para instalar».",
"El escritorio ahora confía en los certificados raíz instalados en el sistema — Watt Toolkit, FastGithub, Fiddler y proxies MITM corporativos funcionan sin tener que usar keytool."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"Les téléchargements multi-source ne s’écrasent plus entre eux.",
"Les installations en repli Shizuku ne marquent plus les apps comme « installées » trop tôt.",
"L’auto-mise à jour ne laisse plus d’apps bloquées sur « Préparation de l’installation »."
"L’auto-mise à jour ne laisse plus d’apps bloquées sur « Préparation de l’installation ».",
"Le bureau fait désormais confiance aux certificats racine installés par l’OS — Watt Toolkit, FastGithub, Fiddler et les proxys MITM d’entreprise fonctionnent sans manip keytool."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"मल्टी-सोर्स डाउनलोड अब एक-दूसरे की APK फ़ाइल को ओवरराइट नहीं करते।",
"Shizuku-फ़ॉलबैक इंस्टॉल अब समय से पहले ऐप को 'इंस्टॉल' के रूप में चिह्नित नहीं करते।",
"सेल्फ़-अपडेट अब ऐप्स को 'इंस्टॉल के लिए तैयार किया जा रहा है' पर अटका नहीं छोड़ता।"
"सेल्फ़-अपडेट अब ऐप्स को 'इंस्टॉल के लिए तैयार किया जा रहा है' पर अटका नहीं छोड़ता।",
"डेस्कटॉप अब OS में इंस्टॉल किए गए रूट सर्टिफिकेट पर भरोसा करता है — Watt Toolkit, FastGithub, Fiddler और कॉर्पोरेट MITM प्रॉक्सी keytool के बिना भी काम करते हैं।"
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"I download multi-sorgente non si sovrascrivono più a vicenda.",
"Le installazioni con fallback Shizuku non segnano più le app come «installate» troppo presto.",
"L’aggiornamento automatico non lascia più app bloccate su «Preparazione all’installazione»."
"L’aggiornamento automatico non lascia più app bloccate su «Preparazione all’installazione».",
"Il desktop ora si fida dei certificati radice installati dal sistema — Watt Toolkit, FastGithub, Fiddler e i proxy MITM aziendali funzionano senza manovre con keytool."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"複数ソースのダウンロードが互いの APK を上書きしてしまう問題を修正。",
"Shizuku フォールバック時に「インストール済み」と早まって表示されることがなくなりました。",
"セルフアップデート後にアプリが「インストールの準備中」のまま固まる問題を修正。"
"セルフアップデート後にアプリが「インストールの準備中」のまま固まる問題を修正。",
"デスクトップが OS にインストール済みのルート証明書を信頼するようになりました。Watt Toolkit、FastGithub、Fiddler、社内 MITM プロキシも keytool 不要で動作します。"
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"다중 소스 다운로드가 서로의 APK 파일을 덮어쓰던 문제를 수정했습니다.",
"Shizuku 폴백 설치가 시스템 확정 전에 ‘설치됨’으로 표시되던 문제를 수정했습니다.",
"셀프 업데이트 후 앱이 ‘설치 준비 중’ 상태로 멈춰 있던 문제를 수정했습니다."
"셀프 업데이트 후 앱이 ‘설치 준비 중’ 상태로 멈춰 있던 문제를 수정했습니다.",
"데스크톱이 OS에 설치된 루트 인증서를 신뢰합니다 — Watt Toolkit, FastGithub, Fiddler, 사내 MITM 프록시가 keytool 작업 없이 그대로 동작합니다."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"Pobierania z wielu źródeł nie nadpisują już swoich plików APK.",
"Instalacje z trybem awaryjnym Shizuku nie oznaczają już aplikacji jako „zainstalowanych” przedwcześnie.",
"Auto-aktualizacja nie zostawia już aplikacji w stanie „Przygotowywanie instalacji”."
"Auto-aktualizacja nie zostawia już aplikacji w stanie „Przygotowywanie instalacji”.",
"Wersja desktopowa ufa teraz certyfikatom głównym zainstalowanym w systemie — Watt Toolkit, FastGithub, Fiddler i firmowe proxy MITM działają bez kombinowania z keytool."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"Загрузки из нескольких источников больше не затирают APK друг друга.",
"Установка через Shizuku-fallback больше не помечает приложения как «установленные» раньше времени.",
"Самообновление больше не оставляет приложения зависшими на статусе «Подготовка к установке»."
"Самообновление больше не оставляет приложения зависшими на статусе «Подготовка к установке».",
"Десктоп теперь доверяет корневым сертификатам, установленным в ОС — Watt Toolkit, FastGithub, Fiddler и корпоративные MITM-прокси работают без шаманства с keytool."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"Çoklu kaynaklı indirmeler artık birbirinin APK dosyasını ezmez.",
"Shizuku yedekli kurulumlar uygulamaları artık erkenden “kuruldu” olarak işaretlemez.",
"Otomatik güncelleme uygulamaları artık “Yüklemeye hazırlanıyor” durumunda asılı bırakmaz."
"Otomatik güncelleme uygulamaları artık “Yüklemeye hazırlanıyor” durumunda asılı bırakmaz.",
"Masaüstü artık işletim sistemine yüklü kök sertifikalara güveniyor — Watt Toolkit, FastGithub, Fiddler ve kurumsal MITM proxy'leri keytool uğraşı olmadan çalışıyor."
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"bullets": [
"修复多源下载相互覆盖 APK 文件的问题。",
"修复 Shizuku 回退安装时,应用提前被标记为「已安装」的问题。",
"修复自动更新后应用卡在「准备安装」状态的问题。"
"修复自动更新后应用卡在「准备安装」状态的问题。",
"桌面端现在信任系统已安装的根证书 — Watt Toolkit、FastGithub、Fiddler 以及企业 MITM 代理无需折腾 keytool 即可使用。"
]
}
]
Expand Down