Skip to content

Commit 4fd6f2f

Browse files
authored
fix(network): 🔒 trust user-installed CAs for custom/internal CA servers (#80) (#81)
Self-hosters fronting Calibre-web/OPDS/sync/AI with a private or internal CA hit 'Trust anchor for certification path not found' because, on API 24+, apps trust system CAs only by default — even when the device browser, which trusts user-installed CAs, connects fine. Add a network-security-config whose base-config trusts both system and user CAs, applied app-wide. Every network path (OkHttp clients, Readium's DefaultHttpClient) uses platform-default trust, so this single config covers them all with no Kotlin changes. Fixed third-party public hosts (openlibrary.org + covers) are pinned back to system-only so they don't inherit the user-CA trust expansion. cleartextTrafficPermitted is intentionally left unset: targetSdk 34 already disables cleartext by default. Closes #80
1 parent bda06ed commit 4fd6f2f

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

‎app/src/main/AndroidManifest.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
android:icon="@mipmap/ic_launcher"
1313
android:roundIcon="@mipmap/ic_launcher_round"
1414
android:label="@string/app_name"
15+
android:networkSecurityConfig="@xml/network_security_config"
1516
android:theme="@style/Theme.Quire">
1617
<!-- configChanges keeps the Activity alive across rotation/keyboard/navigation
1718
changes. Required because EpubNavigatorFragment has no no-arg constructor:
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Trust user-installed CAs in addition to system CAs (issue #80).
4+
5+
Quire connects to arbitrary, user-configured servers (Calibre-web, OPDS,
6+
sync, AI). Self-hosters commonly front those with a private/internal CA that
7+
lives in the device's *user* CA store. On API 24+ apps trust system CAs only
8+
by default, so without this Quire fails such servers with
9+
"Trust anchor for certification path not found" even though the browser
10+
(which does trust user CAs) connects fine.
11+
12+
This is a deliberate, bounded trust expansion appropriate for a self-hosted
13+
app: only CAs the device owner installed themselves are honored, and modern
14+
Android (11+) requires CA installation to go through Settings. The hosts can't
15+
be enumerated at build time, so a global base-config is the only practical
16+
option.
17+
18+
cleartextTrafficPermitted is intentionally left unset: with targetSdk 34 the
19+
platform default already disables cleartext, so omitting it keeps current
20+
behavior without hardcoding.
21+
22+
Fixed third-party public endpoints (Open Library metadata + covers) are pinned
23+
back to system-only — they're served by public CAs and never need a private
24+
CA, so they shouldn't inherit the user-CA trust expansion.
25+
-->
26+
<network-security-config>
27+
<base-config>
28+
<trust-anchors>
29+
<certificates src="system" />
30+
<certificates src="user" />
31+
</trust-anchors>
32+
</base-config>
33+
34+
<domain-config>
35+
<domain includeSubdomains="true">openlibrary.org</domain>
36+
<trust-anchors>
37+
<certificates src="system" />
38+
</trust-anchors>
39+
</domain-config>
40+
</network-security-config>

0 commit comments

Comments
 (0)