feat: replace once_cell with LazyLock (#38)

* RTG-3333 Support X25519MLKEM768 by default, but don't sent it as client

X25519MLKEM768 is the standardised successor of the preliminary
X25519Kyber768Draft00. Latest browsers have switched to X25519MLKEM768.
Cloudflare supports both on the edge.

We've had support for X25519MLKEM768 in this crate for a while, but
didn't enable by default. We're now enabling serverside support by
default. We also let clients advertise support when set
to kx-client-pq-supported.

We don't enable support by default yet for clients set to
kx-client-pq-preferred, as that would cause an extra round-trip due to
HelloRetryRequest if the server doesn't support X25519MLKEM768 yet.

BoringSSL against which we build must support X25519MLKEM768, otherwise
this will fail.

* replace once_cell with LazyLock

We can drop the once_cell dependency since the same functionality is
implemented in std now.

Requires bumping MSRV to 1.80.

* fix manual_c_str_literals clippy warning

---------

Co-authored-by: Bas Westerbaan <bas@cloudflare.com>
Co-authored-by: Alessandro Ghedini <alessandro@cloudflare.com>
This commit is contained in:
0x676e67 2025-01-23 10:08:15 +08:00 committed by GitHub
parent 1a0f1cd24e
commit 13eb268616
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 29 additions and 31 deletions

View File

@ -44,7 +44,6 @@ hyper1 = { package = "hyper", version = "1" }
hyper-util = "0.1.6"
hyper0 = { package = "hyper", version = "0.14", default-features = false }
linked_hash_set = "0.1"
once_cell = "1.0"
openssl-macros = "0.1.1"
tower = { version = "0.4", default-features = false, features = ["util"] }
tower-layer = "0.3"

View File

@ -10,7 +10,7 @@ readme = "README.md"
keywords = ["crypto", "tls", "ssl", "dtls"]
categories = ["cryptography", "api-bindings"]
edition = { workspace = true }
rust-version = "1.70"
rust-version = "1.80"
[package.metadata.docs.rs]
features = ["pq-experimental", "underscore-wildcards"]
@ -74,7 +74,6 @@ kx-client-nist-required = ["kx-safe-default"]
[dependencies]
bitflags = { workspace = true }
foreign-types = { workspace = true }
once_cell = { workspace = true }
openssl-macros = { workspace = true }
libc = { workspace = true }
boring-sys = { workspace = true }

View File

@ -5,10 +5,10 @@ use super::{
SslVerifyMode,
};
use crate::ex_data::Index;
use once_cell::sync::Lazy;
use std::convert::identity;
use std::future::Future;
use std::pin::Pin;
use std::sync::LazyLock;
use std::task::{ready, Context, Poll, Waker};
/// The type of futures to pass to [`SslContextBuilderExt::set_async_select_certificate_callback`].
@ -42,19 +42,20 @@ pub type BoxCustomVerifyFinish = Box<dyn FnOnce(&mut SslRef) -> Result<(), SslAl
/// Public for documentation purposes.
pub type ExDataFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
pub(crate) static TASK_WAKER_INDEX: Lazy<Index<Ssl, Option<Waker>>> =
Lazy::new(|| Ssl::new_ex_index().unwrap());
pub(crate) static SELECT_CERT_FUTURE_INDEX: Lazy<Index<Ssl, MutOnly<Option<BoxSelectCertFuture>>>> =
Lazy::new(|| Ssl::new_ex_index().unwrap());
pub(crate) static SELECT_PRIVATE_KEY_METHOD_FUTURE_INDEX: Lazy<
pub(crate) static TASK_WAKER_INDEX: LazyLock<Index<Ssl, Option<Waker>>> =
LazyLock::new(|| Ssl::new_ex_index().unwrap());
pub(crate) static SELECT_CERT_FUTURE_INDEX: LazyLock<
Index<Ssl, MutOnly<Option<BoxSelectCertFuture>>>,
> = LazyLock::new(|| Ssl::new_ex_index().unwrap());
pub(crate) static SELECT_PRIVATE_KEY_METHOD_FUTURE_INDEX: LazyLock<
Index<Ssl, MutOnly<Option<BoxPrivateKeyMethodFuture>>>,
> = Lazy::new(|| Ssl::new_ex_index().unwrap());
pub(crate) static SELECT_GET_SESSION_FUTURE_INDEX: Lazy<
> = LazyLock::new(|| Ssl::new_ex_index().unwrap());
pub(crate) static SELECT_GET_SESSION_FUTURE_INDEX: LazyLock<
Index<Ssl, MutOnly<Option<BoxGetSessionFuture>>>,
> = Lazy::new(|| Ssl::new_ex_index().unwrap());
pub(crate) static SELECT_CUSTOM_VERIFY_FUTURE_INDEX: Lazy<
> = LazyLock::new(|| Ssl::new_ex_index().unwrap());
pub(crate) static SELECT_CUSTOM_VERIFY_FUTURE_INDEX: LazyLock<
Index<Ssl, MutOnly<Option<BoxCustomVerifyFuture>>>,
> = Lazy::new(|| Ssl::new_ex_index().unwrap());
> = LazyLock::new(|| Ssl::new_ex_index().unwrap());
impl SslContextBuilder {
/// Sets a callback that is called before most [`ClientHello`] processing

View File

@ -219,7 +219,7 @@ struct BIO_METHOD(*mut ffi::BIO_METHOD);
impl BIO_METHOD {
fn new<S: Read + Write>() -> BIO_METHOD {
unsafe {
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr().cast());
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, c"rust".as_ptr().cast());
assert!(!ptr.is_null());
let ret = BIO_METHOD(ptr);
assert!(ffi::BIO_meth_set_write(ptr, Some(bwrite::<S>)) != 0);

View File

@ -59,7 +59,6 @@
//! ```
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_void};
use once_cell::sync::Lazy;
use openssl_macros::corresponds;
use std::any::TypeId;
use std::collections::HashMap;
@ -76,7 +75,7 @@ use std::path::Path;
use std::ptr::{self, NonNull};
use std::slice;
use std::str;
use std::sync::{Arc, Mutex};
use std::sync::{Arc, LazyLock, Mutex};
use crate::dh::DhRef;
use crate::ec::EcKeyRef;
@ -429,12 +428,15 @@ impl NameType {
}
}
static INDEXES: Lazy<Mutex<HashMap<TypeId, c_int>>> = Lazy::new(|| Mutex::new(HashMap::new()));
static SSL_INDEXES: Lazy<Mutex<HashMap<TypeId, c_int>>> = Lazy::new(|| Mutex::new(HashMap::new()));
static SESSION_CTX_INDEX: Lazy<Index<Ssl, SslContext>> = Lazy::new(|| Ssl::new_ex_index().unwrap());
static INDEXES: LazyLock<Mutex<HashMap<TypeId, c_int>>> =
LazyLock::new(|| Mutex::new(HashMap::new()));
static SSL_INDEXES: LazyLock<Mutex<HashMap<TypeId, c_int>>> =
LazyLock::new(|| Mutex::new(HashMap::new()));
static SESSION_CTX_INDEX: LazyLock<Index<Ssl, SslContext>> =
LazyLock::new(|| Ssl::new_ex_index().unwrap());
#[cfg(feature = "rpk")]
static RPK_FLAG_INDEX: Lazy<Index<SslContext, bool>> =
Lazy::new(|| SslContext::new_ex_index().unwrap());
static RPK_FLAG_INDEX: LazyLock<Index<SslContext, bool>> =
LazyLock::new(|| SslContext::new_ex_index().unwrap());
unsafe extern "C" fn free_data_box<T>(
_parent: *mut c_void,

View File

@ -1,5 +1,3 @@
use once_cell::sync::OnceCell;
use super::server::{Builder, Server};
use super::KEY;
use crate::hash::MessageDigest;
@ -12,7 +10,7 @@ use crate::ssl::{
};
use std::io::Write;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use std::sync::{Arc, OnceLock};
#[allow(clippy::type_complexity)]
pub(super) struct Method {
@ -233,7 +231,7 @@ fn test_sign_ok() {
#[test]
fn test_sign_retry_complete_ok() {
let input_cell = Arc::new(OnceCell::new());
let input_cell = Arc::new(OnceLock::new());
let input_cell_clone = input_cell.clone();
let mut builder = builder_with_private_key_method(

View File

@ -9,6 +9,7 @@ repository = { workspace = true }
documentation = "https://docs.rs/hyper-boring"
readme = "README.md"
exclude = ["test/*"]
rust-version = "1.80"
[package.metadata.docs.rs]
features = ["pq-experimental"]
@ -45,7 +46,6 @@ hyper1 = { workspace = true, optional = true }
hyper-util = { workspace = true, optional = true, features = ["client", "client-legacy"] }
hyper0 = { workspace = true, optional = true, features = ["client"] }
linked_hash_set = { workspace = true }
once_cell = { workspace = true }
boring = { workspace = true }
tokio = { workspace = true }
tokio-boring = { workspace = true }

View File

@ -6,8 +6,8 @@ use crate::cache::SessionKey;
use boring::error::ErrorStack;
use boring::ex_data::Index;
use boring::ssl::Ssl;
use once_cell::sync::OnceCell;
use std::fmt;
use std::sync::LazyLock;
use tokio_boring::SslStream;
mod cache;
@ -21,8 +21,8 @@ mod v1;
pub use self::v1::*;
fn key_index() -> Result<Index<Ssl, SessionKey>, ErrorStack> {
static IDX: OnceCell<Index<Ssl, SessionKey>> = OnceCell::new();
IDX.get_or_try_init(Ssl::new_ex_index).copied()
static IDX: LazyLock<Index<Ssl, SessionKey>> = LazyLock::new(|| Ssl::new_ex_index().unwrap());
Ok(*IDX)
}
/// Settings for [`HttpsLayer`]

View File

@ -31,7 +31,6 @@ rpk = ["boring/rpk"]
[dependencies]
boring = { workspace = true }
boring-sys = { workspace = true }
once_cell = { workspace = true }
tokio = { workspace = true }
[dev-dependencies]