Skip to content

Commit 197b9fc

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 373bbbe + 50fa2e6 commit 197b9fc

12 files changed

Lines changed: 170 additions & 107 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ jobs:
6565
key: clippy-target-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
6666
- name: Run clippy
6767
run: cargo clippy --all --all-targets
68+
- name: Check docs
69+
run: cargo doc --no-deps -p boring -p boring-sys --features rpk,pq-experimental,underscore-wildcards
70+
env:
71+
DOCS_RS: 1
6872
test:
6973
name: Test
7074
runs-on: ${{ matrix.os }}

RELEASE_NOTES

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
4.18.0
2+
- 2025-05-29 Add set_verify_param
3+
- 2025-05-28 Add support for X509_STORE_CTX_get0_untrusted
4+
- 2025-06-02 Add X509VerifyParamRef::copy_from (#361)
5+
- 2025-06-02 Fix X509VerifyContextRef::set_verify_param (#358)
6+
- 2025-06-02 Ensure we call X509_STORE_CTX_cleanup on error path too (#360)
7+
- 2025-06-02 Add mutable ex_data APIs for X509StoreContext
8+
- 2025-06-02 Add X509StoreContextRef::init_without_cleanup
9+
- 2025-06-04 Rename to reset_with_context_data
10+
- 2025-06-05 Avoid panicking in error handling
11+
- 2025-06-05 Don't unwrap when Result can be returned instead
12+
- 2025-06-04 Make X509Store shareable between contexts
13+
- 2025-06-05 Sprinkle #[must_use] (#368)
14+
- 2025-06-05 Expose SSL_set1_groups to Efficiently Set Curves on SSL Session (#346)
15+
- 2025-06-09 Upgrade bindgen to v0.72.0
16+
- 2025-06-13 Expose PKey::raw_{private,public}_key (#364)
17+
- 2025-06-10 Don't link binaries on docs.rs
18+
- 2025-06-11 Use cargo:warning for warnings
119

220
4.17.0
321
- 2025-05-27 Revert "feat(x509): Implement `Clone` for `X509Store` (#339)" (#353)

boring-sys/build/main.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,24 @@ fn get_extra_clang_args_for_bindgen(config: &Config) -> Vec<String> {
468468
}
469469

470470
fn ensure_patches_applied(config: &Config) -> io::Result<()> {
471+
if config.env.assume_patched || config.env.path.is_some() {
472+
println!(
473+
"cargo:warning=skipping git patches application, provided\
474+
native BoringSSL is expected to have the patches included"
475+
);
476+
return Ok(());
477+
} else if config.env.source_path.is_some()
478+
&& (config.features.rpk
479+
|| config.features.pq_experimental
480+
|| config.features.underscore_wildcards)
481+
{
482+
panic!(
483+
"BORING_BSSL_ASSUME_PATCHED must be set when setting
484+
BORING_BSSL_SOURCE_PATH and using any of the following
485+
features: rpk, pq-experimental, underscore-wildcards"
486+
);
487+
}
488+
471489
let mut lock_file = LockFile::open(&config.out_dir.join(".patch_lock"))?;
472490
let src_path = get_boringssl_source_path(config);
473491
let has_git = src_path.join(".git").exists();
@@ -551,25 +569,6 @@ fn built_boring_source_path(config: &Config) -> &PathBuf {
551569
static BUILD_SOURCE_PATH: OnceLock<PathBuf> = OnceLock::new();
552570

553571
BUILD_SOURCE_PATH.get_or_init(|| {
554-
if config.env.assume_patched {
555-
println!(
556-
"cargo:warning=skipping git patches application, provided\
557-
native BoringSSL is expected to have the patches included"
558-
);
559-
} else if config.env.source_path.is_some()
560-
&& (config.features.rpk
561-
|| config.features.pq_experimental
562-
|| config.features.underscore_wildcards)
563-
{
564-
panic!(
565-
"BORING_BSSL_ASSUME_PATCHED must be set when setting
566-
BORING_BSSL_SOURCE_PATH and using any of the following
567-
features: rpk, pq-experimental, underscore-wildcards"
568-
);
569-
} else {
570-
ensure_patches_applied(config).unwrap();
571-
}
572-
573572
let mut cfg = get_boringssl_cmake_config(config);
574573

575574
let num_jobs = std::env::var("NUM_JOBS").ok().or_else(|| {
@@ -660,6 +659,7 @@ fn get_cpp_runtime_lib(config: &Config) -> Option<String> {
660659

661660
fn main() {
662661
let config = Config::from_env();
662+
ensure_patches_applied(&config).unwrap();
663663
if !config.env.docs_rs {
664664
emit_link_directives(&config);
665665
}

boring-sys/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::os::raw::{c_char, c_int, c_uint, c_ulong};
2020
clippy::useless_transmute,
2121
clippy::derive_partial_eq_without_eq,
2222
clippy::ptr_offset_with_cast,
23+
unpredictable_function_pointer_comparisons, // TODO: remove Eq/PartialEq in v5
2324
dead_code
2425
)]
2526
mod generated {

boring/src/derive.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ impl<'a> Deriver<'a> {
5151
///
5252
/// It can be used to size the buffer passed to [`Deriver::derive`].
5353
#[corresponds(EVP_PKEY_derive)]
54-
/// [`EVP_PKEY_derive`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
5554
pub fn len(&mut self) -> Result<usize, ErrorStack> {
5655
unsafe {
5756
let mut len = 0;

boring/src/error.rs

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
//! Err(e) => println!("Parsing Error: {:?}", e),
1616
//! }
1717
//! ```
18-
use libc::{c_char, c_uint};
18+
use libc::{c_char, c_int, c_uint};
19+
use openssl_macros::corresponds;
1920
use std::borrow::Cow;
2021
use std::error;
2122
use std::ffi::CStr;
@@ -34,7 +35,8 @@ pub struct ErrorStack(Vec<Error>);
3435

3536
impl ErrorStack {
3637
/// Pops the contents of the OpenSSL error stack, and returns it.
37-
#[allow(clippy::must_use_candidate)]
38+
#[corresponds(ERR_get_error_line_data)]
39+
#[must_use = "Use ErrorStack::clear() to drop the error stack"]
3840
pub fn get() -> ErrorStack {
3941
let mut vec = vec![];
4042
while let Some(err) = Error::get() {
@@ -44,6 +46,7 @@ impl ErrorStack {
4446
}
4547

4648
/// Pushes the errors back onto the OpenSSL error stack.
49+
#[corresponds(ERR_put_error)]
4750
pub fn put(&self) {
4851
for error in self.errors() {
4952
error.put();
@@ -55,6 +58,14 @@ impl ErrorStack {
5558
pub(crate) fn internal_error(err: impl error::Error) -> Self {
5659
Self(vec![Error::new_internal(err.to_string())])
5760
}
61+
62+
/// Empties the current thread's error queue.
63+
#[corresponds(ERR_clear_error)]
64+
pub(crate) fn clear() {
65+
unsafe {
66+
ffi::ERR_clear_error();
67+
}
68+
}
5869
}
5970

6071
impl ErrorStack {
@@ -80,7 +91,9 @@ impl fmt::Display for ErrorStack {
8091
write!(
8192
fmt,
8293
"[{}]",
83-
err.reason_internal().unwrap_or("unknown reason")
94+
err.reason_internal()
95+
.or_else(|| err.library())
96+
.unwrap_or("unknown reason")
8497
)?;
8598
}
8699
Ok(())
@@ -101,7 +114,7 @@ impl From<ErrorStack> for fmt::Error {
101114
}
102115
}
103116

104-
/// An error reported from OpenSSL.
117+
/// A detailed error reported as part of an [`ErrorStack`].
105118
#[derive(Clone)]
106119
pub struct Error {
107120
code: c_uint,
@@ -117,7 +130,8 @@ static BORING_INTERNAL: &CStr = c"boring-rust";
117130

118131
impl Error {
119132
/// Pops the first error off the OpenSSL error stack.
120-
#[allow(clippy::must_use_candidate)]
133+
#[must_use = "Use ErrorStack::clear() to drop the error stack"]
134+
#[corresponds(ERR_get_error_line_data)]
121135
pub fn get() -> Option<Error> {
122136
unsafe {
123137
ffi::init();
@@ -150,6 +164,7 @@ impl Error {
150164
}
151165

152166
/// Pushes the error back onto the OpenSSL error stack.
167+
#[corresponds(ERR_put_error)]
153168
pub fn put(&self) {
154169
unsafe {
155170
ffi::ERR_put_error(
@@ -179,7 +194,10 @@ impl Error {
179194
}
180195
}
181196

182-
/// Returns the raw OpenSSL error code for this error.
197+
/// Returns a raw OpenSSL **packed** error code for this error, which **can't be reliably compared to any error constant**.
198+
///
199+
/// Use [`Error::library_code()`] and [`Error::reason_code()`] instead.
200+
/// Packed error codes are different than [SSL error codes](crate::ssl::ErrorCode).
183201
#[must_use]
184202
pub fn code(&self) -> c_uint {
185203
self.code
@@ -201,27 +219,17 @@ impl Error {
201219
}
202220
}
203221

204-
/// Returns the raw OpenSSL error constant for the library reporting the
205-
/// error.
222+
/// Returns the raw OpenSSL error constant for the library reporting the error (`ERR_LIB_{name}`).
223+
///
224+
/// Error [reason codes](Error::reason_code) are not globally unique, but scoped to each library.
206225
#[must_use]
207-
pub fn library_code(&self) -> libc::c_int {
226+
pub fn library_code(&self) -> c_int {
208227
ffi::ERR_GET_LIB(self.code)
209228
}
210229

211-
/// Returns the name of the function reporting the error.
212-
#[must_use]
230+
/// Returns `None`. Boring doesn't use function codes.
213231
pub fn function(&self) -> Option<&'static str> {
214-
if self.is_internal() {
215-
return None;
216-
}
217-
unsafe {
218-
let cstr = ffi::ERR_func_error_string(self.code);
219-
if cstr.is_null() {
220-
return None;
221-
}
222-
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
223-
str::from_utf8(bytes).ok()
224-
}
232+
None
225233
}
226234

227235
/// Returns the reason for the error.
@@ -237,9 +245,14 @@ impl Error {
237245
}
238246
}
239247

240-
/// Returns the raw OpenSSL error constant for the reason for the error.
248+
/// Returns [library-specific](Error::library_code) reason code corresponding to some of the `{lib}_R_{reason}` constants.
249+
///
250+
/// Reason codes are ambiguous, and different libraries reuse the same numeric values for different errors.
251+
///
252+
/// For `ERR_LIB_SYS` the reason code is `errno`. `ERR_LIB_USER` can use any values.
253+
/// Other libraries may use [`ERR_R_*`](ffi::ERR_R_FATAL) or their own codes.
241254
#[must_use]
242-
pub fn reason_code(&self) -> libc::c_int {
255+
pub fn reason_code(&self) -> c_int {
243256
ffi::ERR_GET_REASON(self.code)
244257
}
245258

@@ -256,6 +269,8 @@ impl Error {
256269
}
257270

258271
/// Returns the line in the source file which encountered the error.
272+
///
273+
/// 0 if unknown
259274
#[allow(clippy::unnecessary_cast)]
260275
#[must_use]
261276
pub fn line(&self) -> u32 {
@@ -294,20 +309,19 @@ impl Error {
294309
impl fmt::Debug for Error {
295310
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
296311
let mut builder = fmt.debug_struct("Error");
297-
builder.field("code", &self.code());
298-
if let Some(library) = self.library() {
299-
builder.field("library", &library);
300-
}
301-
builder.field("library_code", &self.library_code());
302-
if let Some(function) = self.function() {
303-
builder.field("function", &function);
304-
}
305-
if let Some(reason) = self.reason() {
306-
builder.field("reason", &reason);
312+
builder.field("code", &self.code);
313+
if !self.is_internal() {
314+
if let Some(library) = self.library() {
315+
builder.field("library", &library);
316+
}
317+
builder.field("library_code", &self.library_code());
318+
if let Some(reason) = self.reason() {
319+
builder.field("reason", &reason);
320+
}
321+
builder.field("reason_code", &self.reason_code());
322+
builder.field("file", &self.file());
323+
builder.field("line", &self.line());
307324
}
308-
builder.field("reason_code", &self.reason_code());
309-
builder.field("file", &self.file());
310-
builder.field("line", &self.line());
311325
if let Some(data) = self.data() {
312326
builder.field("data", &data);
313327
}
@@ -321,7 +335,7 @@ impl fmt::Display for Error {
321335
fmt,
322336
"{}\n\nCode: {:08X}\nLoc: {}:{}",
323337
self.reason_internal().unwrap_or("unknown TLS error"),
324-
self.code(),
338+
&self.code,
325339
self.file(),
326340
self.line()
327341
)

boring/src/rsa.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,6 @@ impl Rsa<Public> {
413413
/// `n` is the modulus common to both public and private key.
414414
/// `e` is the public exponent.
415415
#[corresponds(RSA_new)]
416-
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
417416
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
418417
unsafe {
419418
let rsa = cvt_p(ffi::RSA_new())?;
@@ -472,7 +471,6 @@ impl RsaPrivateKeyBuilder {
472471
/// `n` is the modulus common to both public and private key.
473472
/// `e` is the public exponent and `d` is the private exponent.
474473
#[corresponds(RSA_new)]
475-
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
476474
pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
477475
unsafe {
478476
let rsa = cvt_p(ffi::RSA_new())?;

boring/src/sign.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ impl<'a> Verifier<'a> {
478478
match r {
479479
1 => Ok(true),
480480
0 => {
481-
ErrorStack::get(); // discard error stack
481+
ErrorStack::clear(); // discard error stack
482482
Ok(false)
483483
}
484484
_ => Err(ErrorStack::get()),
@@ -500,7 +500,7 @@ impl<'a> Verifier<'a> {
500500
match r {
501501
1 => Ok(true),
502502
0 => {
503-
ErrorStack::get();
503+
ErrorStack::clear();
504504
Ok(false)
505505
}
506506
_ => Err(ErrorStack::get()),

boring/src/ssl/async_callbacks.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::pin::Pin;
1111
use std::sync::LazyLock;
1212
use std::task::{ready, Context, Poll, Waker};
1313

14-
/// The type of futures to pass to [`SslContextBuilderExt::set_async_select_certificate_callback`].
14+
/// The type of futures to pass to [`SslContextBuilder::set_async_select_certificate_callback`].
1515
pub type BoxSelectCertFuture = ExDataFuture<Result<BoxSelectCertFinish, AsyncSelectCertError>>;
1616

1717
/// The type of callbacks returned by [`BoxSelectCertFuture`] methods.
@@ -25,19 +25,19 @@ pub type BoxPrivateKeyMethodFuture =
2525
pub type BoxPrivateKeyMethodFinish =
2626
Box<dyn FnOnce(&mut SslRef, &mut [u8]) -> Result<usize, AsyncPrivateKeyMethodError>>;
2727

28-
/// The type of futures to pass to [`SslContextBuilderExt::set_async_get_session_callback`].
28+
/// The type of futures to pass to [`SslContextBuilder::set_async_get_session_callback`].
2929
pub type BoxGetSessionFuture = ExDataFuture<Option<BoxGetSessionFinish>>;
3030

3131
/// The type of callbacks returned by [`BoxSelectCertFuture`] methods.
3232
pub type BoxGetSessionFinish = Box<dyn FnOnce(&mut SslRef, &[u8]) -> Option<SslSession>>;
3333

34-
/// The type of futures to pass to [`SslContextBuilderExt::set_async_custom_verify_callback`].
34+
/// The type of futures to pass to [`SslContextBuilder::set_async_custom_verify_callback`].
3535
pub type BoxCustomVerifyFuture = ExDataFuture<Result<BoxCustomVerifyFinish, SslAlert>>;
3636

3737
/// The type of callbacks returned by [`BoxCustomVerifyFuture`] methods.
3838
pub type BoxCustomVerifyFinish = Box<dyn FnOnce(&mut SslRef) -> Result<(), SslAlert>>;
3939

40-
/// Convenience alias for futures stored in [`Ssl`] ex data by [`SslContextBuilderExt`] methods.
40+
/// Convenience alias for futures stored in [`Ssl`] ex data by [`SslContextBuilder`] methods.
4141
///
4242
/// Public for documentation purposes.
4343
pub type ExDataFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
@@ -123,7 +123,7 @@ impl SslContextBuilder {
123123
///
124124
/// # Safety
125125
///
126-
/// The returned [`SslSession`] must not be associated with a different [`SslContext`].
126+
/// The returned [`SslSession`] must not be associated with a different [`SslContextBuilder`].
127127
pub unsafe fn set_async_get_session_callback<F>(&mut self, callback: F)
128128
where
129129
F: Fn(&mut SslRef, &[u8]) -> Option<BoxGetSessionFuture> + Send + Sync + 'static,

0 commit comments

Comments
 (0)