Merge remote-tracking branch 'upstream/master'

This commit is contained in:
0x676e67 2025-09-04 16:20:35 +08:00
commit 197b9fcb5c
12 changed files with 170 additions and 107 deletions

View File

@ -65,6 +65,10 @@ jobs:
key: clippy-target-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }} key: clippy-target-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- name: Run clippy - name: Run clippy
run: cargo clippy --all --all-targets run: cargo clippy --all --all-targets
- name: Check docs
run: cargo doc --no-deps -p boring -p boring-sys --features rpk,pq-experimental,underscore-wildcards
env:
DOCS_RS: 1
test: test:
name: Test name: Test
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}

View File

@ -1,3 +1,21 @@
4.18.0
- 2025-05-29 Add set_verify_param
- 2025-05-28 Add support for X509_STORE_CTX_get0_untrusted
- 2025-06-02 Add X509VerifyParamRef::copy_from (#361)
- 2025-06-02 Fix X509VerifyContextRef::set_verify_param (#358)
- 2025-06-02 Ensure we call X509_STORE_CTX_cleanup on error path too (#360)
- 2025-06-02 Add mutable ex_data APIs for X509StoreContext
- 2025-06-02 Add X509StoreContextRef::init_without_cleanup
- 2025-06-04 Rename to reset_with_context_data
- 2025-06-05 Avoid panicking in error handling
- 2025-06-05 Don't unwrap when Result can be returned instead
- 2025-06-04 Make X509Store shareable between contexts
- 2025-06-05 Sprinkle #[must_use] (#368)
- 2025-06-05 Expose SSL_set1_groups to Efficiently Set Curves on SSL Session (#346)
- 2025-06-09 Upgrade bindgen to v0.72.0
- 2025-06-13 Expose PKey::raw_{private,public}_key (#364)
- 2025-06-10 Don't link binaries on docs.rs
- 2025-06-11 Use cargo:warning for warnings
4.17.0 4.17.0
- 2025-05-27 Revert "feat(x509): Implement `Clone` for `X509Store` (#339)" (#353) - 2025-05-27 Revert "feat(x509): Implement `Clone` for `X509Store` (#339)" (#353)

View File

@ -468,6 +468,24 @@ fn get_extra_clang_args_for_bindgen(config: &Config) -> Vec<String> {
} }
fn ensure_patches_applied(config: &Config) -> io::Result<()> { fn ensure_patches_applied(config: &Config) -> io::Result<()> {
if config.env.assume_patched || config.env.path.is_some() {
println!(
"cargo:warning=skipping git patches application, provided\
native BoringSSL is expected to have the patches included"
);
return Ok(());
} else if config.env.source_path.is_some()
&& (config.features.rpk
|| config.features.pq_experimental
|| config.features.underscore_wildcards)
{
panic!(
"BORING_BSSL_ASSUME_PATCHED must be set when setting
BORING_BSSL_SOURCE_PATH and using any of the following
features: rpk, pq-experimental, underscore-wildcards"
);
}
let mut lock_file = LockFile::open(&config.out_dir.join(".patch_lock"))?; let mut lock_file = LockFile::open(&config.out_dir.join(".patch_lock"))?;
let src_path = get_boringssl_source_path(config); let src_path = get_boringssl_source_path(config);
let has_git = src_path.join(".git").exists(); let has_git = src_path.join(".git").exists();
@ -551,25 +569,6 @@ fn built_boring_source_path(config: &Config) -> &PathBuf {
static BUILD_SOURCE_PATH: OnceLock<PathBuf> = OnceLock::new(); static BUILD_SOURCE_PATH: OnceLock<PathBuf> = OnceLock::new();
BUILD_SOURCE_PATH.get_or_init(|| { BUILD_SOURCE_PATH.get_or_init(|| {
if config.env.assume_patched {
println!(
"cargo:warning=skipping git patches application, provided\
native BoringSSL is expected to have the patches included"
);
} else if config.env.source_path.is_some()
&& (config.features.rpk
|| config.features.pq_experimental
|| config.features.underscore_wildcards)
{
panic!(
"BORING_BSSL_ASSUME_PATCHED must be set when setting
BORING_BSSL_SOURCE_PATH and using any of the following
features: rpk, pq-experimental, underscore-wildcards"
);
} else {
ensure_patches_applied(config).unwrap();
}
let mut cfg = get_boringssl_cmake_config(config); let mut cfg = get_boringssl_cmake_config(config);
let num_jobs = std::env::var("NUM_JOBS").ok().or_else(|| { let num_jobs = std::env::var("NUM_JOBS").ok().or_else(|| {
@ -660,6 +659,7 @@ fn get_cpp_runtime_lib(config: &Config) -> Option<String> {
fn main() { fn main() {
let config = Config::from_env(); let config = Config::from_env();
ensure_patches_applied(&config).unwrap();
if !config.env.docs_rs { if !config.env.docs_rs {
emit_link_directives(&config); emit_link_directives(&config);
} }

View File

@ -20,6 +20,7 @@ use std::os::raw::{c_char, c_int, c_uint, c_ulong};
clippy::useless_transmute, clippy::useless_transmute,
clippy::derive_partial_eq_without_eq, clippy::derive_partial_eq_without_eq,
clippy::ptr_offset_with_cast, clippy::ptr_offset_with_cast,
unpredictable_function_pointer_comparisons, // TODO: remove Eq/PartialEq in v5
dead_code dead_code
)] )]
mod generated { mod generated {

View File

@ -51,7 +51,6 @@ impl<'a> Deriver<'a> {
/// ///
/// It can be used to size the buffer passed to [`Deriver::derive`]. /// It can be used to size the buffer passed to [`Deriver::derive`].
#[corresponds(EVP_PKEY_derive)] #[corresponds(EVP_PKEY_derive)]
/// [`EVP_PKEY_derive`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
pub fn len(&mut self) -> Result<usize, ErrorStack> { pub fn len(&mut self) -> Result<usize, ErrorStack> {
unsafe { unsafe {
let mut len = 0; let mut len = 0;

View File

@ -15,7 +15,8 @@
//! Err(e) => println!("Parsing Error: {:?}", e), //! Err(e) => println!("Parsing Error: {:?}", e),
//! } //! }
//! ``` //! ```
use libc::{c_char, c_uint}; use libc::{c_char, c_int, c_uint};
use openssl_macros::corresponds;
use std::borrow::Cow; use std::borrow::Cow;
use std::error; use std::error;
use std::ffi::CStr; use std::ffi::CStr;
@ -34,7 +35,8 @@ pub struct ErrorStack(Vec<Error>);
impl ErrorStack { impl ErrorStack {
/// Pops the contents of the OpenSSL error stack, and returns it. /// Pops the contents of the OpenSSL error stack, and returns it.
#[allow(clippy::must_use_candidate)] #[corresponds(ERR_get_error_line_data)]
#[must_use = "Use ErrorStack::clear() to drop the error stack"]
pub fn get() -> ErrorStack { pub fn get() -> ErrorStack {
let mut vec = vec![]; let mut vec = vec![];
while let Some(err) = Error::get() { while let Some(err) = Error::get() {
@ -44,6 +46,7 @@ impl ErrorStack {
} }
/// Pushes the errors back onto the OpenSSL error stack. /// Pushes the errors back onto the OpenSSL error stack.
#[corresponds(ERR_put_error)]
pub fn put(&self) { pub fn put(&self) {
for error in self.errors() { for error in self.errors() {
error.put(); error.put();
@ -55,6 +58,14 @@ impl ErrorStack {
pub(crate) fn internal_error(err: impl error::Error) -> Self { pub(crate) fn internal_error(err: impl error::Error) -> Self {
Self(vec![Error::new_internal(err.to_string())]) Self(vec![Error::new_internal(err.to_string())])
} }
/// Empties the current thread's error queue.
#[corresponds(ERR_clear_error)]
pub(crate) fn clear() {
unsafe {
ffi::ERR_clear_error();
}
}
} }
impl ErrorStack { impl ErrorStack {
@ -80,7 +91,9 @@ impl fmt::Display for ErrorStack {
write!( write!(
fmt, fmt,
"[{}]", "[{}]",
err.reason_internal().unwrap_or("unknown reason") err.reason_internal()
.or_else(|| err.library())
.unwrap_or("unknown reason")
)?; )?;
} }
Ok(()) Ok(())
@ -101,7 +114,7 @@ impl From<ErrorStack> for fmt::Error {
} }
} }
/// An error reported from OpenSSL. /// A detailed error reported as part of an [`ErrorStack`].
#[derive(Clone)] #[derive(Clone)]
pub struct Error { pub struct Error {
code: c_uint, code: c_uint,
@ -117,7 +130,8 @@ static BORING_INTERNAL: &CStr = c"boring-rust";
impl Error { impl Error {
/// Pops the first error off the OpenSSL error stack. /// Pops the first error off the OpenSSL error stack.
#[allow(clippy::must_use_candidate)] #[must_use = "Use ErrorStack::clear() to drop the error stack"]
#[corresponds(ERR_get_error_line_data)]
pub fn get() -> Option<Error> { pub fn get() -> Option<Error> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -150,6 +164,7 @@ impl Error {
} }
/// Pushes the error back onto the OpenSSL error stack. /// Pushes the error back onto the OpenSSL error stack.
#[corresponds(ERR_put_error)]
pub fn put(&self) { pub fn put(&self) {
unsafe { unsafe {
ffi::ERR_put_error( ffi::ERR_put_error(
@ -179,7 +194,10 @@ impl Error {
} }
} }
/// Returns the raw OpenSSL error code for this error. /// Returns a raw OpenSSL **packed** error code for this error, which **can't be reliably compared to any error constant**.
///
/// Use [`Error::library_code()`] and [`Error::reason_code()`] instead.
/// Packed error codes are different than [SSL error codes](crate::ssl::ErrorCode).
#[must_use] #[must_use]
pub fn code(&self) -> c_uint { pub fn code(&self) -> c_uint {
self.code self.code
@ -201,27 +219,17 @@ impl Error {
} }
} }
/// Returns the raw OpenSSL error constant for the library reporting the /// Returns the raw OpenSSL error constant for the library reporting the error (`ERR_LIB_{name}`).
/// error. ///
/// Error [reason codes](Error::reason_code) are not globally unique, but scoped to each library.
#[must_use] #[must_use]
pub fn library_code(&self) -> libc::c_int { pub fn library_code(&self) -> c_int {
ffi::ERR_GET_LIB(self.code) ffi::ERR_GET_LIB(self.code)
} }
/// Returns the name of the function reporting the error. /// Returns `None`. Boring doesn't use function codes.
#[must_use]
pub fn function(&self) -> Option<&'static str> { pub fn function(&self) -> Option<&'static str> {
if self.is_internal() { None
return None;
}
unsafe {
let cstr = ffi::ERR_func_error_string(self.code);
if cstr.is_null() {
return None;
}
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
str::from_utf8(bytes).ok()
}
} }
/// Returns the reason for the error. /// Returns the reason for the error.
@ -237,9 +245,14 @@ impl Error {
} }
} }
/// Returns the raw OpenSSL error constant for the reason for the error. /// Returns [library-specific](Error::library_code) reason code corresponding to some of the `{lib}_R_{reason}` constants.
///
/// Reason codes are ambiguous, and different libraries reuse the same numeric values for different errors.
///
/// For `ERR_LIB_SYS` the reason code is `errno`. `ERR_LIB_USER` can use any values.
/// Other libraries may use [`ERR_R_*`](ffi::ERR_R_FATAL) or their own codes.
#[must_use] #[must_use]
pub fn reason_code(&self) -> libc::c_int { pub fn reason_code(&self) -> c_int {
ffi::ERR_GET_REASON(self.code) ffi::ERR_GET_REASON(self.code)
} }
@ -256,6 +269,8 @@ impl Error {
} }
/// Returns the line in the source file which encountered the error. /// Returns the line in the source file which encountered the error.
///
/// 0 if unknown
#[allow(clippy::unnecessary_cast)] #[allow(clippy::unnecessary_cast)]
#[must_use] #[must_use]
pub fn line(&self) -> u32 { pub fn line(&self) -> u32 {
@ -294,20 +309,19 @@ impl Error {
impl fmt::Debug for Error { impl fmt::Debug for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let mut builder = fmt.debug_struct("Error"); let mut builder = fmt.debug_struct("Error");
builder.field("code", &self.code()); builder.field("code", &self.code);
if !self.is_internal() {
if let Some(library) = self.library() { if let Some(library) = self.library() {
builder.field("library", &library); builder.field("library", &library);
} }
builder.field("library_code", &self.library_code()); builder.field("library_code", &self.library_code());
if let Some(function) = self.function() {
builder.field("function", &function);
}
if let Some(reason) = self.reason() { if let Some(reason) = self.reason() {
builder.field("reason", &reason); builder.field("reason", &reason);
} }
builder.field("reason_code", &self.reason_code()); builder.field("reason_code", &self.reason_code());
builder.field("file", &self.file()); builder.field("file", &self.file());
builder.field("line", &self.line()); builder.field("line", &self.line());
}
if let Some(data) = self.data() { if let Some(data) = self.data() {
builder.field("data", &data); builder.field("data", &data);
} }
@ -321,7 +335,7 @@ impl fmt::Display for Error {
fmt, fmt,
"{}\n\nCode: {:08X}\nLoc: {}:{}", "{}\n\nCode: {:08X}\nLoc: {}:{}",
self.reason_internal().unwrap_or("unknown TLS error"), self.reason_internal().unwrap_or("unknown TLS error"),
self.code(), &self.code,
self.file(), self.file(),
self.line() self.line()
) )

View File

@ -413,7 +413,6 @@ impl Rsa<Public> {
/// `n` is the modulus common to both public and private key. /// `n` is the modulus common to both public and private key.
/// `e` is the public exponent. /// `e` is the public exponent.
#[corresponds(RSA_new)] #[corresponds(RSA_new)]
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> { pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
unsafe { unsafe {
let rsa = cvt_p(ffi::RSA_new())?; let rsa = cvt_p(ffi::RSA_new())?;
@ -472,7 +471,6 @@ impl RsaPrivateKeyBuilder {
/// `n` is the modulus common to both public and private key. /// `n` is the modulus common to both public and private key.
/// `e` is the public exponent and `d` is the private exponent. /// `e` is the public exponent and `d` is the private exponent.
#[corresponds(RSA_new)] #[corresponds(RSA_new)]
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> { pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
unsafe { unsafe {
let rsa = cvt_p(ffi::RSA_new())?; let rsa = cvt_p(ffi::RSA_new())?;

View File

@ -478,7 +478,7 @@ impl<'a> Verifier<'a> {
match r { match r {
1 => Ok(true), 1 => Ok(true),
0 => { 0 => {
ErrorStack::get(); // discard error stack ErrorStack::clear(); // discard error stack
Ok(false) Ok(false)
} }
_ => Err(ErrorStack::get()), _ => Err(ErrorStack::get()),
@ -500,7 +500,7 @@ impl<'a> Verifier<'a> {
match r { match r {
1 => Ok(true), 1 => Ok(true),
0 => { 0 => {
ErrorStack::get(); ErrorStack::clear();
Ok(false) Ok(false)
} }
_ => Err(ErrorStack::get()), _ => Err(ErrorStack::get()),

View File

@ -11,7 +11,7 @@ use std::pin::Pin;
use std::sync::LazyLock; use std::sync::LazyLock;
use std::task::{ready, Context, Poll, Waker}; use std::task::{ready, Context, Poll, Waker};
/// The type of futures to pass to [`SslContextBuilderExt::set_async_select_certificate_callback`]. /// The type of futures to pass to [`SslContextBuilder::set_async_select_certificate_callback`].
pub type BoxSelectCertFuture = ExDataFuture<Result<BoxSelectCertFinish, AsyncSelectCertError>>; pub type BoxSelectCertFuture = ExDataFuture<Result<BoxSelectCertFinish, AsyncSelectCertError>>;
/// The type of callbacks returned by [`BoxSelectCertFuture`] methods. /// The type of callbacks returned by [`BoxSelectCertFuture`] methods.
@ -25,19 +25,19 @@ pub type BoxPrivateKeyMethodFuture =
pub type BoxPrivateKeyMethodFinish = pub type BoxPrivateKeyMethodFinish =
Box<dyn FnOnce(&mut SslRef, &mut [u8]) -> Result<usize, AsyncPrivateKeyMethodError>>; Box<dyn FnOnce(&mut SslRef, &mut [u8]) -> Result<usize, AsyncPrivateKeyMethodError>>;
/// The type of futures to pass to [`SslContextBuilderExt::set_async_get_session_callback`]. /// The type of futures to pass to [`SslContextBuilder::set_async_get_session_callback`].
pub type BoxGetSessionFuture = ExDataFuture<Option<BoxGetSessionFinish>>; pub type BoxGetSessionFuture = ExDataFuture<Option<BoxGetSessionFinish>>;
/// The type of callbacks returned by [`BoxSelectCertFuture`] methods. /// The type of callbacks returned by [`BoxSelectCertFuture`] methods.
pub type BoxGetSessionFinish = Box<dyn FnOnce(&mut SslRef, &[u8]) -> Option<SslSession>>; pub type BoxGetSessionFinish = Box<dyn FnOnce(&mut SslRef, &[u8]) -> Option<SslSession>>;
/// The type of futures to pass to [`SslContextBuilderExt::set_async_custom_verify_callback`]. /// The type of futures to pass to [`SslContextBuilder::set_async_custom_verify_callback`].
pub type BoxCustomVerifyFuture = ExDataFuture<Result<BoxCustomVerifyFinish, SslAlert>>; pub type BoxCustomVerifyFuture = ExDataFuture<Result<BoxCustomVerifyFinish, SslAlert>>;
/// The type of callbacks returned by [`BoxCustomVerifyFuture`] methods. /// The type of callbacks returned by [`BoxCustomVerifyFuture`] methods.
pub type BoxCustomVerifyFinish = Box<dyn FnOnce(&mut SslRef) -> Result<(), SslAlert>>; pub type BoxCustomVerifyFinish = Box<dyn FnOnce(&mut SslRef) -> Result<(), SslAlert>>;
/// Convenience alias for futures stored in [`Ssl`] ex data by [`SslContextBuilderExt`] methods. /// Convenience alias for futures stored in [`Ssl`] ex data by [`SslContextBuilder`] methods.
/// ///
/// Public for documentation purposes. /// Public for documentation purposes.
pub type ExDataFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>; pub type ExDataFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
@ -123,7 +123,7 @@ impl SslContextBuilder {
/// ///
/// # Safety /// # Safety
/// ///
/// The returned [`SslSession`] must not be associated with a different [`SslContext`]. /// The returned [`SslSession`] must not be associated with a different [`SslContextBuilder`].
pub unsafe fn set_async_get_session_callback<F>(&mut self, callback: F) pub unsafe fn set_async_get_session_callback<F>(&mut self, callback: F)
where where
F: Fn(&mut SslRef, &[u8]) -> Option<BoxGetSessionFuture> + Send + Sync + 'static, F: Fn(&mut SslRef, &[u8]) -> Option<BoxGetSessionFuture> + Send + Sync + 'static,

View File

@ -1,16 +1,20 @@
use crate::ffi; use crate::ffi;
use crate::x509::X509VerifyError; use crate::x509::X509VerifyError;
use libc::c_int; use libc::c_int;
use openssl_macros::corresponds;
use std::error; use std::error;
use std::error::Error as StdError; use std::error::Error as StdError;
use std::ffi::CStr;
use std::fmt; use std::fmt;
use std::io; use std::io;
use crate::error::ErrorStack; use crate::error::ErrorStack;
use crate::ssl::MidHandshakeSslStream; use crate::ssl::MidHandshakeSslStream;
/// An error code returned from SSL functions. /// `SSL_ERROR_*` error code returned from SSL functions.
#[derive(Debug, Copy, Clone, PartialEq, Eq)] ///
/// This is different than [packed error codes](crate::error::Error).
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct ErrorCode(c_int); pub struct ErrorCode(c_int);
impl ErrorCode { impl ErrorCode {
@ -50,16 +54,52 @@ impl ErrorCode {
/// An error occurred in the SSL library. /// An error occurred in the SSL library.
pub const SSL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SSL); pub const SSL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SSL);
/// Wrap an `SSL_ERROR_*` error code.
///
/// This is different than [packed error codes](crate::error::Error).
#[must_use] #[must_use]
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn from_raw(raw: c_int) -> ErrorCode { pub fn from_raw(raw: c_int) -> ErrorCode {
ErrorCode(raw) let code = ErrorCode(raw);
debug_assert!(
raw < 64 || code.description().is_some(),
"{raw} is not an SSL_ERROR_* code"
);
code
} }
/// An `SSL_ERROR_*` error code.
///
/// This is different than [packed error codes](crate::error::Error).
#[allow(clippy::trivially_copy_pass_by_ref)] #[allow(clippy::trivially_copy_pass_by_ref)]
#[must_use] #[must_use]
pub fn as_raw(&self) -> c_int { pub fn as_raw(&self) -> c_int {
self.0 self.0
} }
#[corresponds(SSL_error_description)]
pub fn description(self) -> Option<&'static str> {
unsafe {
let msg = ffi::SSL_error_description(self.0);
if msg.is_null() {
return None;
}
CStr::from_ptr(msg).to_str().ok()
}
}
}
impl fmt::Display for ErrorCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} ({})", self.description().unwrap_or("error"), self.0)
}
}
impl fmt::Debug for ErrorCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -68,7 +108,7 @@ pub(crate) enum InnerError {
Ssl(ErrorStack), Ssl(ErrorStack),
} }
/// An SSL error. /// A general SSL error, based on [`SSL_ERROR_*` error codes](ErrorCode).
#[derive(Debug)] #[derive(Debug)]
pub struct Error { pub struct Error {
pub(crate) code: ErrorCode, pub(crate) code: ErrorCode,
@ -76,6 +116,7 @@ pub struct Error {
} }
impl Error { impl Error {
/// An `SSL_ERROR_*` error code.
#[must_use] #[must_use]
pub fn code(&self) -> ErrorCode { pub fn code(&self) -> ErrorCode {
self.code self.code
@ -96,6 +137,7 @@ impl Error {
} }
} }
/// Stack of [library-specific errors](crate::error::Error), if available.
#[must_use] #[must_use]
pub fn ssl_error(&self) -> Option<&ErrorStack> { pub fn ssl_error(&self) -> Option<&ErrorStack> {
match self.cause { match self.cause {
@ -131,26 +173,27 @@ impl From<ErrorStack> for Error {
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.code { let msg = match self.code {
ErrorCode::ZERO_RETURN => fmt.write_str("the SSL session has been shut down"), ErrorCode::ZERO_RETURN => "the SSL session has been shut down",
ErrorCode::WANT_READ => match self.io_error() { ErrorCode::WANT_READ => match self.io_error() {
Some(_) => fmt.write_str("a nonblocking read call would have blocked"), Some(_) => "a nonblocking read call would have blocked",
None => fmt.write_str("the operation should be retried"), None => "the operation should be retried",
}, },
ErrorCode::WANT_WRITE => match self.io_error() { ErrorCode::WANT_WRITE => match self.io_error() {
Some(_) => fmt.write_str("a nonblocking write call would have blocked"), Some(_) => "a nonblocking write call would have blocked",
None => fmt.write_str("the operation should be retried"), None => "the operation should be retried",
}, },
ErrorCode::SYSCALL => match self.io_error() { ErrorCode::SYSCALL => match self.io_error() {
Some(err) => write!(fmt, "{err}"), Some(err) => return err.fmt(fmt),
None => fmt.write_str("unexpected EOF"), None => "unexpected EOF",
}, },
ErrorCode::SSL => match self.ssl_error() { ErrorCode::SSL => match self.ssl_error() {
Some(e) => write!(fmt, "{e}"), Some(err) => return err.fmt(fmt),
None => fmt.write_str("unknown BoringSSL error"), None => "unknown BoringSSL error",
}, },
ErrorCode(code) => write!(fmt, "unknown error code {code}"), ErrorCode(code) => return code.fmt(fmt),
} };
fmt.write_str(msg)
} }
} }

View File

@ -192,14 +192,14 @@ impl<T: Stackable> StackRef<T> {
} }
#[must_use] #[must_use]
pub fn iter(&'_ self) -> Iter<'_, T> { pub fn iter(&self) -> Iter<'_, T> {
Iter { Iter {
stack: self, stack: self,
idxs: 0..self.len(), idxs: 0..self.len(),
} }
} }
pub fn iter_mut(&'_ mut self) -> IterMut<'_, T> { pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut { IterMut {
idxs: 0..self.len(), idxs: 0..self.len(),
stack: self, stack: self,

View File

@ -167,11 +167,10 @@ impl X509StoreContextRef {
/// * `cert_chain` - The certificates chain. /// * `cert_chain` - The certificates chain.
/// * `with_context` - The closure that is called with the initialized context. /// * `with_context` - The closure that is called with the initialized context.
/// ///
/// This corresponds to [`X509_STORE_CTX_init`] before calling `with_context` and to /// Calls [`X509_STORE_CTX_cleanup`] after calling `with_context`.
/// [`X509_STORE_CTX_cleanup`] after calling `with_context`.
/// ///
/// [`X509_STORE_CTX_init`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_init.html
/// [`X509_STORE_CTX_cleanup`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_cleanup.html /// [`X509_STORE_CTX_cleanup`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_cleanup.html
#[corresponds(X509_STORE_CTX_init)]
pub fn init<F, T>( pub fn init<F, T>(
&mut self, &mut self,
trust: &store::X509StoreRef, trust: &store::X509StoreRef,
@ -816,7 +815,7 @@ impl X509 {
if ffi::ERR_GET_LIB(err) == ffi::ERR_LIB_PEM.0.try_into().unwrap() if ffi::ERR_GET_LIB(err) == ffi::ERR_LIB_PEM.0.try_into().unwrap()
&& ffi::ERR_GET_REASON(err) == ffi::PEM_R_NO_START_LINE && ffi::ERR_GET_REASON(err) == ffi::PEM_R_NO_START_LINE
{ {
ffi::ERR_clear_error(); ErrorStack::clear();
break; break;
} }
@ -1287,10 +1286,7 @@ pub struct X509ReqBuilder(X509Req);
impl X509ReqBuilder { impl X509ReqBuilder {
/// Returns a builder for a certificate request. /// Returns a builder for a certificate request.
/// #[corresponds(X509_REQ_new)]
/// This corresponds to [`X509_REQ_new`].
///
///[`X509_REQ_new`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_new.html
pub fn new() -> Result<X509ReqBuilder, ErrorStack> { pub fn new() -> Result<X509ReqBuilder, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -1299,10 +1295,7 @@ impl X509ReqBuilder {
} }
/// Set the numerical value of the version field. /// Set the numerical value of the version field.
/// #[corresponds(X509_REQ_set_version)]
/// This corresponds to [`X509_REQ_set_version`].
///
///[`X509_REQ_set_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_set_version.html
pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> { pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_REQ_set_version(self.0.as_ptr(), version.into())).map(|_| ()) } unsafe { cvt(ffi::X509_REQ_set_version(self.0.as_ptr(), version.into())).map(|_| ()) }
} }
@ -1460,10 +1453,7 @@ impl X509ReqRef {
} }
/// Returns the public key of the certificate request. /// Returns the public key of the certificate request.
/// #[corresponds(X509_REQ_get_pubkey)]
/// This corresponds to [`X509_REQ_get_pubkey"]
///
/// [`X509_REQ_get_pubkey`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_pubkey.html
pub fn public_key(&self) -> Result<PKey<Public>, ErrorStack> { pub fn public_key(&self) -> Result<PKey<Public>, ErrorStack> {
unsafe { unsafe {
let key = cvt_p(ffi::X509_REQ_get_pubkey(self.as_ptr()))?; let key = cvt_p(ffi::X509_REQ_get_pubkey(self.as_ptr()))?;
@ -1474,10 +1464,7 @@ impl X509ReqRef {
/// Check if the certificate request is signed using the given public key. /// Check if the certificate request is signed using the given public key.
/// ///
/// Returns `true` if verification succeeds. /// Returns `true` if verification succeeds.
/// #[corresponds(X509_REQ_verify)]
/// This corresponds to [`X509_REQ_verify"].
///
/// [`X509_REQ_verify`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_verify.html
pub fn verify<T>(&self, key: &PKeyRef<T>) -> Result<bool, ErrorStack> pub fn verify<T>(&self, key: &PKeyRef<T>) -> Result<bool, ErrorStack>
where where
T: HasPublic, T: HasPublic,
@ -1486,8 +1473,7 @@ impl X509ReqRef {
} }
/// Returns the extensions of the certificate request. /// Returns the extensions of the certificate request.
/// #[corresponds(X509_REQ_get_extensions)]
/// This corresponds to [`X509_REQ_get_extensions"]
pub fn extensions(&self) -> Result<Stack<X509Extension>, ErrorStack> { pub fn extensions(&self) -> Result<Stack<X509Extension>, ErrorStack> {
unsafe { unsafe {
let extensions = cvt_p(ffi::X509_REQ_get_extensions(self.as_ptr()))?; let extensions = cvt_p(ffi::X509_REQ_get_extensions(self.as_ptr()))?;