Repository navigation
fix: install security provider before tls use - #1416
Conversation
|
@Jasonvdb is this critical for next release? it kinda seems so to me, pls db check and lmk. it's currently on 2.6.0 milestone because I consider(ed) it critical |
|
@ovitrif Yes, I'd treat it as critical for 2.6.0. On master, Paykit refused every TLS connection for the rest of the session after 9 of 10 cold launches while signed in to Pubky (emulator, master 6ba44a4). With this change it was 0 of 10. Once it fails, contact payments and Pubky profile reads stop working until the app is restarted. It fails closed (TLS is refused, never weakened), so it isn't a security hole, but it's a broken feature for most signed-in launches. Caveat: I only measured on an emulator. On a fast phone the race window may be smaller. The fix only changes the order of security provider set-up at start-up. |
|
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
|
@ovi-reviewer review |
There was a problem hiding this comment.
Suggestion: 👍 Approve
Review: diff 4 files.
This fixes an Android provider startup race. iOS uses CryptoKit and secp256k1 without Java provider changes. iOS already uses the same Paykit rc56 through synonymdev/bitkit-ios#823, so it needs no matching change.
Findings:
2 inline (1 MEDIUM, 1 LOW)
QA:
Tests queued.
Replies:
@Jasonvdb: Yes, I’d treat it as critical for 2.6.0. (comment)
The reported session-long TLS failure blocks contact payments and Pubky profile reads, so this belongs in 2.6.0.
The review is complete. The ten online cold launches still need device testing.
Reviewed by gpt-6.1-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest
|
@ovi-reviewer review |
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Keep them coming! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
Suggestion: 👍 Approve
Reaudit: diff 2 files.
No new findings; the rest is in the review.
This delta restores an Android startup note and adds an Android Hilt regression test; no shared protocol or iOS behavior changes.
QA:
Tests running.
Replies:
@chatgpt-codex-connector: Codex Review Summary (comment)
That status concerns the separate Codex review. This reaudit is complete; the cold-launch check still awaits device testing.
Reviewed by gpt-6.1-sol-medium via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Verdict: ✅ Approve
Tests for the review: Test 1 passes.
QA:
Tested on Android 15 emulator.
🟢 Test 1
Test 1
Ten online cold launches while signed in produced no BKS not found or CertificateVerifier errors.
1.mp4 |
![]() | ![]() |
Checked Manual Test 1 in the PR description.
Reviewed by gpt-6.1-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest


Closes #1425
This PR installs the bundled BouncyCastle security provider as the first step of
App.onCreate, so swapping security providers can no longer race paykit's first TLS connection at start-up.I found this while testing #1399. It is older than that PR: master fails at the same rate.
Description
Crypto.installSecurityProvider()and calls it beforesuper.onCreate()inApp, where Hilt has not built anything yet, so the swap finishes before any service can open a connection.Crypto's constructor still calls it, and that second call finds BouncyCastle in place and does nothingRoot cause
Crypto'sinitruns on the main thread when MainActivity's ViewModels are created. It removed Android's built-in "BC" provider and only then constructedBouncyCastleProvider(), which took 0.8–1.1 s on the emulator. During that time no provider offered "BKS".App.onCreate→super.onCreate()injectsPubkyAuthHandlerRegistrar→PubkyRepo.init→PaykitSdkService.initialize(), which launchesrepublishIdentityIfNeeded(). That makes paykit's first HTTPS call on an IO thread 1.6–2.8 s after process start.rustls-platform-verifier. The static initialiser oforg.rustls.platformverifier.CertificateVerifierstarts withKeyStore.getInstance(KeyStore.getDefaultType()), and the default type on Android is "BKS". Inside the window it throwsKeyStoreException: BKS not found, the class is marked as failed for the whole process, and every later paykit certificate check throwsNoClassDefFoundErroruntil the app restarts.Measurements
These were online cold launches on an Android emulator while signed in to a Pubky profile. A launch counts as broken when logcat shows
BKS not foundor theNoClassDefFoundError.Crypto.ktis unchanged andApponly gainedSubscriptionClockOffsetSync, but the change has not been re-measured on that base.App.onCreate. Push starts already did, becauseFcmServiceinjectsCrypto.Security
Appcovers all of them.Out of Scope
Crypto.kt: putting the full BouncyCastle first in the global provider list changes JCA choices for the whole process. For example, paykit'sCertPathValidator.getInstance("PKIX")resolves to BouncyCastle after the swap. The cleaner long-term fix is a privateBouncyCastleProviderinstance passed explicitly toCrypto'sgetInstancecalls for key generation, key factories and ECDH. TheCiphercalls should get it too: without BouncyCastle first they would resolve to Conscrypt, which might reject Blocktank's 16-byte GCM IVs. That needs its own tests, so it is left for a follow-up.Design
N/A — no UI changes.
Preview
N/A
QA Notes
Journeys
N/A — not drivable; see Manual Tests.
Manual Tests
BKS not foundand noCertificateVerifiererror on any launch — repeated cold launches checked through logcat are not in CapabilitiesAutomated Checks
CryptoTest.kt—installSecurityProvideradds BouncyCastle when no BC provider exists, replaces an outdated BC provider at position 1, and leaves the installed provider in place on later calls, including the one fromCrypto's constructor