Support for SSLKEYLOGFILE in HTTPS client from Reqwest

Hi,

How can i log the secret/sessions keys for a TLS connection to SSLKEYLOGFILE to enable wireshark to decrypt encrypted communication in MacOS Catalina Version 10.15.4?

My current program looks like this:

use reqwest;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {

    let body = reqwest::get("https://www.rust-lang.org")
    .await?
    .text()
    .await?;

    println!("response: {}", body);

    Ok(())
}

Command: SSLKEYLOGFILE=/tmp/keys.log cargo run

Expected: /tmp/keys.log to be populated with data in NSS key log format
Actual: Empty

Thanks,
Karan

You could try enabling the rustls-tls feature for reqwest and try something like this. It seems like rustls supports the feature in general but its not exposed by reqwest. This is untested so it might not work anyway. If this is something you need for a long term project, I would consider creating an issue on reqwest's Github to see if its something that could be supported natively, since that would be more robust.

Cargo.toml

...
[dependencies]
reqwest = { version = "0.10", features = ["rustls-tls"] }
rustls = "0.18"
webpki-roots =  "0.20"
...

Code

    let mut tls = rustls::ClientConfig::new();
    tls.set_protocols(&["h2".into(), "http/1.1".into()]);
    tls.root_store
        .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
    tls.key_log = Arc::new(rustls::KeyLogFile::new());
    let client = reqwest::ClientBuilder::new()
        .use_preconfigured_tls(tls)
        .build()
        .unwrap();
1 Like

Thanks @drewkett this does work.

use reqwest::Client;
use http::StatusCode;
use rustls;
use std::sync::Arc;
use tokio;
use webpki_roots;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut tls = rustls::ClientConfig::new();
    tls.set_protocols(&["h2".into(), "http/1.1".into()]);
    tls.root_store
        .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
    tls.key_log = Arc::new(rustls::KeyLogFile::new());

    //let client = reqwest::ClientBuilder::new()
    let client = Client::builder()
        .use_preconfigured_tls(tls)
        .build()
        .unwrap();
    println!("making request");
    let response = client.get("https://ifconfig.co").send().await?;
    if response.status() == StatusCode::OK {
        println!("awesome");
    } else {
        eprintln!("bad status: {}", response.status());
    }

    Ok(())
}

Have cut them a a ticket as i do think this should be supported out of the box.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.