Skip to content
This repository was archived by the owner on May 17, 2026. It is now read-only.
This repository was archived by the owner on May 17, 2026. It is now read-only.

Add option to bypass certificate verification for self-signed certificates #18

Description

@ecker00

The current Client::rustls() method uses rustls-platform-verifier which enforces strict certificate verification, causing failures with self-signed certificates (e.g., ProtonMail Bridge).

Error: failed to verify TLS certificate: invalid peer certificate: Other(OtherError(CaUsedAsEndEntity))

Cause

The issue is in src/client/tokio.rs in the upgrade_rustls() method:

let mut config = ClientConfig::with_platform_verifier();

rustls-platform-verifier is designed for security and intentionally doesn't provide bypass options. To ignore certificate verification, we need to use core rustls with a custom ServerCertVerifier.

Current vs. Needed Flow

Current: imap-client → rustls-platform-verifier → OS certificate store → REJECT self-signed

Needed: imap-client → custom rustls config → DangerousNoCertificateVerifier → ACCEPT all

Proposed Solution

Add an alternative method that bypasses rustls-platform-verifier entirely:

pub async fn rustls_dangerous(host: &str, port: u16, starttls: bool) -> Result<Self, ClientError>

// Implementation replaces platform verifier with custom verifier
async fn upgrade_rustls_dangerous(mut self, starttls: bool) -> Result<Self, ClientError> {
    let config = ClientConfig::builder()
        .with_safe_defaults()
        .with_custom_certificate_verifier(Arc::new(DangerousNoCertificateVerification))
        .with_no_client_auth();

    config.alpn_protocols = vec![b"imap".to_vec()];
    // ... rest of TLS setup unchanged
}

struct DangerousNoCertificateVerification;
impl ServerCertVerifier for DangerousNoCertificateVerification {
    fn verify_server_cert(
        &self,
        _end_entity: &Certificate,
        _intermediates: &[Certificate],
        _server_name: &ServerName,
        _scts: &mut dyn Iterator<Item = &[u8]>,
        _ocsp_response: &[u8],
        _now: SystemTime,
    ) -> Result<ServerCertVerified, Error> {
        Ok(ServerCertVerified::assertion())
    }
}

Related Issues

This is needed for trusted local servers like ProtonMail Bridge that use self-signed certificates where the user explicitly accepts the security risk.


Note: I'm not a Rust developer - this analysis came from working with Claude Sonnet via the CLI to figure out how to bypass verification for self-signed certificates. If I had the time I would compile and verify this, but don't have the chance right now. Hopefully it's useful and not just noise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions