如何使用 Rust tokio_native_tls 在两个对等点之间建立 TLS 连接

问题描述 投票:0回答:1

我正在一个文件传输系统中工作,该系统具有使用 Rust 的 p2p 连接库。它仅使用 tcp 即可工作,但现在我想使用 TLS 改进它,但我不明白两件事。首先是两个对等方如何共享证书颁发机构 CA,以便他们可以验证连接是否值得信赖。其次,我尝试使用 tokio_native_tls 来包装 native_tls 库并添加异步。我正在遵循 native_tls 文档中的示例。然而,他们使用带有域的连接器,并使用谷歌作为域。这是他们提供的示例。

use native_tls::TlsConnector;
use std::io::{Read, Write};
use std::net::TcpStream;

let connector = TlsConnector::new().unwrap();

let stream = TcpStream::connect("google.com:443").unwrap();
let mut stream = connector.connect("google.com", stream).unwrap();

stream.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
let mut res = vec![];
stream.read_to_end(&mut res).unwrap();
println!("{}", String::from_utf8_lossy(&res));

在我描述的对等连接中,只有 2 个对等点尝试传输一些文件。由于他们没有纯域名 IP,因此无法正常工作。如果有人能给我一些帮助,请提供一些如何处理的指南,那就太好了,谢谢。

ssl network-programming rust p2p tls1.3
1个回答
0
投票

同步 connect 函数的

docs
说:

如果同时禁用 SNI 和主机名验证,则域将被忽略。

考虑到这一点,切换到

async
API,并生成自签名证书,我们得到以下工作代码:

[package]
name = "tls"
version = "0.1.0"
edition = "2021"

[dependencies]
rcgen = "0.13.1"
tokio = { version = "1.41.1", features = ["full"] }
tokio-native-tls = "0.3.1"
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use tokio_native_tls::native_tls::Identity;
use tokio_native_tls::{native_tls, TlsAcceptor, TlsConnector};

#[tokio::main]
async fn main() {
    let cert = rcgen::generate_simple_self_signed([]).unwrap();
    let listener = TcpListener::bind("127.0.0.1:8001").await.unwrap();

    let trusted = native_tls::Certificate::from_pem(cert.cert.pem().as_bytes()).unwrap();
    tokio::spawn(async move {
        let connector = TlsConnector::from(
            native_tls::TlsConnector::builder()
                .disable_built_in_roots(true)
                .add_root_certificate(trusted)
                .danger_accept_invalid_hostnames(true)
                .use_sni(false)
                .build()
                .unwrap(),
        );
        let tcp = TcpStream::connect("0.0.0.0:8001").await.unwrap();
        let mut tls = connector.connect("N/A", tcp).await.unwrap();
        tls.write_all(b"hello!").await.unwrap();
    });

    let acceptor = TlsAcceptor::from(
        native_tls::TlsAcceptor::new(
            Identity::from_pkcs8(
                cert.cert.pem().as_bytes(),
                cert.key_pair.serialize_pem().as_bytes(),
            )
            .unwrap(),
        )
        .unwrap(),
    );

    let (tcp, _) = listener.accept().await.unwrap();
    let mut tls = acceptor.accept(tcp).await.unwrap();
    let mut buf = String::new();
    tls.read_to_string(&mut buf).await.unwrap();
    println!("read: {buf}");
}

如果您想使用 CA 签名的证书,则应信任 CA 证书。

© www.soinside.com 2019 - 2024. All rights reserved.