Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
197b9fcb5c
|
|
@ -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 }}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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())?;
|
||||||
|
|
|
||||||
|
|
@ -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()),
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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()))?;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue