mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 21:32:34 +00:00
Merge branch 'develop' into renovate/maplibre.compose
This commit is contained in:
@@ -342,6 +342,9 @@ licensee {
|
||||
ignoreDependencies("com.github.matrix-org", "matrix-analytics-events")
|
||||
// Ignore dependency that are not third-party licenses to us.
|
||||
ignoreDependencies(groupId = "io.element.android")
|
||||
// The rustls-platform-verifier dependency does not provide a license file in their maven repo, but there are MIT and Apache licenses in
|
||||
// the source code repo: see https://github.com/rustls/rustls-platform-verifier
|
||||
ignoreDependencies(groupId = "org.rustls", artifactId = "rustls-platform-verifier")
|
||||
}
|
||||
|
||||
fun Project.configureLicensesTasks(reportingExtension: ReportingExtension) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.system.Os
|
||||
import androidx.startup.Initializer
|
||||
import io.element.android.features.rageshake.api.logs.createWriteToFilesConfiguration
|
||||
import io.element.android.libraries.architecture.bindings
|
||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.matrix.api.tracing.TracingConfiguration
|
||||
import io.element.android.x.di.AppBindings
|
||||
@@ -41,9 +42,18 @@ class PlatformInitializer : Initializer<Unit> {
|
||||
sdkSentryDsn = appBindings.sentrySdkDsn()?.value?.takeIf { it.isNotBlank() },
|
||||
)
|
||||
bugReporter.setCurrentTracingLogLevel(logLevel.name)
|
||||
|
||||
// Init the tracing service with the configuration so we have logging enabled as soon as possible
|
||||
platformService.init(tracingConfiguration)
|
||||
// Also set env variable for rust back trace
|
||||
Os.setenv("RUST_BACKTRACE", "1", true)
|
||||
|
||||
// Init the SDK with the Android Context, so it can be used with rustls and other Android specific features
|
||||
runCatchingExceptions {
|
||||
org.matrix.rustsdk.Android.init(context)
|
||||
}.onFailure {
|
||||
Timber.e(it, "Failed to init the SDK with an Android Context. The app probably won't work properly.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun dependencies(): List<Class<out Initializer<*>>> = mutableListOf()
|
||||
|
||||
@@ -30,5 +30,384 @@
|
||||
<domain includeSubdomains="true">home</domain>
|
||||
<domain includeSubdomains="true">lan</domain>
|
||||
<domain includeSubdomains="true">localdomain</domain>
|
||||
|
||||
<!-- Domains below are imported from rustls-platform-verifier 0.2.0 by tools/dependencies/update_rustls_platform_verifier.py -->
|
||||
<!-- They are needed to fetch the certificate revocation lists over cleartext -->
|
||||
<domain includeSubdomains="true">abitabdv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">abitabev.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">abitabov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">alpiro.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">anticdv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">antrustovsslg2r30ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">autontrustprodvtlsg2r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">bitcert.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">btdvtlsr35g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">c.cf-b.ssl.com</domain>
|
||||
<domain includeSubdomains="true">c.cf-i.ssl.com</domain>
|
||||
<domain includeSubdomains="true">c.pki.goog</domain>
|
||||
<domain includeSubdomains="true">ca1.agid.gov.it</domain>
|
||||
<domain includeSubdomains="true">cdn.d-trust-cloudcrl.net</domain>
|
||||
<domain includeSubdomains="true">cdp.disig.sk</domain>
|
||||
<domain includeSubdomains="true">cdp.elektronicznypodpis.pl</domain>
|
||||
<domain includeSubdomains="true">cdp.geotrust.com</domain>
|
||||
<domain includeSubdomains="true">cdp.rapidssl.com</domain>
|
||||
<domain includeSubdomains="true">cdp.thawte.com</domain>
|
||||
<domain includeSubdomains="true">cdp1.disig.sk</domain>
|
||||
<domain includeSubdomains="true">cdp1.pca.dfn.de</domain>
|
||||
<domain includeSubdomains="true">cdpa.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">cdpb.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">cdpc.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">cdpd.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">cdpe.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">cdpf.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">cdpg.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">cdph.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">cdpi.digitalcertvalidation.com</domain>
|
||||
<domain includeSubdomains="true">certcloud.crl.trust-provider.com</domain>
|
||||
<domain includeSubdomains="true">certdata.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">certera.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">certificates.godaddy.com</domain>
|
||||
<domain includeSubdomains="true">certum-crl.wt.trustasia.com</domain>
|
||||
<domain includeSubdomains="true">certum.crl.sheca.com</domain>
|
||||
<domain includeSubdomains="true">certumdvtlsg2e39ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">certumdvtlsg2r39ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">certumevtlsg2e39ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">certumevtlsg2r39ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">certumovtlsg2e39ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">certumovtlsg2r39ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">cfcadveccca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">cfcadvrsaca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">cfcaeveccca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">cfcaevrsaca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">cfcaoveccca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">cfcaovrsaca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">cnssldvtlsg2r36ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">cnsslovtlsg2r36ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">crl-01.r1.ica.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl-01.r1.ica.amznts.eu</domain>
|
||||
<domain includeSubdomains="true">crl-c.emsign.com</domain>
|
||||
<domain includeSubdomains="true">crl-pro.litessl.com</domain>
|
||||
<domain includeSubdomains="true">crl.anf.es</domain>
|
||||
<domain includeSubdomains="true">crl.apple.com</domain>
|
||||
<domain includeSubdomains="true">crl.businessid.telesec.de</domain>
|
||||
<domain includeSubdomains="true">crl.buypass.no</domain>
|
||||
<domain includeSubdomains="true">crl.catrust.oemssl.cn</domain>
|
||||
<domain includeSubdomains="true">crl.certigna.fr</domain>
|
||||
<domain includeSubdomains="true">crl.certsign.ro</domain>
|
||||
<domain includeSubdomains="true">crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">crl.cfca.com.cn</domain>
|
||||
<domain includeSubdomains="true">crl.cntrus.oemssl.cn</domain>
|
||||
<domain includeSubdomains="true">crl.cnwebtrust.oemssl.cn</domain>
|
||||
<domain includeSubdomains="true">crl.comodoca.com</domain>
|
||||
<domain includeSubdomains="true">crl.crlocsp.cn</domain>
|
||||
<domain includeSubdomains="true">crl.cybertrust.ne.jp</domain>
|
||||
<domain includeSubdomains="true">crl.d-trust.net</domain>
|
||||
<domain includeSubdomains="true">crl.dhimyotis.com</domain>
|
||||
<domain includeSubdomains="true">crl.digicert.cn</domain>
|
||||
<domain includeSubdomains="true">crl.digicert.eu</domain>
|
||||
<domain includeSubdomains="true">crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">crl.e2m01.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2m01.eu.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2m02.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2m03.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2m04.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2s14.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2s15.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2s16.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2s17.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2s18.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2s19.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2s20.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e2s21.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3m01.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3m01.eu.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3m02.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3m03.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3m04.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3s22.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3s23.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3s24.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3s25.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3s26.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3s27.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3s28.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.e3s29.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.emsign.com</domain>
|
||||
<domain includeSubdomains="true">crl.ensuredca.com</domain>
|
||||
<domain includeSubdomains="true">crl.firmaprofesional.com</domain>
|
||||
<domain includeSubdomains="true">crl.gdca.com.cn</domain>
|
||||
<domain includeSubdomains="true">crl.global.sheca.com</domain>
|
||||
<domain includeSubdomains="true">crl.globalsign.com</domain>
|
||||
<domain includeSubdomains="true">crl.globalsign.net</domain>
|
||||
<domain includeSubdomains="true">crl.godaddy.com</domain>
|
||||
<domain includeSubdomains="true">crl.harica.gr</domain>
|
||||
<domain includeSubdomains="true">crl.izenpe.com</domain>
|
||||
<domain includeSubdomains="true">crl.litessl.com</domain>
|
||||
<domain includeSubdomains="true">crl.netsolssl.com</domain>
|
||||
<domain includeSubdomains="true">crl.oem.trustca.net</domain>
|
||||
<domain includeSubdomains="true">crl.pcsp.telesec.de</domain>
|
||||
<domain includeSubdomains="true">crl.pki.goog</domain>
|
||||
<domain includeSubdomains="true">crl.quovadisglobal.com</domain>
|
||||
<domain includeSubdomains="true">crl.r1001.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2001.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2m01.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2m01.eu.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2m02.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2m03.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2m04.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2s18.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2s19.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2s20.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2s21.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2s22.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2s23.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2s24.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r2s25.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r3001.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r4001.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r4m01.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r4m02.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r4m03.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.r4m04.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.root-e1.certainly.com</domain>
|
||||
<domain includeSubdomains="true">crl.root-r1.certainly.com</domain>
|
||||
<domain includeSubdomains="true">crl.rootca1.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.rootca2.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.rootca3.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.rootca4.amazontrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.rztrust.oemssl.cn</domain>
|
||||
<domain includeSubdomains="true">crl.sbca.telesec.de</domain>
|
||||
<domain includeSubdomains="true">crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">crl.sectigochina.com</domain>
|
||||
<domain includeSubdomains="true">crl.serverid.telesec.de</domain>
|
||||
<domain includeSubdomains="true">crl.starfieldtech.com</domain>
|
||||
<domain includeSubdomains="true">crl.swisssign.ch</domain>
|
||||
<domain includeSubdomains="true">crl.trust-provider.cn</domain>
|
||||
<domain includeSubdomains="true">crl.trust-provider.com</domain>
|
||||
<domain includeSubdomains="true">crl.tuntrust.tn</domain>
|
||||
<domain includeSubdomains="true">crl.usertrust.com</domain>
|
||||
<domain includeSubdomains="true">crl.wt.trustasia.com</domain>
|
||||
<domain includeSubdomains="true">crl.xinchacha.oemssl.cn</domain>
|
||||
<domain includeSubdomains="true">crl.zw.oemssl.cn</domain>
|
||||
<domain includeSubdomains="true">crl05.actalis.it</domain>
|
||||
<domain includeSubdomains="true">crl06.actalis.it</domain>
|
||||
<domain includeSubdomains="true">crl09.actalis.it</domain>
|
||||
<domain includeSubdomains="true">crl1.ecert.gov.hk</domain>
|
||||
<domain includeSubdomains="true">crl13.actalis.it</domain>
|
||||
<domain includeSubdomains="true">crl14.actalis.it</domain>
|
||||
<domain includeSubdomains="true">crl15.actalis.it</domain>
|
||||
<domain includeSubdomains="true">crl2.microsoft.com</domain>
|
||||
<domain includeSubdomains="true">crl3.digicert.com</domain>
|
||||
<domain includeSubdomains="true">crl4.digicert.com</domain>
|
||||
<domain includeSubdomains="true">crls.certainly.com</domain>
|
||||
<domain includeSubdomains="true">crls.ssl.com</domain>
|
||||
<domain includeSubdomains="true">cyberfolks2.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">depo.kamusm.gov.tr</domain>
|
||||
<domain includeSubdomains="true">digitaltrust.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">dnencrypt.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">dvtlsca2025-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">dvtlsca2026-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">e5.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">e6.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">e7.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">e8.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">ec2ca2017-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec2ca2017-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec2ca2017-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec2sslca2017-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec2sslca2017-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec2sslca2017-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec3ca2017-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec3ca2017-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec3ca2017-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec3sslca2017-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec3sslca2017-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ec3sslca2017-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eca.hinet.net</domain>
|
||||
<domain includeSubdomains="true">edvtlsca2023-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">edvtlsca2025-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">edvtlsca2026-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">emudhra.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">eosslca2017-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eosslca2017-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eosslca2017-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eovtlsca2023-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eovtlsca2025-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eovtlsca2026-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqca2017-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqca2017-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqca2017-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqcpca2017-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqcpca2017-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqcpca2017-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqoca2017-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqoca2017-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqoca2017-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqtlsca2018-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqtlsca2018-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqtlsca2018-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqtlsca2023-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqtlsca2025-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">eqtlsca2026-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">esafer.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">eue2m1.crl.root.amznts.eu</domain>
|
||||
<domain includeSubdomains="true">eue3m1.crl.root.amznts.eu</domain>
|
||||
<domain includeSubdomains="true">eur2m1.crl.root.amznts.eu</domain>
|
||||
<domain includeSubdomains="true">eveccca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">evrsaca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">gdcadv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">gdcaev.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">gdcaov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">gdcatrustauthdvtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">gdcatrustauthevtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">gdcatrustauthovtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">geant.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">genious.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">geossldvtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">geosslevtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">geosslovtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">globaltrust.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">globessl.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">gogetssldv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">gogetsslev.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">gogetsslov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">homepldvtlsg2r35ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">homepldvtlsg2r36ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">homeplovtlsg2r35ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">homeplovtlsg2r36ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">httpcrl.trust.telia.com</domain>
|
||||
<domain includeSubdomains="true">ica.navercloudtrust.com</domain>
|
||||
<domain includeSubdomains="true">ica.navercorp.com</domain>
|
||||
<domain includeSubdomains="true">issauth.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">itrusdv2.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">itrusdvtlsr35g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">itrusov2.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">itrusovtlsr35g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">itso.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">joyssldvtlsg2r33ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">joysslovtlsg2r33ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">kingnettechdv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">kingnettechev.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">kingnettechov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">kr.crl.digicert.com</domain>
|
||||
<domain includeSubdomains="true">lh2.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">namecheap.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">nazwassldvtlsg2e29ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">nazwassldvtlsg2r29ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">netartcadv2.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">netartssldvtlsg2e31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">nijimo.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">nyalabscadv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">nyatworkdv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">omitsecurity.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">onesign.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">osslca2016-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">osslca2016-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">osslca2016-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ovtlsca2025-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ovtlsca2026-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">pki-crl.atos.net</domain>
|
||||
<domain includeSubdomains="true">pki.telesec.de</domain>
|
||||
<domain includeSubdomains="true">pkipro.certsign.ro</domain>
|
||||
<domain includeSubdomains="true">positiwise.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">psw.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">public.wisekey.com</domain>
|
||||
<domain includeSubdomains="true">qiduodv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">qtlsca2018-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">qtlsca2018-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">qtlsca2018-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">qtlsca2026-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">r10.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">r11.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">r12.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">r13.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">rca.navercloudtrust.com</domain>
|
||||
<domain includeSubdomains="true">rca.navercorp.com</domain>
|
||||
<domain includeSubdomains="true">repo.pubcert.jprs.jp</domain>
|
||||
<domain includeSubdomains="true">repo1.secomtrust.net</domain>
|
||||
<domain includeSubdomains="true">repository.secomtrust.net</domain>
|
||||
<domain includeSubdomains="true">repository.tls.hinet.net</domain>
|
||||
<domain includeSubdomains="true">rootca.twca.com.tw</domain>
|
||||
<domain includeSubdomains="true">rootglobaldv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">rootnetworksdv2.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">shenzhendv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">shenzhenev.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">shenzhenov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">shoperdvtlsg2r34ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">shuididv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">shuidiev.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">shuidiov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">soomadv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">ssl2ca2016-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ssl2ca2016-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">ssl2ca2016-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">sslca2014-crl1.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">sslca2014-crl2.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">sslca2014-crl3.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">sslcom.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">ssllimiteddv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">sslserver.twca.com.tw</domain>
|
||||
<domain includeSubdomains="true">subca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">titrust.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">tlcdvtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">tlcevtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">tlcovtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">tlsrootca2025-crl.e-szigno.hu</domain>
|
||||
<domain includeSubdomains="true">trustasia.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustasiadv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustasiadvtlsr35g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustasiaev.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustasiaevtlse35g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustasiaevtlsr35g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustasiaov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustasiaovtlse35g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustasiaovtlsr35g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">trustocean.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">tstlser20.crl.telesec.de</domain>
|
||||
<domain includeSubdomains="true">tstlsrr23.crl.telesec.de</domain>
|
||||
<domain includeSubdomains="true">unitedtrustov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">validation.identrust.com</domain>
|
||||
<domain includeSubdomains="true">verokey.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">vtrusdvtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">vtrusovtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">webnic.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">whitessldvtlsg2e36ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">wosign.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">wotrus-dvca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">wotrus-evca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">wotrus-ovca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">wotrus.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">wtca-cafiles.itrus.com.cn</domain>
|
||||
<domain includeSubdomains="true">wtca-crl.itrus.com.cn</domain>
|
||||
<domain includeSubdomains="true">www.accv.es</domain>
|
||||
<domain includeSubdomains="true">www.cert.fnmt.es</domain>
|
||||
<domain includeSubdomains="true">www.d-trust.net</domain>
|
||||
<domain includeSubdomains="true">www.microsoft.com</domain>
|
||||
<domain includeSubdomains="true">x1.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">x2.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">xcctrustdvtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xcctrustevtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xcctrustovtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xinchacha2dv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xinchacha2ov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xinchachatrustdvtlsg2r34ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xinchachatrustevtlsg2r34ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xinchachatrustovtlsg2r34ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xinnetdvtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xinnetevtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">xinnetovtlsr34g2ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">ye.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">ye1.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">ye2.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">yektadv.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">yektaov.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">yr.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">yr1.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">yr2.c.lencr.org</domain>
|
||||
<domain includeSubdomains="true">zerossl.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">ziwit.crl.sectigo.com</domain>
|
||||
<domain includeSubdomains="true">zycatrustdvtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">zycatrustevtlsg3r31ca.crl.certum.pl</domain>
|
||||
<domain includeSubdomains="true">zycatrustovtlsg3r31ca.crl.certum.pl</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Ref: https://developer.android.com/training/articles/security-config.html -->
|
||||
<!-- By default, do not allow clearText traffic -->
|
||||
<base-config cleartextTrafficPermitted="false">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
<certificates
|
||||
src="user"
|
||||
tools:ignore="AcceptsUserCertificates" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
|
||||
<!-- Allow clearText traffic on some specified host -->
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<!-- Localhost -->
|
||||
<domain includeSubdomains="true">localhost</domain>
|
||||
<domain includeSubdomains="true">127.0.0.1</domain>
|
||||
<!-- Localhost for Android emulator -->
|
||||
<domain includeSubdomains="true">10.0.2.2</domain>
|
||||
<!-- Onion services -->
|
||||
<domain includeSubdomains="true">onion</domain>
|
||||
|
||||
<!-- Domains that are used for LANs -->
|
||||
<!-- These are IANA recognized special use domain names, see https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml -->
|
||||
<domain includeSubdomains="true">home.arpa</domain>
|
||||
<domain includeSubdomains="true">local</domain> <!-- Note this has been reserved for use with mDNS -->
|
||||
<domain includeSubdomains="true">test</domain>
|
||||
<!-- These are observed in the wild either by convention or RFCs that have not been accepted, and are not currently TLDs -->
|
||||
<domain includeSubdomains="true">home</domain>
|
||||
<domain includeSubdomains="true">lan</domain>
|
||||
<domain includeSubdomains="true">localdomain</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
@@ -182,7 +182,8 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version
|
||||
# https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt
|
||||
# All new features should not be implemented in the pull request that upgrades the version, developers should
|
||||
# only fix API breaks and may add some TODOs.
|
||||
matrix_sdk = "org.matrix.rustcomponents:sdk-android:26.09.26"
|
||||
matrix_sdk = "org.matrix.rustcomponents:sdk-android:26.09.28"
|
||||
rustls_platform_verifier = "org.rustls:rustls-platform-verifier:0.2.0"
|
||||
|
||||
# Others
|
||||
coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" }
|
||||
|
||||
@@ -28,7 +28,7 @@ dependencies {
|
||||
} else {
|
||||
debugImplementation(libs.matrix.sdk)
|
||||
}
|
||||
implementation(projects.libraries.rustlsTls)
|
||||
implementation(variantOf(libs.rustls.platform.verifier) { artifactType("aar") })
|
||||
|
||||
implementation(projects.appconfig)
|
||||
implementation(projects.features.enterprise.api)
|
||||
|
||||
+10
-15
@@ -7,11 +7,13 @@
|
||||
|
||||
package io.element.android.libraries.matrix.impl.storage
|
||||
|
||||
import android.util.Base64
|
||||
import io.element.android.libraries.androidutils.crypto.ClientSecret
|
||||
import io.element.android.libraries.core.data.ByteUnit
|
||||
import io.element.android.libraries.core.data.megaBytes
|
||||
import io.element.android.libraries.matrix.api.paths.SessionPaths
|
||||
import org.matrix.rustcomponents.sdk.ClientBuilder
|
||||
import uniffi.matrix_sdk_sqlite.Base64Variant
|
||||
import org.matrix.rustcomponents.sdk.SqliteStoreBuilder as SdkSqliteStoreBuilder
|
||||
|
||||
/**
|
||||
@@ -40,10 +42,15 @@ class RustSqliteStoreBuilder(
|
||||
override fun secret(clientSecret: ClientSecret?): SqliteStoreBuilder {
|
||||
when (clientSecret) {
|
||||
null -> Unit
|
||||
is ClientSecret.Passphrase -> inner = inner.passphrase(clientSecret.value)
|
||||
is ClientSecret.Passphrase -> {
|
||||
// Use high entropy passphrase to migrate a passphrase to a raw key.
|
||||
val base64Passphrase = Base64.decode(clientSecret.value, Base64.NO_WRAP or Base64.NO_PADDING)
|
||||
inner = inner.highEntropyPassphrase(base64Passphrase, Base64Variant.UNPADDED)
|
||||
// Once the passphrase is migrated, we can derive a raw key from it and use that for the SDK, replacing the line above.
|
||||
// inner = inner.key(base64Passphrase)
|
||||
}
|
||||
is ClientSecret.RawKey -> {
|
||||
// Ensure the key is 32 bytes long, as required by the SDK
|
||||
inner = inner.key(clientSecret.keyOfSize(32))
|
||||
inner = inner.key(clientSecret.bytes)
|
||||
}
|
||||
}
|
||||
return this
|
||||
@@ -53,15 +60,3 @@ class RustSqliteStoreBuilder(
|
||||
return clientBuilder.sqliteStore(this.inner)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClientSecret.RawKey.keyOfSize(size: Int): ByteArray {
|
||||
return if (bytes.size == 32) {
|
||||
bytes
|
||||
} else if (bytes.size < 32) {
|
||||
// If the key is shorter than 32 bytes, pad it with zeros
|
||||
bytes + ByteArray(32 - bytes.size)
|
||||
} else {
|
||||
// Otherwise, take the first 32 bytes of the key
|
||||
bytes.copyOfRange(0, 32)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package org.matrix.rustsdk
|
||||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
* This class is used to initialize the Rust SDK on Android and give it access to an Android [Context].
|
||||
*/
|
||||
object Android {
|
||||
init {
|
||||
System.loadLibrary("matrix_sdk_ffi")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
external fun init(context: Context)
|
||||
}
|
||||
+4
@@ -40,6 +40,8 @@ internal fun aRustEventTimelineItem(
|
||||
canBeRepliedTo: Boolean = true,
|
||||
reactions: List<Reaction> = emptyList(),
|
||||
lazyProvider: LazyTimelineItemProvider = FakeFfiLazyTimelineItemProvider(),
|
||||
editSendState: EventSendState? = null,
|
||||
redactionSendState: EventSendState? = null,
|
||||
) = EventTimelineItem(
|
||||
isRemote = isRemote,
|
||||
eventOrTransactionId = eventOrTransactionId,
|
||||
@@ -59,4 +61,6 @@ internal fun aRustEventTimelineItem(
|
||||
canBeRepliedTo = canBeRepliedTo,
|
||||
reactions = reactions,
|
||||
lazyProvider = lazyProvider,
|
||||
editSendState = editSendState,
|
||||
redactionSendState = redactionSendState,
|
||||
)
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
This module is a wrapper for the Android code distributed in the rustls-platform-verifier-android crate.
|
||||
|
||||
To avoid the distribution mess that this library has (download a Rust crate, then search for it using Gradle and use it as local maven repo),
|
||||
we previously just manually updated the AAR file instead using a script. This won't work for F-Droid because the AAR library is a black box with
|
||||
no sources attached to it, so we can't use it like that.
|
||||
|
||||
Instead, for the time being, we're adding the single `CertificateVerifier.kt` class this AAR had in it as part of our sources.
|
||||
|
||||
When this file is updated, the [UPDATED.md](./UPDATED.md) file should be updated too with the commit SHA of the new version.
|
||||
@@ -1,7 +0,0 @@
|
||||
Below is the commit SHA in [rustls-platform-verifier](https://github.com/rustls/rustls-platform-verifier) library used to update the code in this module:
|
||||
|
||||
```
|
||||
996b1c903491641b17b3c9afb65d1352f6fc6b76
|
||||
```
|
||||
|
||||
Please update it after making manual changes.
|
||||
@@ -1,24 +0,0 @@
|
||||
import extension.buildConfigFieldBoolean
|
||||
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("io.element.android-library")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "org.rustls.platformverifier"
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
buildConfigFieldBoolean("TEST", false)
|
||||
}
|
||||
}
|
||||
-398
@@ -1,398 +0,0 @@
|
||||
@file:SuppressLint("LogNotTimber", "ObsoleteSdkInt")
|
||||
@file:Suppress("KotlinConstantConditions")
|
||||
|
||||
// IMPORTANT: this file comes from rustls-platform-verifier and should not be modified locally.
|
||||
|
||||
/*
|
||||
* Copyright (c) 2022 1Password
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
package org.rustls.platformverifier
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.net.http.X509TrustManagerExtensions
|
||||
import android.util.Log
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.File
|
||||
import java.security.KeyStore
|
||||
import java.security.KeyStoreException
|
||||
import java.security.MessageDigest
|
||||
import java.security.PublicKey
|
||||
import java.security.cert.CertificateException
|
||||
import java.security.cert.CertificateExpiredException
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.CertificateNotYetValidException
|
||||
import java.security.cert.CertificateParsingException
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.Date
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
import javax.net.ssl.X509TrustManager
|
||||
import javax.security.auth.x500.X500Principal
|
||||
|
||||
// If this is updated, update the Rust definition too.
|
||||
// Marked private as this is not meant to be used in Android code.
|
||||
private enum class StatusCode(val value: Int) {
|
||||
Ok(0),
|
||||
Unavailable(1),
|
||||
Expired(2),
|
||||
UnknownCert(3),
|
||||
Revoked(4),
|
||||
InvalidEncoding(5),
|
||||
InvalidExtension(6),
|
||||
}
|
||||
|
||||
// Marked private as this is not meant to be used in Android code.
|
||||
private class VerificationResult(
|
||||
status: StatusCode,
|
||||
@Suppress("unused") val message: String? = null
|
||||
) {
|
||||
@Suppress("unused")
|
||||
private val code: Int = status.value
|
||||
}
|
||||
|
||||
// NOTE: All TrustManager and certificate validation methods are not thread safe. These
|
||||
// are all guarded by Kotlin's `Synchronized` accessors to prevent undefined behavior.
|
||||
|
||||
// Only JNI and test code calls this, so unused code warnings are suppressed.
|
||||
// Internal for test code - no other Kotlin code should use this object directly.
|
||||
@Suppress("unused")
|
||||
// We want to show a difference between Kotlin-side logs and those in Rust code
|
||||
@SuppressLint("LongLogTag")
|
||||
internal object CertificateVerifier {
|
||||
private const val TAG = "rustls-platform-verifier-android"
|
||||
|
||||
private fun createTrustManager(keystore: KeyStore?): X509TrustManagerExtensions? {
|
||||
// This can never throw since the default algorithm is used.
|
||||
val factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
|
||||
factory.init(keystore)
|
||||
|
||||
val availableTrustManagers = try {
|
||||
factory.trustManagers
|
||||
} catch (e: RuntimeException) {
|
||||
Log.w(TAG, "exception thrown creating a TrustManager: $e")
|
||||
return null
|
||||
}
|
||||
|
||||
for (manager in availableTrustManagers) {
|
||||
if (manager is X509TrustManager) {
|
||||
// Kotlin ensures this can't throw at runtime since it knows that
|
||||
// it must be the correct type by now.
|
||||
return X509TrustManagerExtensions(manager)
|
||||
}
|
||||
}
|
||||
|
||||
Log.e(TAG, "failed to find a usable trust manager")
|
||||
return null
|
||||
}
|
||||
|
||||
private fun makeLazyTrustManager(keystore: KeyStore?): Lazy<X509TrustManagerExtensions?> {
|
||||
// Ensure the keystore is loaded. Since all of the trust managers are initialized in a
|
||||
// `Lazy`, this will only run once.
|
||||
keystore?.load(null)
|
||||
|
||||
return lazy { createTrustManager(keystore) }
|
||||
}
|
||||
|
||||
// -- Test only --
|
||||
// Ideally, all of this will be optimized out at compile time due to not being accessed
|
||||
// in release builds.
|
||||
|
||||
@get:Synchronized
|
||||
private val mockKeystore: KeyStore = KeyStore.getInstance(KeyStore.getDefaultType())
|
||||
|
||||
@get:Synchronized
|
||||
private var mockTrustManager: Lazy<X509TrustManagerExtensions?> =
|
||||
makeLazyTrustManager(mockKeystore)
|
||||
|
||||
@JvmStatic
|
||||
private fun addMockRoot(root: ByteArray) {
|
||||
if (!BuildConfig.TEST) {
|
||||
throw Exception("attempted to add a mock root outside a test!")
|
||||
}
|
||||
|
||||
val alias = "root_${mockKeystore.size()}"
|
||||
// Throwing here is fine since test roots should always be well-formed
|
||||
val cert = certFactory.generateCertificate(ByteArrayInputStream(root))
|
||||
mockKeystore.setCertificateEntry(alias, cert)
|
||||
|
||||
reloadMockData()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun clearMockRoots() {
|
||||
// Reload to get a completely fresh internal state
|
||||
mockKeystore.load(null)
|
||||
reloadMockData()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun reloadMockData() {
|
||||
if (mockTrustManager.isInitialized()) {
|
||||
mockTrustManager = makeLazyTrustManager(mockKeystore)
|
||||
}
|
||||
}
|
||||
|
||||
// Get a list of the system's root CAs.
|
||||
// Function is public for testing only.
|
||||
@JvmStatic
|
||||
fun getSystemRootCAs(): List<X509Certificate> {
|
||||
val rootCAs = mutableListOf<X509Certificate>()
|
||||
|
||||
val factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
factory.init(systemKeystore)
|
||||
|
||||
val availableTrustManagers = try {
|
||||
factory.trustManagers
|
||||
} catch (e: RuntimeException) {
|
||||
Log.w(TAG, "exception thrown creating a TrustManager: $e")
|
||||
return rootCAs
|
||||
}
|
||||
|
||||
availableTrustManagers.forEach { trustManager ->
|
||||
if (trustManager is X509TrustManager) {
|
||||
rootCAs.addAll(trustManager.acceptedIssuers)
|
||||
}
|
||||
}
|
||||
|
||||
return rootCAs
|
||||
}
|
||||
|
||||
// -- End testing requirements --
|
||||
|
||||
private val certFactory: CertificateFactory = CertificateFactory.getInstance("X.509")
|
||||
|
||||
private var systemTrustAnchorCache = hashSetOf<Pair<X500Principal, PublicKey>>()
|
||||
|
||||
@get:Synchronized
|
||||
private var systemCertificateDirectory: File? = System.getenv("ANDROID_ROOT")?.let { rootPath ->
|
||||
File("$rootPath/etc/security/cacerts")
|
||||
}
|
||||
|
||||
@get:Synchronized
|
||||
private val systemKeystore: KeyStore? = try {
|
||||
KeyStore.getInstance("AndroidCAStore")
|
||||
} catch (_: KeyStoreException) {
|
||||
null
|
||||
}
|
||||
|
||||
@get:Synchronized
|
||||
private val systemTrustManager: Lazy<X509TrustManagerExtensions?> =
|
||||
makeLazyTrustManager(systemKeystore)
|
||||
|
||||
@JvmStatic
|
||||
private fun verifyCertificateChain(
|
||||
@Suppress("UNUSED_PARAMETER") context: Context,
|
||||
serverName: String,
|
||||
authMethod: String,
|
||||
allowedEkus: Array<String>,
|
||||
ocspResponse: ByteArray?,
|
||||
time: Long,
|
||||
certChain: Array<ByteArray>
|
||||
): VerificationResult {
|
||||
// Convert the array of (supposedly) DER bytes into certificates.
|
||||
val certificateChain = mutableListOf<X509Certificate>()
|
||||
certChain.forEach { certBytes ->
|
||||
val certificate = try {
|
||||
certFactory.generateCertificate(ByteArrayInputStream(certBytes))
|
||||
} catch (e: CertificateException) {
|
||||
return VerificationResult(StatusCode.InvalidEncoding)
|
||||
}
|
||||
certificateChain.add(certificate as X509Certificate)
|
||||
}
|
||||
|
||||
// Will never throw `ArrayIndexOutOfBoundsException` because `rustls`'s `ServerCertVerifier` trait
|
||||
// has a mandatory `end_entity` parameter in `verify_server_cert`.
|
||||
val endEntity = certificateChain[0]
|
||||
|
||||
// Check that the certificate is valid at the point of time provided by `rustls`.
|
||||
try {
|
||||
endEntity.checkValidity(Date(time))
|
||||
} catch (e: CertificateExpiredException) {
|
||||
return VerificationResult(StatusCode.Expired)
|
||||
} catch (e: CertificateNotYetValidException) {
|
||||
return VerificationResult(StatusCode.Expired)
|
||||
}
|
||||
|
||||
// Check that this certificate can be used in a TLS server.
|
||||
if (!verifyCertUsage(endEntity, allowedEkus)) {
|
||||
return VerificationResult(StatusCode.InvalidExtension)
|
||||
}
|
||||
|
||||
// Select the trust manager to use.
|
||||
//
|
||||
// We select them as follows:
|
||||
// - If built for release, only use the system trust manager. This should let all test-related
|
||||
// code be optimized out.
|
||||
// - If built for tests:
|
||||
// - If the mock CA store has any values, use the mock trust manager.
|
||||
// - Otherwise, use the system trust manager.
|
||||
val (trustManager, keystore) = if (!BuildConfig.TEST) {
|
||||
val trustManager =
|
||||
systemTrustManager.value ?: return VerificationResult(StatusCode.Unavailable)
|
||||
Pair(trustManager, systemKeystore)
|
||||
} else {
|
||||
if (mockKeystore.size() != 0) {
|
||||
val trustManager = mockTrustManager.value!!
|
||||
Pair(trustManager, mockKeystore)
|
||||
} else {
|
||||
val trustManager =
|
||||
systemTrustManager.value ?: return VerificationResult(StatusCode.Unavailable)
|
||||
Pair(trustManager, systemKeystore)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the certificate chain is valid and correct, and nothing more.
|
||||
//
|
||||
// NOTE: This does not validate `serverName` is valid for the end-entity certificate.
|
||||
// That is handled in Rust as Android/Java do not currently provide a RFC 6125 compliant
|
||||
// hostname verifier. Additionally, even the RFC 2818 verifier is not available until API 24.
|
||||
//
|
||||
// `serverName` is only used for pinning/CT requirements.
|
||||
//
|
||||
// Returns the "the properly ordered chain used for verification as a list of X509Certificates.",
|
||||
// meaning a list from end-entity certificate to trust-anchor.
|
||||
val validChain = try {
|
||||
trustManager.checkServerTrusted(certificateChain.toTypedArray(), authMethod, serverName)
|
||||
} catch (e: CertificateException) {
|
||||
// In test configurations we may see `checkServerTrusted` fail once vendored test
|
||||
// certificates pass their expiry date. We try to avoid that by using a fixed
|
||||
// verification time when calling `endEntity.checkValidity` above, however we can't
|
||||
// fix the time for the `checkServerTrusted` call.
|
||||
//
|
||||
// To make diagnosing CI test failures easier we try to find the root cause of
|
||||
// checkServerTrusted failing, returning a different `StatusCode` as appropriate.
|
||||
if (BuildConfig.TEST) {
|
||||
var rootCause: Throwable? = e
|
||||
while (rootCause?.cause != null && rootCause.cause != rootCause) {
|
||||
rootCause = rootCause.cause
|
||||
}
|
||||
return when (rootCause) {
|
||||
is CertificateExpiredException, is CertificateNotYetValidException -> VerificationResult(
|
||||
StatusCode.Expired,
|
||||
rootCause.toString()
|
||||
)
|
||||
|
||||
else -> VerificationResult(StatusCode.UnknownCert, rootCause.toString())
|
||||
}
|
||||
}
|
||||
// In non-test configurations we should have caught expiry errors earlier and
|
||||
// can simply return an unknown cert error without digging through the exception
|
||||
// cause chain.
|
||||
return VerificationResult(StatusCode.UnknownCert, e.toString())
|
||||
}
|
||||
|
||||
// TEST ONLY: Mock test suite cannot attempt to check revocation status if no OSCP data has been stapled,
|
||||
// because Android requires certificates to an specify OCSP responder for network fetch in this case.
|
||||
// If in testing w/o OCSP stapled, short-circuit here - only prior checks apply.
|
||||
if (BuildConfig.TEST && (mockKeystore.size() != 0) && (ocspResponse == null)) {
|
||||
return VerificationResult(StatusCode.Ok)
|
||||
}
|
||||
|
||||
// =================================================================================================
|
||||
// IMPORTANT! DIFF WITH THE ORIGINAL SOURCES HERE:
|
||||
//
|
||||
// We removed the cert revocation checks because Android won't do them by default
|
||||
// and supporting them would be quite difficult given CRLs won't work out of the box.
|
||||
//
|
||||
// See https://github.com/rustls/rustls-platform-verifier/issues/221 for more info.
|
||||
// =================================================================================================
|
||||
|
||||
return VerificationResult(StatusCode.Ok)
|
||||
}
|
||||
|
||||
private fun verifyCertUsage(certificate: X509Certificate, allowedEkus: Array<String>): Boolean {
|
||||
val ekus = try {
|
||||
certificate.extendedKeyUsage
|
||||
}
|
||||
// This should be unreachable, but could happen.
|
||||
catch (_: CertificateParsingException) {
|
||||
return false
|
||||
} catch (_: NullPointerException) {
|
||||
// According to Chromium's implementation, this can crash when the EKU data is malformed.
|
||||
Log.w(TAG, "exception handling certificate EKU")
|
||||
return false
|
||||
} ?: return true // If the list is empty, we have nothing to do.
|
||||
|
||||
return ekus.any { allowedEkus.contains(it) }
|
||||
}
|
||||
|
||||
// Android hashes a principal using the first four bytes of its MD5 digest, encoded in
|
||||
// lowercase hex and reversed.
|
||||
//
|
||||
// Ref: https://source.chromium.org/chromium/chromium/src/+/main:net/android/java/src/org/chromium/net/X509Util.java;l=339
|
||||
private fun hashPrincipal(principal: X500Principal): String {
|
||||
val hexDigits = "0123456789abcdef".toCharArray()
|
||||
val digest = MessageDigest.getInstance("MD5").digest(principal.encoded)
|
||||
val hexChars = CharArray(8)
|
||||
|
||||
for (i in 0..3) {
|
||||
// Kotlin doesn't support bitwise operators for bytes, only Int and Long.
|
||||
val digestByte = digest[3 - i].toInt()
|
||||
hexChars[2 * i] = hexDigits[(digestByte shr 4) and 0xf]
|
||||
hexChars[2 * i + 1] = hexDigits[digestByte and 0xf]
|
||||
}
|
||||
|
||||
return String(hexChars)
|
||||
}
|
||||
|
||||
// Check if CA root is known or not.
|
||||
// Known means installed in root CA store, either a preset public CA or a custom one installed by an enterprise/user.
|
||||
//
|
||||
// Ref: https://source.chromium.org/chromium/chromium/src/+/main:net/android/java/src/org/chromium/net/X509Util.java;l=351
|
||||
fun isKnownRoot(root: X509Certificate): Boolean {
|
||||
// System keystore and cert directory must be non-null to perform checking
|
||||
systemKeystore?.let { loadedSystemKeystore ->
|
||||
systemCertificateDirectory?.let { loadedSystemCertificateDirectory ->
|
||||
|
||||
// Check the in-memory cache first
|
||||
val key = Pair(root.subjectX500Principal, root.publicKey)
|
||||
if (systemTrustAnchorCache.contains(key)) {
|
||||
return true
|
||||
}
|
||||
|
||||
// System trust anchors are stored under a hash of the principal.
|
||||
// In case of collisions, append number.
|
||||
val hash = hashPrincipal(root.subjectX500Principal)
|
||||
var i = 0
|
||||
while (true) {
|
||||
val alias = "$hash.$i"
|
||||
|
||||
if (!File(loadedSystemCertificateDirectory, alias).exists()) {
|
||||
break
|
||||
}
|
||||
|
||||
val anchor = loadedSystemKeystore.getCertificate("system:$alias")
|
||||
|
||||
// It's possible for `anchor` to be `null` if the user deleted a trust anchor.
|
||||
// Continue iterating as there may be further collisions after the deleted anchor.
|
||||
if (anchor == null) {
|
||||
continue
|
||||
// This should never happen
|
||||
} else if (anchor !is X509Certificate) {
|
||||
// SAFETY: This logs a unique identifier (hash value) only in cases where a file within the
|
||||
// system's root trust store is not a valid X509 certificate (extremely unlikely error).
|
||||
// The hash doesn't tell us any sensitive information about the invalid cert or reveal any of
|
||||
// its contents - it just lets us ID the bad file if a user is having TLS failure issues.
|
||||
Log.e(TAG, "anchor is not a certificate, alias: $alias")
|
||||
continue
|
||||
// If subject and public key match, it's a system root.
|
||||
} else {
|
||||
if ((root.subjectX500Principal == anchor.subjectX500Principal) && (root.publicKey == anchor.publicKey)) {
|
||||
systemTrustAnchorCache.add(key)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not found in cache or store: non-public
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,6 @@ val excludedKoverSubProjects = listOf(
|
||||
":libraries:core",
|
||||
":libraries:coroutines",
|
||||
":libraries:di",
|
||||
":libraries:rustls-tls",
|
||||
":tests:detekt-rules",
|
||||
":tests:konsist",
|
||||
":tests:testutils",
|
||||
|
||||
@@ -17,6 +17,16 @@ pluginManagement {
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven {
|
||||
url = uri("https://github.com/rustls/rustls-platform-verifier/raw/maven-archive/android-release-support/maven/")
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeModule("org.rustls", "rustls-platform-verifier")
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url = uri("https://www.jitpack.io")
|
||||
content {
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (c) 2026 Element Creations Ltd.
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
# Please see LICENSE files in the repository root for full details.
|
||||
|
||||
"""
|
||||
Update the rustls-platform-verifier dependency to the given version and regenerate
|
||||
app/src/main/res/xml/network_security_config.xml.
|
||||
|
||||
The rustls-platform-verifier AAR ships a network_security_config.xml allowing cleartext traffic
|
||||
to the domains used by certificate authorities to publish their CRLs. Since the app has its own
|
||||
network security config, those domains are merged into a copy of network_security_config_element.xml.
|
||||
|
||||
Usage: ./tools/dependencies/update_rustls_platform_verifier.py <version>
|
||||
"""
|
||||
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ET
|
||||
import zipfile
|
||||
|
||||
ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
LIBS_VERSIONS_TOML = os.path.join(ROOT_DIR, "gradle", "libs.versions.toml")
|
||||
XML_DIR = os.path.join(ROOT_DIR, "app", "src", "main", "res", "xml")
|
||||
SOURCE_CONFIG = os.path.join(XML_DIR, "network_security_config_element.xml")
|
||||
TARGET_CONFIG = os.path.join(XML_DIR, "network_security_config.xml")
|
||||
|
||||
AAR_URL = (
|
||||
"https://raw.githubusercontent.com/rustls/rustls-platform-verifier/maven-archive/android-release-support/"
|
||||
"maven/org/rustls/rustls-platform-verifier/{version}/rustls-platform-verifier-{version}.aar"
|
||||
)
|
||||
AAR_CONFIG_PATH = "res/xml/network_security_config.xml"
|
||||
|
||||
CLEARTEXT_DOMAIN_CONFIG_REGEX = re.compile(
|
||||
r'(<domain-config\s+cleartextTrafficPermitted="true"\s*>.*?)(\n?[ \t]*</domain-config>)',
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def update_libs_versions(version):
|
||||
with open(LIBS_VERSIONS_TOML, "r") as f:
|
||||
content = f.read()
|
||||
new_content, count = re.subn(
|
||||
r'^(rustls_platform_verifier\s*=\s*"org\.rustls:rustls-platform-verifier:)[^"]+(")',
|
||||
rf"\g<1>{version}\g<2>",
|
||||
content,
|
||||
flags=re.MULTILINE,
|
||||
)
|
||||
if count != 1:
|
||||
sys.exit(f"Error: could not find the rustls_platform_verifier dependency in {LIBS_VERSIONS_TOML}")
|
||||
with open(LIBS_VERSIONS_TOML, "w") as f:
|
||||
f.write(new_content)
|
||||
print(f"Updated rustls_platform_verifier to {version} in {os.path.relpath(LIBS_VERSIONS_TOML, ROOT_DIR)}")
|
||||
|
||||
|
||||
def download_aar(version):
|
||||
url = AAR_URL.format(version=version)
|
||||
print(f"Downloading {url}")
|
||||
try:
|
||||
with urllib.request.urlopen(url) as response:
|
||||
return response.read()
|
||||
except urllib.error.HTTPError as e:
|
||||
sys.exit(f"Error: could not download the AAR for version {version} ({e.code} {e.reason})")
|
||||
|
||||
|
||||
def extract_cleartext_domains(aar_bytes):
|
||||
with zipfile.ZipFile(io.BytesIO(aar_bytes)) as aar:
|
||||
try:
|
||||
config = aar.read(AAR_CONFIG_PATH)
|
||||
except KeyError:
|
||||
sys.exit(f"Error: {AAR_CONFIG_PATH} not found in the AAR")
|
||||
root = ET.fromstring(config)
|
||||
domains = []
|
||||
for domain_config in root.iter("domain-config"):
|
||||
if domain_config.get("cleartextTrafficPermitted") != "true":
|
||||
continue
|
||||
for domain in domain_config.findall("domain"):
|
||||
domains.append((domain.get("includeSubdomains"), domain.text.strip()))
|
||||
if not domains:
|
||||
sys.exit("Error: no cleartext domains found in the AAR network_security_config.xml")
|
||||
return domains
|
||||
|
||||
|
||||
def write_network_security_config(domains, version):
|
||||
with open(SOURCE_CONFIG, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
lines = [
|
||||
"",
|
||||
"",
|
||||
f" <!-- Domains below are imported from rustls-platform-verifier {version} by tools/dependencies/update_rustls_platform_verifier.py -->",
|
||||
" <!-- They are needed to fetch the certificate revocation lists over cleartext -->",
|
||||
]
|
||||
for include_subdomains, name in domains:
|
||||
attributes = f' includeSubdomains="{include_subdomains}"' if include_subdomains is not None else ""
|
||||
lines.append(f" <domain{attributes}>{name}</domain>")
|
||||
extra = "\n".join(lines)
|
||||
|
||||
new_content, count = CLEARTEXT_DOMAIN_CONFIG_REGEX.subn(lambda m: m.group(1) + extra + m.group(2), content, count=1)
|
||||
if count != 1:
|
||||
sys.exit(f'Error: could not find <domain-config cleartextTrafficPermitted="true"> in {SOURCE_CONFIG}')
|
||||
|
||||
with open(TARGET_CONFIG, "w") as f:
|
||||
f.write(new_content)
|
||||
print(f"Wrote {os.path.relpath(TARGET_CONFIG, ROOT_DIR)} with {len(domains)} extra domains")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2:
|
||||
sys.exit(f"Usage: {sys.argv[0]} <version>")
|
||||
version = sys.argv[1].strip()
|
||||
if not re.fullmatch(r"[0-9A-Za-z.\-]+", version):
|
||||
sys.exit(f"Error: invalid version '{version}'")
|
||||
|
||||
# Download first, so nothing is modified if the version does not exist
|
||||
aar_bytes = download_aar(version)
|
||||
domains = extract_cleartext_domains(aar_bytes)
|
||||
update_libs_versions(version)
|
||||
write_network_security_config(domains, version)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -42,6 +42,8 @@
|
||||
<ignore path="**/src/debug/**" />
|
||||
<!-- Ignore unused resources in designsystem since they're imported elsewhere through aliases and can't be properly detected -->
|
||||
<ignore path="**/libraries/designsystem/src/main/res/**" />
|
||||
<!-- Ignore the network security config template: this will be merged with rustls's security config -->
|
||||
<ignore path="**/src/main/res/xml/network_security_config_element.xml" />
|
||||
</issue>
|
||||
|
||||
<!-- UX -->
|
||||
|
||||
Reference in New Issue
Block a user