跳过正文

目录

rustls
#

rustls 是一个纯 Rust 实现的现代 TLS 库, 支持 TLS1.2 和 TLS1.3。

rustls 底层使用的是 AWS 开源的 TLS 库 aws-lc (基于 Google BoringSSL 和 OpenSSL),它是一个底层库,应用可以使用 reqwest/hyper/tokio-rustls 高层库。

rustls 举例:

use std::io;
use rustls::Connection;

let root_store = rustls::RootCertStore::from_iter( webpki_roots::TLS_SERVER_ROOTS .iter() .cloned(), );
let config = rustls::ClientConfig::builder() .with_root_certificates(root_store) .with_no_client_auth();
let rc_config = Arc::new(config);
let example_com = "example.com".try_into().unwrap();
let mut client = rustls::ClientConnection::new(rc_config, example_com);

client.writer().write(b"GET / HTTP/1.0\r\n\r\n").unwrap();
let mut socket = connect("example.com", 443);
loop {
    if client.wants_read() && socket.ready_for_read() {
        client.read_tls(&mut socket).unwrap();
        client.process_new_packets().unwrap();

        let mut plaintext = Vec::new();
        client.reader().read_to_end(&mut plaintext).unwrap();
        io::stdout().write(&plaintext).unwrap();
    }

    if client.wants_write() && socket.ready_for_write() {
        client.write_tls(&mut socket).unwrap();
    }

    socket.wait_for_something_to_happen();
}

native-tls
#

使用平台自带的 TLS 实现:

  1. windows:使用 SChannel;
  2. MacOS:使用 Secure Transport;
  3. Linux:OpenSSL;

native-tls 主要是提供一套平台无关的 TLS/SSL APIs 接口,同时提供安全、合理的缺省值。

native-tls 示例:

extern crate native_tls;

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

fn main() {
    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));
}

//  native-tls server 例子
extern crate native_tls;

use native_tls::{Identity, TlsAcceptor, TlsStream};
use std::fs::File;
use std::io::{Read};
use std::net::{TcpListener, TcpStream};
use std::sync::Arc;
use std::thread;

fn main() {
    let mut file = File::open("identity.pfx").unwrap();
    let mut identity = vec![];
    file.read_to_end(&mut identity).unwrap();
    let identity = Identity::from_pkcs12(&identity, "hunter2").unwrap();
    let acceptor = TlsAcceptor::new(identity).unwrap();
    let acceptor = Arc::new(acceptor);

    let listener = TcpListener::bind("0.0.0.0:8443").unwrap();

    fn handle_client(stream: TlsStream<TcpStream>) {
        // ...
    }

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let acceptor = acceptor.clone();
                thread::spawn(move || {
                    let stream = acceptor.accept(stream).unwrap();
                    handle_client(stream);
                });
            }
            Err(e) => { /* connection failed */ }
        }
    }
}

其它选择
#

Google BoringSSL:https://github.com/cloudflare/boring