3 unstable releases

Uses old Rust 2015

0.2.1 Mar 15, 2016
0.2.0 Feb 16, 2016
0.1.0 Feb 11, 2016

#5 in #libressl

ISC license

130KB
789 lines

Rust bindings for libressl's libtls For the authoritative source on the inner workings of libtls check the manpage. The raw module holds the bindings around libtls. A more idiomatic API is provided here.

Client

use std::io::Write;
use std::net::TcpStream;
let tcp = TcpStream::connect("google.com:443").unwrap();
let mut client = telos::new_client()
    .connect(tcp, "google.com")
    .unwrap();
client.write("GET / HTTP/1.1\n\n".as_bytes()).unwrap();

Server

The library does not handle TCP listening and binding, you need to handle the TCP server accept() and then call TlsServer::accept

use std::net::TcpListener;
let srv = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = srv.local_addr().unwrap();
let mut tls_srv = telos::new_server()
    .key_file("tests/private_key.key")
    .cert_file("tests/certificate.crt")
    .bind().unwrap();
// Accept TCP connection, and then start TLS over it
let tcp_conn = srv.incoming().next().unwrap().unwrap();
let mut tls_conn = tls_srv.accept(tcp_conn).unwrap();

Certificate Verification

By default libtls will verify certificates using the system certificate store (usually defined as /etc/ssl/cert.pem). In some Linux flavours and in Windows this file does not exist and you will need to use one of the appropriate methods to load the correct certificates for your system - check the Builder classes for the ca methods.

Connection Lifetime

By default connect() and accept() take ownership of the underlying sockets, to ensure they are not closed while still in use.

If you want to keep ownership, connect_socket() and accept_socket() allow you to do it. However dropping TlsStream WILL NOT close the underlying sockets, you need to close them yourself.

Likewise it is up to the caller to make sure the socket is not closed too early. This example fails to keep the original TcpStream in scope

#[cfg(unix)]
use std::os::unix::io::AsRawFd;
#[cfg(windows)]
use std::os::windows::io::AsRawSocket;
use std::net::TcpStream;
fn create_client() -> telos::TlsStream<()> {
    let tcp = TcpStream::connect("google.com:443").unwrap();
    let mut client = telos::new_client()
        .connect_socket(&tcp, "google.com")
        .unwrap();
    client
}

fn main() {
    let mut client = create_client();
    // The TcpStream was closed when create_client exited the following
    // will fail with "handshake failed: Bad file descriptor"
    client.handshake().unwrap();
}

Dependencies

~2.5MB
~38K SLoC