Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,8 @@ jobs:
with:
persist-credentials: false

- name: Install nightly rust toolchain
uses: dtolnay/rust-toolchain@nightly
with:
# TODO(XXX): remove toolchain pinning once upstream issue is resolved:
# https://github.com/rust-lang/rust/issues/139715
toolchain: nightly-2025-03-25
- name: Install stable rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Install cbindgen
# Pin the installed version of cbindgen so that local usage can be
Expand Down
4 changes: 0 additions & 4 deletions librustls/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,3 @@ include = ["rustls_tls_version"]
"feature = aws-lc-rs" = "DEFINE_AWS_LC_RS"
"feature = ring" = "DEFINE_RING"
"feature = fips" = "DEFINE_FIPS"

[parse.expand]
crates = ["rustls-ffi"]
features = ["read_buf", "aws-lc-rs", "ring", "fips"]
93 changes: 54 additions & 39 deletions librustls/src/acceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,61 @@ use rustls::server::{Accepted, AcceptedAlert, Acceptor};
use crate::connection::rustls_connection;
use crate::error::{map_error, rustls_io_result, rustls_result};
use crate::ffi::{
box_castable, free_box, set_boxed_mut_ptr, to_box, to_boxed_mut_ptr, try_callback,
Castable, OwnershipBox, free_box, set_boxed_mut_ptr, to_box, to_boxed_mut_ptr, try_callback,
try_clone_arc, try_mut_from_ptr, try_mut_from_ptr_ptr, try_ref_from_ptr, try_take,
};
use crate::io::{CallbackReader, CallbackWriter, rustls_read_callback, rustls_write_callback};
use crate::panic::ffi_panic_boundary;
use crate::rslice::{rustls_slice_bytes, rustls_str};
use crate::server::rustls_server_config;

