Skip to content

Fix iOS Certificate Validation Issue for Tendermint Balance Streaming#2674

Merged
onur-ozkan merged 4 commits intodevfrom
wss-cert-fix
Oct 31, 2025
Merged

Fix iOS Certificate Validation Issue for Tendermint Balance Streaming#2674
onur-ozkan merged 4 commits intodevfrom
wss-cert-fix

Conversation

@smk762
Copy link
Copy Markdown

@smk762 smk762 commented Oct 31, 2025

🐛 Problem

iOS devices were encountering Invalid certificate: UnknownIssuer errors when connecting to Tendermint balance streaming WebSocket endpoints. This prevented proper functionality of balance streaming on iOS platforms.

30 20:03:41, coins::tendermint::tendermint_balance_events:103] ERROR Couldn't connect to 'wss://cosmos-rpc.alpha.komodo.earth/websocket': IO error: invalid peer certificate contents: invalid peer certificate: UnknownIssuer
30 20:03:41, rustls::conn:1274] WARN Sending fatal alert BadCertificate

Error Details:

30 20:03:41, coins::tendermint::tendermint_balance_events:103] ERROR Couldn't connect to 'wss://cosmos-rpc.alpha.komodo.earth/websocket': IO error: invalid peer certificate contents: invalid peer certificate: UnknownIssuer

Root Cause: The current tokio-tungstenite-wasm dependency was using an outdated certificate validation mechanism that doesn't recognize the newer Let's Encrypt ECDSA certificate chain (E7 → ISRG Root X1) used by modern servers.

🔧 Solution

Updated the TLS certificate validation to use the embedded webpki-roots certificate store instead of native system roots, ensuring compatibility with the latest Let's Encrypt ECDSA certificates.

📋 Changes Made

1. Updated tokio-tungstenite-wasm TLS Features

  • File: Cargo.toml (line 200)
  • Change: rustls-tls-native-rootsrustls-tls-webpki-roots
  • Reason: Uses embedded certificate store with latest Let's Encrypt certificates

2. Updated Coins Package Dependencies

  • File: mm2src/coins/Cargo.toml (line 121)
  • Change: Updated tokio-tungstenite-wasm features to use rustls-tls-webpki-roots

3. Updated webpki-roots Version

  • File: Cargo.toml (line 215)
  • Change: Version 0.250.26
  • Reason: Includes newer Let's Encrypt ECDSA certificate chain support

4. Fixed Rustls API Compatibility

  • File: mm2src/coins/utxo/rpc_clients/electrum_rpc/tcp_stream.rs
  • Change: Updated API calls for newer rustls version
  • Details: Fixed field names (spkisubject_public_key_info) and ownership issues

5. Fixed mm2_p2p Dependency Configuration

  • File: mm2src/coins/Cargo.toml (line 88)
  • Change: Added application feature to mm2_p2p dependency
  • Reason: Exposed existing configuration inconsistency during dependency updates

🧪 Testing

  • Coins package compilation: Successful
  • Full workspace compilation: Successful
  • No regressions: All existing functionality maintained
  • 🔄 iOS device testing: Ready for validation

📚 Background

This follows the same pattern as the previous certificate fix (commit 76a34cc) which resolved similar issues with hyper-rustls by using webpki-tokio features to avoid certificate validation problems on iOS.

🎯 Expected Results

After this fix:

  • ✅ iOS devices should successfully connect to Tendermint balance streaming endpoints
  • ✅ WebSocket connections will properly validate Let's Encrypt ECDSA certificates
  • ✅ No impact on other platforms or existing functionality
  • ✅ Future-proofed against similar certificate chain updates

🔗 Related Issues

Fixes #2673 - Invalid certificate: UnknownIssuer with tendermint balance streaming on iOS

📝 Notes

The mm2_p2p dependency change was not directly related to the certificate fix but was an existing configuration issue exposed during the dependency updates. The application feature is required for proper compilation of the coins package with mm2_p2p.


