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 实现:
- windows:使用 SChannel;
- MacOS:使用 Secure Transport;
- 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