box_castable! {
/// A buffer and parser for ClientHello bytes.
///
/// This allows reading ClientHello before choosing a rustls_server_config.
///
/// It's useful when the server config will be based on parameters in the
/// ClientHello: server name indication (SNI), ALPN protocols, signature
/// schemes, and cipher suites.
///
/// In particular, if a server wants to do some potentially expensive work
/// to load a certificate for a given hostname, rustls_acceptor allows doing
/// that asynchronously, as opposed to rustls_server_config_builder_set_hello_callback(),
/// which doesn't work well for asynchronous I/O.
///
/// The general flow is:
/// - rustls_acceptor_new()
/// - Loop:
/// - Read bytes from the network it with rustls_acceptor_read_tls().
/// - If successful, parse those bytes with rustls_acceptor_accept().
/// - If that returns RUSTLS_RESULT_ACCEPTOR_NOT_READY, continue.
/// - Otherwise, break.
/// - If rustls_acceptor_accept() returned RUSTLS_RESULT_OK:
/// - Examine the resulting rustls_accepted.
/// - Create or select a rustls_server_config.
/// - Call rustls_accepted_into_connection().
/// - Otherwise, there was a problem with the ClientHello data and the
/// connection should be rejected.
pub struct rustls_acceptor(Acceptor);
/// A buffer and parser for ClientHello bytes.
///
/// This allows reading ClientHello before choosing a rustls_server_config.
///
/// It's useful when the server config will be based on parameters in the
/// ClientHello: server name indication (SNI), ALPN protocols, signature
/// schemes, and cipher suites.
///
/// In particular, if a server wants to do some potentially expensive work
/// to load a certificate for a given hostname, rustls_acceptor allows doing
/// that asynchronously, as opposed to rustls_server_config_builder_set_hello_callback(),
/// which doesn't work well for asynchronous I/O.
///
/// The general flow is:
/// - rustls_acceptor_new()
/// - Loop:
/// - Read bytes from the network it with rustls_acceptor_read_tls().
/// - If successful, parse those bytes with rustls_acceptor_accept().
/// - If that returns RUSTLS_RESULT_ACCEPTOR_NOT_READY, continue.
/// - Otherwise, break.
/// - If rustls_acceptor_accept() returned RUSTLS_RESULT_OK:
/// - Examine the resulting rustls_accepted.
/// - Create or select a rustls_server_config.
/// - Call rustls_accepted_into_connection().
/// - Otherwise, there was a problem with the ClientHello data and the
/// connection should be rejected.
pub struct rustls_acceptor {
_private: [u8; 0],
}

box_castable! {
/// A parsed ClientHello produced by a rustls_acceptor.
///
/// It is used to check server name indication (SNI), ALPN protocols,
/// signature schemes, and cipher suites. It can be combined with a
/// `rustls_server_config` to build a `rustls_connection`.
pub struct rustls_accepted(Option<Accepted>);
impl Castable for rustls_acceptor {
type Ownership = OwnershipBox;
type RustType = Acceptor;
}

/// A parsed ClientHello produced by a rustls_acceptor.
///
/// It is used to check server name indication (SNI), ALPN protocols,
/// signature schemes, and cipher suites. It can be combined with a
/// `rustls_server_config` to build a `rustls_connection`.
pub struct rustls_accepted {
_private: [u8; 0],
}

impl Castable for rustls_accepted {
type Ownership = OwnershipBox;
type RustType = Option<Accepted>;
}

impl rustls_acceptor {
Expand Down Expand Up @@ -446,9 +456,14 @@ impl rustls_accepted {
}
}

box_castable! {
/// Represents a TLS alert resulting from accepting a client.
pub struct rustls_accepted_alert(AcceptedAlert);
/// Represents a TLS alert resulting from accepting a client.
pub struct rustls_accepted_alert {
_private: [u8; 0],
}

impl Castable for rustls_accepted_alert {
type Ownership = OwnershipBox;
type RustType = AcceptedAlert;
}

impl rustls_accepted_alert {
Expand Down
71 changes: 46 additions & 25 deletions librustls/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,24 @@ use rustls::sign::CertifiedKey;
use crate::crypto_provider::{self, rustls_signing_key};
use crate::error::{map_error, rustls_result};
use crate::ffi::{
arc_castable, box_castable, free_arc, free_box, ref_castable, set_arc_mut_ptr,
Castable, OwnershipArc, OwnershipBox, OwnershipRef, free_arc, free_box, set_arc_mut_ptr,
to_arc_const_ptr, to_boxed_mut_ptr, try_box_from_ptr, try_mut_from_ptr, try_ref_from_ptr,
try_ref_from_ptr_ptr, try_slice, try_take,
};
use crate::panic::ffi_panic_boundary;
use crate::rslice::rustls_slice_bytes;

ref_castable! {
/// An X.509 certificate, as used in rustls.
/// Corresponds to `CertificateDer` in the Rust pki-types API.
/// <https://docs.rs/rustls-pki-types/latest/rustls_pki_types/struct.CertificateDer.html>
pub struct rustls_certificate(CertificateDer<'a>);
/// An X.509 certificate, as used in rustls.
/// Corresponds to `CertificateDer` in the Rust pki-types API.
/// <https://docs.rs/rustls-pki-types/latest/rustls_pki_types/struct.CertificateDer.html>
pub struct rustls_certificate<'a> {
_private: [u8; 0],
_marker: PhantomData<&'a ()>,
}

impl<'a> Castable for rustls_certificate<'a> {
type Ownership = OwnershipRef;
type RustType = CertificateDer<'a>;
}

/// Get the DER data of the certificate itself.
Expand All @@ -48,13 +54,18 @@ pub extern "C" fn rustls_certificate_get_der(
}
}

arc_castable! {
/// The complete chain of certificates to send during a TLS handshake,
/// plus a private key that matches the end-entity (leaf) certificate.
///
/// Corresponds to `CertifiedKey` in the Rust API.
/// <https://docs.rs/rustls/latest/rustls/sign/struct.CertifiedKey.html>
pub struct rustls_certified_key(CertifiedKey);
/// The complete chain of certificates to send during a TLS handshake,
/// plus a private key that matches the end-entity (leaf) certificate.
///
/// Corresponds to `CertifiedKey` in the Rust API.
/// <https://docs.rs/rustls/latest/rustls/sign/struct.CertifiedKey.html>
pub struct rustls_certified_key {
_private: [u8; 0],
}

impl Castable for rustls_certified_key {
type Ownership = OwnershipArc;
type RustType = CertifiedKey;
}

impl rustls_certified_key {
Expand Down Expand Up @@ -270,14 +281,19 @@ impl rustls_certified_key {
}
}

box_castable! {
/// A `rustls_root_cert_store` being constructed.
///
/// A builder can be modified by adding trust anchor root certificates with
/// `rustls_root_cert_store_builder_add_pem`. Once you're done adding root certificates,
/// call `rustls_root_cert_store_builder_build` to turn it into a `rustls_root_cert_store`.
/// This object is not safe for concurrent mutation.
pub struct rustls_root_cert_store_builder(Option<RootCertStoreBuilder>);
/// A `rustls_root_cert_store` being constructed.
///
/// A builder can be modified by adding trust anchor root certificates with
/// `rustls_root_cert_store_builder_add_pem`. Once you're done adding root certificates,
/// call `rustls_root_cert_store_builder_build` to turn it into a `rustls_root_cert_store`.
/// This object is not safe for concurrent mutation.
pub struct rustls_root_cert_store_builder {
_private: [u8; 0],
}

impl Castable for rustls_root_cert_store_builder {
type Ownership = OwnershipBox;
type RustType = Option<RootCertStoreBuilder>;
}

pub(crate) struct RootCertStoreBuilder {
Expand Down Expand Up @@ -440,10 +456,15 @@ impl rustls_root_cert_store_builder {
}
}

arc_castable! {
/// A root certificate store.
/// <https://docs.rs/rustls/latest/rustls/struct.RootCertStore.html>
pub struct rustls_root_cert_store(RootCertStore);
/// A root certificate store.
/// <https://docs.rs/rustls/latest/rustls/struct.RootCertStore.html>
pub struct rustls_root_cert_store {
_private: [u8; 0],
}

impl Castable for rustls_root_cert_store {
type Ownership = OwnershipArc;
type RustType = RootCertStore;
}

impl rustls_root_cert_store {
Expand Down
13 changes: 9 additions & 4 deletions librustls/src/cipher.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
use rustls::SupportedCipherSuite;

use crate::enums::rustls_tls_version;
use crate::ffi::{ref_castable, try_ref_from_ptr};
use crate::ffi::{Castable, OwnershipRef, try_ref_from_ptr};
use crate::panic::ffi_panic_boundary;
use crate::rslice::rustls_str;

ref_castable! {
/// A cipher suite supported by rustls.
pub struct rustls_supported_ciphersuite(SupportedCipherSuite);
/// A cipher suite supported by rustls.
pub struct rustls_supported_ciphersuite {
_private: [u8; 0],
}

impl Castable for rustls_supported_ciphersuite {
type Ownership = OwnershipRef;
type RustType = SupportedCipherSuite;
}

impl rustls_supported_ciphersuite {
Expand Down
52 changes: 31 additions & 21 deletions librustls/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::connection::{Connection, rustls_connection};
use crate::crypto_provider::{self, rustls_crypto_provider, rustls_hpke};
use crate::error::{self, map_error, rustls_result};
use crate::ffi::{
arc_castable, box_castable, free_arc, free_box, set_arc_mut_ptr, set_boxed_mut_ptr,
Castable, OwnershipArc, OwnershipBox, free_arc, free_box, set_arc_mut_ptr, set_boxed_mut_ptr,
to_boxed_mut_ptr, try_box_from_ptr, try_clone_arc, try_mut_from_ptr, try_mut_from_ptr_ptr,
try_ref_from_ptr, try_ref_from_ptr_ptr, try_slice,
};
Expand All @@ -29,20 +29,25 @@ use crate::rslice::{rustls_slice_bytes, rustls_slice_slice_bytes, rustls_str};
use crate::userdata::userdata_get;
use crate::verifier::rustls_server_cert_verifier;

box_castable! {
/// A client config being constructed.
///
/// A builder can be modified by, e.g. `rustls_client_config_builder_load_roots_from_file`.
/// Once you're done configuring settings, call `rustls_client_config_builder_build`
/// to turn it into a *rustls_client_config.
///
/// Alternatively, if an error occurs or, you don't wish to build a config,
/// call `rustls_client_config_builder_free` to free the builder directly.
///
/// This object is not safe for concurrent mutation. Under the hood,
/// it corresponds to a `Box<ClientConfig>`.
/// <https://docs.rs/rustls/latest/rustls/struct.ConfigBuilder.html>
pub struct rustls_client_config_builder(ClientConfigBuilder);
/// A client config being constructed.
///
/// A builder can be modified by, e.g. `rustls_client_config_builder_load_roots_from_file`.
/// Once you're done configuring settings, call `rustls_client_config_builder_build`
/// to turn it into a *rustls_client_config.
///
/// Alternatively, if an error occurs or, you don't wish to build a config,
/// call `rustls_client_config_builder_free` to free the builder directly.
///
/// This object is not safe for concurrent mutation. Under the hood,
/// it corresponds to a `Box<ClientConfig>`.
/// <https://docs.rs/rustls/latest/rustls/struct.ConfigBuilder.html>
pub struct rustls_client_config_builder {
_private: [u8; 0],
}

impl Castable for rustls_client_config_builder {
type Ownership = OwnershipBox;
type RustType = ClientConfigBuilder;
}

pub(crate) struct ClientConfigBuilder {
Expand Down Expand Up @@ -76,12 +81,17 @@ impl Default for ClientConfigBuilder {
}
}

arc_castable! {
/// A client config that is done being constructed and is now read-only.
///
/// Under the hood, this object corresponds to an `Arc<ClientConfig>`.
/// <https://docs.rs/rustls/latest/rustls/struct.ClientConfig.html>
pub struct rustls_client_config(ClientConfig);
/// A client config that is done being constructed and is now read-only.
///
/// Under the hood, this object corresponds to an `Arc<ClientConfig>`.
/// <https://docs.rs/rustls/latest/rustls/struct.ClientConfig.html>
pub struct rustls_client_config {
_private: [u8; 0],
}

impl Castable for rustls_client_config {
type Ownership = OwnershipArc;
type RustType = ClientConfig;
}

impl rustls_client_config_builder {
Expand Down
13 changes: 9 additions & 4 deletions librustls/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::certificate::rustls_certificate;
use crate::enums::rustls_handshake_kind;
use crate::error::{map_error, rustls_io_result, rustls_result};
use crate::ffi::{
box_castable, free_box, try_callback, try_mut_from_ptr, try_ref_from_ptr, try_slice,
Castable, OwnershipBox, free_box, try_callback, try_mut_from_ptr, try_ref_from_ptr, try_slice,
try_slice_mut,
};
use crate::io::{
Expand Down Expand Up @@ -92,9 +92,14 @@ impl std::ops::DerefMut for Connection {
}
}

box_castable! {
/// A C representation of a Rustls `Connection`.
pub struct rustls_connection(Connection);
/// A C representation of a Rustls `Connection`.
pub struct rustls_connection {
_private: [u8; 0],
}

impl Castable for rustls_connection {
type Ownership = OwnershipBox;
type RustType = Connection;
}

impl rustls_connection {
Expand Down
Loading
Loading