Testing Instructions for Reviewers:

  1. Build the project and verify no compilation errors
  2. Test Tendermint balance streaming on iOS devices
  3. Verify WebSocket connections to servers using Let's Encrypt ECDSA certificates
  4. Confirm no regressions in existing functionality

@smk762 smk762 self-assigned this Oct 31, 2025
@onur-ozkan
Copy link
Copy Markdown

Using webpki is a bad path for us because we don't update dependencies often, meaning, we will be stuck on the same roots for too long.

Does this problem happen witg any RPC nodes, or is it specific to just a few ones? We need to avoid this change if an alternative exists. Worst case, this change should be strictly an iOS build-specific fix.

@smk762
Copy link
Copy Markdown
Author

smk762 commented Oct 31, 2025

Using webpki is a bad path for us because we don't update dependencies often, meaning, we will be stuck on the same roots for too long.

Does this problem happen witg any RPC nodes, or is it specific to just a few ones? We need to avoid this change if an alternative exists. Worst case, this change should be strictly an iOS build-specific fix.

Right now it could happen with any tendermint server using modern certs. Though I can downgrade the ones I operate, we cant reasonably expect the same from others.

This change brings tendermint into line with existing cert handling for everything else following a similar update in 2021 for the same ios specific issue.

@onur-ozkan
Copy link
Copy Markdown

To reduce the scope of potential issues, can you make the webpki change only for IOS platform?

Comment on lines +86 to +90
.map(|ta| OwnedTrustAnchor::from_subject_spki_name_constraints(ta.subject, ta.spki, ta.name_constraints)),
.map(|ta| OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject.to_vec(),
ta.subject_public_key_info.to_vec(),
ta.name_constraints.as_ref().map(|nc| nc.to_vec())
)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

does this work with native certs?

winapi.workspace = true

# iOS-specific dependencies to fix certificate validation issues
[target.'cfg(target_os = "ios")'.dependencies]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

since we re adding this as a iOS specific override this means both are active since rustls-tls-native-roots is enabled by the gen dependency. so if we want to differentiate platform wise we d need "per target" sections for diff. between native and webpki.

alternatively (how i tested in a local fix): we just update it to webpki globally cc @onur-ozkan whats preferred / more solid from?

Copy link
Copy Markdown

@onur-ozkan onur-ozkan Oct 31, 2025

Choose a reason for hiding this comment

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

If we must use webpki for IOS, I suggest doing it for IOS only and keep native roots for others (as we have no issues with it, at least so far?). Relying on OS roots are better than relying on the roots that are bundled with the dependency which will not be updated for a quite long time (we don't update our deps very often).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

thanks - will update this PR accordingly to handle it platform-specific shortly and keep the native everywhere else as there weren't any issues with it (yet)

@cipig
Copy link
Copy Markdown

cipig commented Oct 31, 2025

coins::utxo::rpc_clients::electrum_rpc::connection_manager::manager:440] ERROR Failed to establish connection to electrum.seed.mazanode.com:50002 due to error: Temporary("Couldn't connect to the electrum server: Custom { kind: InvalidData, error: InvalidCertificate(UnknownIssuer) }")
on Desktop, from https://electrum.seed.mazanode.com:50005/ with a valid cert, just not from letsencrypt
image
but it's the only one i found that shows "UnknownIssuer"

onur-ozkan
onur-ozkan previously approved these changes Oct 31, 2025
Copy link
Copy Markdown

@onur-ozkan onur-ozkan left a comment

Choose a reason for hiding this comment

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

LGTM

@onur-ozkan
Copy link
Copy Markdown

Waiting for build pipelines to finish for merge.

@onur-ozkan onur-ozkan merged commit bebdc9a into dev Oct 31, 2025
15 of 26 checks passed
@onur-ozkan onur-ozkan deleted the wss-cert-fix branch October 31, 2025 14:58
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.

4 participants