Skip to content

Improve CRL retrieval and fix poisoned cache - #833

Merged
mickael-menu merged 3 commits into
developfrom
fix/crl
Sep 11, 2026
Merged

mickael-menu merged 3 commits into
developfrom
fix/crl

Conversation

@mickael-menu

@mickael-menu mickael-menu commented Sep 9, 2026

Copy link
Copy Markdown
Member

Changed

LCP

  • Opening an LCP publication is no longer delayed by the CRL used to validate its license. The CRL is now downloaded when creating the LcpService, and an expired one is refreshed in the background instead of making the user wait for the response.

Fixed

LCP

  • #832 The CRL used to validate LCP licenses is now checked to be a genuine X.509 CRL before being cached. Networks with a captive portal (e.g. on a plane) could return their login page with a 200 OK status, which was then cached for seven days and prevented opening LCP publications. An invalid CRL cached by a previous version is now ignored instead of waiting for its expiration.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new Crl.kt uses experimental kotlin.io.encoding.Base64 without opting in, and the updated test suite should clear shared preferences between cases to avoid order-dependent failures.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR addresses LCP publications failing to open when a captive portal response (HTML with HTTP 200) was mistakenly cached as the CRL, by validating CRL payloads as genuine X.509 CRLs before caching and by ignoring previously cached invalid CRLs.

Changes:

  • Added a Crl value class to parse/validate DER- and PEM-encoded CRLs using CertificateFactory.
  • Updated CRLService to validate the fetched CRL before caching and to ignore invalid cached CRLs.
  • Expanded Robolectric test coverage for valid/invalid CRLs (including legacy wrapped Base64) and documented the fix in the changelog.
File summaries
File Description
readium/lcp/src/test/java/org/readium/r2/lcp/service/CRLServiceTest.kt Adds fixtures and new tests covering valid CRL caching, captive portal HTML rejection, and legacy wrapped Base64 handling.
readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt Validates fetched/cached CRLs and prevents caching invalid responses; introduces a shared CRL URL constant.
readium/lcp/src/main/java/org/readium/r2/lcp/service/Crl.kt New validated CRL wrapper providing DER→PEM conversion and PEM parsing with X.509 CRL verification.
CHANGELOG.md Adds an LCP entry describing the captive-portal/CRL-cache fix (issue #832).
Review details
  • Files reviewed: 4/5 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread readium/lcp/src/main/java/org/readium/r2/lcp/service/Crl.kt
Comment thread readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There is at least one compile-blocking issue (missing opt-in for experimental kotlin.io.encoding.Base64) plus an unresolved lifecycle concern for the newly introduced long-lived coroutine scope.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

readium/lcp/src/main/java/org/readium/r2/lcp/service/Crl.kt:12

  • kotlin.io.encoding.Base64 is still experimental; this file uses Base64.encode/Base64.Mime.decode without opting in to ExperimentalEncodingApi, which can fail compilation (and diverges from the existing pattern used elsewhere in the module).
import kotlin.io.encoding.Base64
import org.readium.r2.lcp.BuildConfig.DEBUG
  • Files reviewed: 5/6 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt
@mickael-menu mickael-menu changed the title Fix LCP publications failing to open after a captive portal poisoned the CRL cache Improve CRL retrieval and fix poisoned cache Sep 9, 2026
@panaC

panaC commented Sep 10, 2026

Copy link
Copy Markdown
Member

Cross-reference with ThDk edrlab/thorium-reader#3865

@mickael-menu
mickael-menu merged commit 3c0d17a into develop Sep 11, 2026
5 checks passed
@mickael-menu
mickael-menu deleted the fix/crl branch September 11, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LCP SDK caches captive portal HTML as CRL when device is offline

3 participants