Conversation
Member
Author
flowchart TD
A[App startup / main.ts] --> B[Import BUILD_CRL + BUILD_CRL_CACHED_AT]
B --> C[Create LcpCrlCache]
C --> D[Seed memory cache]
D --> E[memoryCrl = BUILD_CRL]
E --> F[cachedAt = BUILD_CRL_CACHED_AT]
F --> G[Install setCRLGetter]
G --> H[Call preload]
H --> I[readMemory]
I --> J{Memory CRL exists?}
J -- no --> K[Start network refresh in background]
J -- yes --> L{Is memory CRL expired?}
L -- no --> M[Do nothing]
L -- yes --> K
K --> N{Fetch succeeds and response is X.509 CRL?}
N -- yes --> O[Encode DER to PEM]
O --> P[Replace memoryCrl]
P --> Q[cachedAt = Date.now]
N -- no --> R[Keep existing memory CRL]
S[Open / unlock LCP publication] --> T[LCP calls setCRLGetter]
T --> U[LcpCrlCache.retrieve]
U --> V[readMemory]
V --> W{Memory CRL exists?}
W -- no --> X[Await network refresh]
X --> Y{Fetch succeeds and response is X.509 CRL?}
Y -- yes --> Z[Save fresh CRL in memory]
Z --> AA[Return fresh CRL to liblcp]
Y -- no --> AB[Throw CRL fetch error]
W -- yes --> AC{Is memory CRL expired?}
AC -- no --> AD[Return memory CRL immediately]
AC -- yes --> AE[Start/reuse refresh in background]
AE --> AF[Return expired memory CRL immediately]
|
panaC
commented
Sep 14, 2026
| kUiV/PFCwL66iiF666DrXLY= | ||
| /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| // run this at each new build to update the CRL: | ||
| node -e "const url='http://crl.edrlab.telesec.de/rl/EDRLab_CA.crl'; const tick=String.fromCharCode(96); const now=Date.now(); fetch(url).then(async r=>{ if(!r.ok) throw new Error('HTTP '+r.status); const buf=Buffer.from(await r.arrayBuffer()); const b64=buf.toString('base64').match(/.{1,64}/g).join('\n'); console.log('// Build-time CRL fallback generated from CRL_URL on '+new Date(now).toISOString()+'.'); console.log('export const BUILD_CRL_CACHED_AT = '+now+';'); console.log('export const BUILD_CRL = '+tick+'-----BEGIN X509 CRL-----\n'+b64+'\n-----END X509 CRL-----'+tick+';'); }).catch(e=>{ console.error(e); process.exit(1); });" |
Member
Author
There was a problem hiding this comment.
before each release build we have to refresh the static CRL
Member
Author
There was a problem hiding this comment.
> node -e "const url='http://crl.edrlab.telesec.de/rl/EDRLab_CA.crl'; const tick=String.fromCharCode(96); const now=Date.now(); fetch(url).then(async r=>{ if(!r.ok) throw new Error('HTTP '+r.status); const buf=Buffer.from(await r.arrayBuffer()); const b64=buf.toString('base64').match(/.{1,64}/g).join('\n'); console.log('// Build-time CRL fallback generated from CRL_URL on '+new Date(now).toISOString()+'.'); console.log('export const BUILD_CRL_CACHED_AT = '+now+';'); console.log('export const BUILD_CRL = '+tick+'-----BEGIN X509 CRL-----\n'+b64+'\n-----END X509 CRL-----'+tick+';'); }).catch(e=>{ console.error(e); process.exit(1); });"
// Build-time CRL fallback generated from CRL_URL on 2026-09-14T10:04:49.729Z.
export const BUILD_CRL_CACHED_AT = 1789380289729;
export const BUILD_CRL = `-----BEGIN X509 CRL-----
MIICkTCCAXkCAQEwDQYJKoZIhvcNAQELBQAwQjETMBEGA1UEChMKZWRybGFiLm9y
ZzEXMBUGA1UECxMOZWRybGFiLm9yZyBMQ1AxEjAQBgNVBAMTCUVEUkxhYiBDQRcN
MjYwOTEzMTQxNzA4WhcNMjYwOTE4MTQxNzA3WjCB0DAnAgg9/PrnYyy4ABcNMjYw
ODA1MjAyMTEzWjAMMAoGA1UdFQQDCgEBMCgCCQCoPyWN9DqSBhcNMjYwNTI1MDc1
NTAwWjAMMAoGA1UdFQQDCgEGMCgCCQCwrtK1lYNPKhcNMjYwODI4MTcyNzQ1WjAM
MAoGA1UdFQQDCgEGMCcCCAD7am95HSWbFw0yNjAzMjMxMjQ1NThaMAwwCgYDVR0V
BAMKAQYwKAIJAKjr9Zx5OfipFw0yNjAyMTIxMDE0MDJaMAwwCgYDVR0VBAMKAQag
MDAuMB8GA1UdIwQYMBaAFNxc/JPkH5/usLrqUgsrylJc4MmHMAsGA1UdFAQEAgIN
/jANBgkqhkiG9w0BAQsFAAOCAQEAhHCfMKjWaIORdex9iYL2WYOK/qOyRegPa+uT
TeS6SAqFPwT8EWuo0aa9dSt2GXtMNfPEmOyxioVvhV2gfYyjbmoDyUJDlkySUAcO
c4voHAuf4wT2y1GzuvI4pQNn3KkZu35HrWBy5pMFwrBkTSRlbTtYESpWlXAezrmD
YN/kMSjDLSyan15L9r1Hkp1gKMxTluUByQW4pm1zY3MR19Gkew8RivQWt5yPUfCD
3+HMgBYMnbHmxpUPi3LyfswTiMZxNT2BHiHy6Qdg3uC25tTQs3sq5ih1ErRMuCl/
MVZZnnZh4KBBFzgcZsSFf8Kggn5SW9BUZRGN4QHuAY9Sma4fAQ==
-----END X509 CRL-----`;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3864
Revert 260ab54
Target PR #3825
This PR replaces the LCP CRL refresh logic with a memory-only cache model inspired by readium/swift-toolkit#894.
Swift uses readLocal() backed by UserDefaults. In Thorium/Electron, the equivalent is readMemory(), because persisting the CRL in userData would create a mutable local trust input unless we also verify the CRL signature/authenticity before loading it.
The model is simple: at startup, the cache is seeded with BUILD_CRL and BUILD_CRL_CACHED_AT. preload() calls readMemory(); if the memory CRL is missing or expired, it starts a network refresh in the background. During LCP unlock, retrieve() calls readMemory(); if the CRL is fresh, it returns it immediately. If it is expired, it still returns it immediately and refreshes in the background. Only if there is no memory CRL at all does unlock wait for the network refresh.
The workaround for avoiding disk persistence is the build-time CRL fallback. BUILD_CRL acts as the default local CRL, and BUILD_CRL_CACHED_AT lets the normal freshness logic decide when it should be refreshed. This keeps offline/startup behavior safe enough without trusting a user-writable filesystem cache.
The fetched CRL is still checked with isX509Crl() before replacing the memory cache. This mirrors the Swift guard: it rejects HTML/captive portal responses, truncated data, and trailing garbage. It is not a cryptographic signature verification.
If we later add disk persistence, the disk CRL must be treated as untrusted input and validated cryptographically before being promoted into memory.