ssl - 如何使用 ruSTLs 库建立 TLS 连接?

标签 ssl rust

documentation提供了一个例子——不幸的是它不能编译;很多东西都改名了,ClientSession 的界面构造函数改变了。我设法将错误修复到它可以编译的地步,但没有修复到它可以工作的地步。

这是我使最小示例起作用的最佳尝试:

extern crate rustls;

use io::Read;
use io::Write;
use rustls::Session;
use std::io;

fn main() {
    let mut socket = std::net::TcpStream::connect("www.google.com:443").unwrap();
    let mut config = rustls::ClientConfig::new();
    config
        .root_store
        .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
    let arc = std::sync::Arc::new(config);
    let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.google.com").unwrap();
    let mut client = rustls::ClientSession::new(&arc, dns_name);
    client.write(b"GET https://www.google.com\r\n\r\n").unwrap();
    loop {
        if client.wants_read() {
            client.read_tls(&mut socket).unwrap();
            client.process_new_packets().unwrap();
            let mut plaintext = Vec::new();
            client.read_to_end(&mut plaintext).unwrap();
            io::stdout().write(&plaintext).unwrap();
        }
        if client.wants_write() {
            client.write_tls(&mut socket).unwrap();
        }
        // For testing purposes only
        std::thread::sleep_ms(1000);
    }
}

发生的情况是程序开始运行并在 10 秒后中止,并出现错误“已建立的连接已被主机中的软件中止”。

我本来希望它将一些数据打印到标准输出,但事实并非如此。

最佳答案

有一个名为 rustls::Stream 的结构将 session 用作普通流。它记录在 docs.rs .您还可以找到示例 on their GitHub repository .

您可以将代码转换为使用 rustls::Stream像这样:

extern crate rustls; // 0.17.0

use io::Read;
use io::Write;
use std::io;

fn main() {
    let mut socket = std::net::TcpStream::connect("www.google.com:443").unwrap();
    let mut config = rustls::ClientConfig::new();
    config
        .root_store
        .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
    let arc = std::sync::Arc::new(config);
    let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.google.com").unwrap();
    let mut client = rustls::ClientSession::new(&arc, dns_name);
    let mut stream = rustls::Stream::new(&mut client, &mut socket); // Create stream
                                                                    // Instead of writing to the client, you write to the stream
    stream
        .write(b"GET / HTTP/1.1\r\nConnection: close\r\n\r\n")
        .unwrap();
    let mut plaintext = Vec::new();
    stream.read_to_end(&mut plaintext).unwrap();
    io::stdout().write_all(&plaintext).unwrap();
}

关于ssl - 如何使用 ruSTLs 库建立 TLS 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60357636/

相关文章:

apache - 带有客户端证书主题名称的 Tomcat 7 访问日志

rust - tokio::run_async 与 tokio::net::UnixStream panic

arrays - Rust 中不可调整大小的动态长度数组的最佳选择是什么?

ssl - Github webhook over https : "Service timeout"

ssl - 在 wamp 服务器上使用 openssl 修改 ssl 版本

rust - 如何用 Rust 宏简化数学公式?

rust - 什么使某些东西成为 "trait object"?

input - 如何在 Rust 1.0 中读取用户输入的整数?

ssl - IBM MQ.Net CertificateLabel、CipherSpec

python - 使用 nginx 将 http 重定向到 https 而不是使用 django-sslify?