Skip to content

Commit

Permalink
Add experimental support for rustls (#374)
Browse files Browse the repository at this point in the history
* Add experimental support for rustls

This adds experimental support for using rustls as a TLS backend for curl. This is made possible by the upstream rustls support recently merged into master. As such, this branch also updates the bundled curl version to the bleeding edge.

We need to use a fork of the crustls wrapper layer for now in order to depend on it in an ideal way. I will work on upstreaming these changes before this can be merged.

There's still some things that will need to be solved before we make this available for everyone, but I am already able to run a sample program with HTTPS successfully under rustls, which is very promising!

* Formatting

* Formatting

* Add feature to readme

* Use upstream version of crustls

* Update to latest main

* Update to bleeding edge

* Add rustls test to CI

* Bump to 0.8.2, disable bundled log capture

* Use rustls-ffi version from Crates.io
  • Loading branch information
sagebind authored Jan 6, 2022
1 parent a9ea4b0 commit c9b3f70
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ ssl = ["openssl-sys", "openssl-probe", "curl-sys/ssl"] # OpenSSL/system TLS back
mesalink = ["curl-sys/mesalink"] # MesaLink TLS backend
http2 = ["curl-sys/http2"]
spnego = ["curl-sys/spnego"]
rustls = ["curl-sys/rustls"]
static-curl = ["curl-sys/static-curl"]
static-ssl = ["curl-sys/static-ssl"]
force-system-lib-on-osx = ['curl-sys/force-system-lib-on-osx']
Expand All @@ -57,6 +58,10 @@ ntlm = ["curl-sys/ntlm"]
name = "atexit"
harness = false

[[example]]
name = "https"
path = "examples/https.rs"

[[example]]
name = "ssl_proxy"
path = "examples/ssl_proxy.rs"
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ libcurl and the system-wide SSL library. Some of this behavior can be customized
with various Cargo features:

- `ssl`: Enable SSL/TLS support using the platform-default TLS backend. On Windows this is [Schannel], on macOS [Secure Transport], and [OpenSSL] (or equivalent) on all other platforms. Enabled by default.
- `rustls` Enable SSL/TLS support via [Rustls], a well-received alternative TLS backend written in Rust. Rustls is always statically linked. Disabled by default.

Note that Rustls support is experimental within Curl itself and may have significant bugs, so we don't offer any sort of stability guarantee with this feature.
- `mesalink`: Enable SSL/TLS support via [MesaLink], an alternative TLS backend written in Rust based on [Rustls]. MesaLink is always statically linked. Disabled by default.
- `http2`: Enable HTTP/2 support via libnghttp2. Disabled by default.
- `static-curl`: Use a bundled libcurl version and statically link to it. Disabled by default.
Expand Down
2 changes: 2 additions & 0 deletions ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ set -ex
cargo test --target $TARGET --no-run
# First test with no extra protocols enabled.
cargo test --target $TARGET --no-run --features static-curl
# Then with rustls TLS backend.
cargo test --target $TARGET --no-run --features rustls,static-curl
# Then with all extra protocols enabled.
cargo test --target $TARGET --no-run --features static-curl,protocol-ftp,ntlm
if [ -z "$NO_RUN" ]; then
Expand Down
6 changes: 6 additions & 0 deletions curl-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ optional = true
default-features = false
features = ["client_apis", "error_strings", "tls13", "aesgcm", "chachapoly", "x25519", "ecdh", "ecdsa", "verifier"]

[dependencies.rustls-ffi]
version = "0.8"
optional = true
features = ["no_log_capture"]

[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]
openssl-sys = { version = "0.9", optional = true }

Expand All @@ -47,6 +52,7 @@ cc = "1.0"
default = ["ssl"]
ssl = ["openssl-sys"]
http2 = ["libnghttp2-sys"]
rustls = ["rustls-ffi"]
static-curl = []
static-ssl = ["openssl-sys/vendored"]
spnego = []
Expand Down
4 changes: 4 additions & 0 deletions curl-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@ fn main() {
} else {
cfg.define("HAVE_UNIX", None);
}
} else if cfg!(feature = "rustls") {
cfg.define("USE_RUSTLS", None)
.file("curl/lib/vtls/rustls.c")
.include(env::var_os("DEP_RUSTLS_FFI_INCLUDE").unwrap());
} else if cfg!(feature = "ssl") {
if windows {
// For windows, spnego feature is auto on in case ssl feature is on.
Expand Down
2 changes: 2 additions & 0 deletions curl-sys/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ extern crate libz_sys;
extern crate mesalink;
#[cfg(link_openssl)]
extern crate openssl_sys;
#[cfg(feature = "rustls")]
extern crate rustls_ffi;

use libc::c_ulong;
use libc::{c_char, c_double, c_int, c_long, c_short, c_uint, c_void, size_t, time_t};
Expand Down
23 changes: 23 additions & 0 deletions examples/https.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! Simple HTTPS GET
//!
//! This example is a Rust adaptation of the [C example of the same
//! name](https://curl.se/libcurl/c/https.html).
extern crate curl;

use curl::easy::Easy;
use std::io::{stdout, Write};

fn main() -> Result<(), curl::Error> {
let mut curl = Easy::new();

curl.url("https://example.com/")?;
curl.write_function(|data| {
stdout().write_all(data).unwrap();
Ok(data.len())
})?;

curl.perform()?;

Ok(())
}

0 comments on commit c9b3f70

Please sign in to comment.