wallet2: preserve required SSL when allowing chained certificates
What changed, and why it matters
This small patch fixes a logic bug in how the Monero wallet decides whether SSL/TLS is required when connecting to a daemon. Previously, the wallet only treated SSL as required when the user explicitly pinned a specific certificate ('user_certificates' mode). If the user supplied a custom CA file or allowed certificate fingerprints, the code did not mark SSL as required, which could let the wallet silently fall back to an unencrypted connection in some situations. The fix introduces a separate flag so that supplying a CA file or fingerprints now correctly forces SSL to be required, preserving the user's intended security setting.
Treat as a security-hardening fix with possible confidentiality impact. Users who configured --daemon-ssl-ca-file or --daemon-ssl-allowed-fingerprints without also explicitly setting --daemon-ssl should upgrade, because prior versions may not have enforced SSL in that configuration. Review whether the downstream epee SSL client can fall back to plaintext when support is only 'enabled' rather than 'required', which would determine if this is a practical downgrade vulnerability.
Security signals we found
Logic bug in SSL requirement determination
Custom CA / fingerprint paths did not force SSL enforcement
Potential silent downgrade from intended encrypted connection
Patch is partial/small (3 lines) and conservative
Evidence from the diff
In src/wallet/wallet2.cpp::make_basic(), the original condition ssl_options.verification != e_ssl_verification_t::user_certificates || !is_arg_defaulted(...) was too narrow: it only required SSL when the user had set user_certificates verification. The branch that sets verification to user_ca (custom CA file) or user_fingerprint (allowed fingerprints) did not set any corresponding ‘required’ state. The patch adds a boolean ssl_required set to true in those branches and changes the guard to !ssl_required || !is_arg_defaulted(...). This ensures that when a user provides a CA file or fingerprints, the daemon_ssl argument is validated and SSL support is enforced rather than potentially remaining at the default ‘enabled’ (which may still permit plaintext fallback depending on downstream behavior).
Changed components
src/wallet/wallet2.cppwallet2::make_basic() SSL initialization pathdaemon SSL option handlingInspect captured patch +3 / −1
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index fadfb9f..a92919a 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -348,11 +348,13 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
auto daemon_ssl = command_line::get_arg(vm, opts.daemon_ssl);
// user specified CA file or fingerprints implies enabled SSL by default
+ bool ssl_required = false;
epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_enabled;
if (daemon_ssl_allow_any_cert)
ssl_options.verification = epee::net_utils::ssl_verification_t::none;
else if (!daemon_ssl_ca_file.empty() || !daemon_ssl_allowed_fingerprints.empty())
{
+ ssl_required = true;
std::vector<std::vector<uint8_t>> ssl_allowed_fingerprints{ daemon_ssl_allowed_fingerprints.size() };
std::transform(daemon_ssl_allowed_fingerprints.begin(), daemon_ssl_allowed_fingerprints.end(), ssl_allowed_fingerprints.begin(), epee::from_hex_locale::to_vector);
for (const auto &fpr: ssl_allowed_fingerprints)
@@ -369,7 +371,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
ssl_options.verification = epee::net_utils::ssl_verification_t::user_ca;
}
- if (ssl_options.verification != epee::net_utils::ssl_verification_t::user_certificates || !command_line::is_arg_defaulted(vm, opts.daemon_ssl))
+ if (!ssl_required || !command_line::is_arg_defaulted(vm, opts.daemon_ssl))
{
THROW_WALLET_EXCEPTION_IF(!epee::net_utils::ssl_support_from_string(ssl_options.support, daemon_ssl), tools::error::wallet_internal_error,
tools::wallet2::tr("Invalid argument for ") + std::string(opts.daemon_ssl.name));
Why this scored 46/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.