sync upstream

This commit is contained in:
0x676e67 2024-12-06 22:59:10 +08:00
commit f1c29d439c
16 changed files with 266 additions and 306 deletions

View File

@ -113,16 +113,22 @@ jobs:
target: aarch64-apple-ios target: aarch64-apple-ios
os: macos-latest os: macos-latest
check_only: true check_only: true
custom_env:
IPHONEOS_DEPLOYMENT_TARGET: 17.5
# It's... theoretically possible to run tests on iPhone Simulator, # It's... theoretically possible to run tests on iPhone Simulator,
# but for now, make sure that BoringSSL only builds. # but for now, make sure that BoringSSL only builds.
- thing: aarch64-ios-sim - thing: aarch64-ios-sim
target: aarch64-apple-ios-sim target: aarch64-apple-ios-sim
os: macos-latest os: macos-latest
check_only: true check_only: true
custom_env:
IPHONEOS_DEPLOYMENT_TARGET: 17.5
- thing: x86_64-ios - thing: x86_64-ios
target: x86_64-apple-ios target: x86_64-apple-ios
os: macos-latest os: macos-latest
check_only: true check_only: true
custom_env:
IPHONEOS_DEPLOYMENT_TARGET: 17.5
- thing: i686-linux - thing: i686-linux
target: i686-unknown-linux-gnu target: i686-unknown-linux-gnu
rust: stable rust: stable

View File

@ -1,3 +1,11 @@
4.13.0
- 2024-11-26 Sync X509StoreBuilder with openssl
- 2024-11-26 Sync X509VerifyFlags with openssl
- 2021-11-21 More corresponds from openssl
- 2024-11-28 Work around Rust settings inconsistent iOS SDK version
- 2024-11-28 Clippy
- 2024-03-11 Fix Windows build
4.12.0 4.12.0
- 2024-11-20 Add bindings for SSL_CB_ACCEPT_EXIT and SSL_CB_CONNECT_EXIT - 2024-11-20 Add bindings for SSL_CB_ACCEPT_EXIT and SSL_CB_CONNECT_EXIT
- 2024-10-22 (ci): brew link x86 toolchain for macos13 runner - 2024-10-22 (ci): brew link x86 toolchain for macos13 runner

View File

@ -10,6 +10,7 @@ readme = "README.md"
keywords = ["crypto", "tls", "ssl", "dtls"] keywords = ["crypto", "tls", "ssl", "dtls"]
categories = ["cryptography", "api-bindings"] categories = ["cryptography", "api-bindings"]
edition = { workspace = true } edition = { workspace = true }
rust-version = "1.70"
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = ["rpk", "pq-experimental", "underscore-wildcards"] features = ["rpk", "pq-experimental", "underscore-wildcards"]

View File

@ -39,6 +39,7 @@
//! //!
use crate::ffi; use crate::ffi;
use libc::{c_int, c_uint, size_t}; use libc::{c_int, c_uint, size_t};
use openssl_macros::corresponds;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::ptr; use std::ptr;
@ -55,7 +56,7 @@ impl AesKey {
/// # Failure /// # Failure
/// ///
/// Returns an error if the key is not 128, 192, or 256 bits. /// Returns an error if the key is not 128, 192, or 256 bits.
#[allow(deprecated)] // https://github.com/rust-lang/rust/issues/63566 #[corresponds(AES_set_encrypt_key)]
pub fn new_encrypt(key: &[u8]) -> Result<AesKey, KeyError> { pub fn new_encrypt(key: &[u8]) -> Result<AesKey, KeyError> {
unsafe { unsafe {
assert!(key.len() <= c_int::MAX as usize / 8); assert!(key.len() <= c_int::MAX as usize / 8);
@ -79,7 +80,7 @@ impl AesKey {
/// # Failure /// # Failure
/// ///
/// Returns an error if the key is not 128, 192, or 256 bits. /// Returns an error if the key is not 128, 192, or 256 bits.
#[allow(deprecated)] // https://github.com/rust-lang/rust/issues/63566 #[corresponds(AES_set_decrypt_key)]
pub fn new_decrypt(key: &[u8]) -> Result<AesKey, KeyError> { pub fn new_decrypt(key: &[u8]) -> Result<AesKey, KeyError> {
unsafe { unsafe {
assert!(key.len() <= c_int::MAX as usize / 8); assert!(key.len() <= c_int::MAX as usize / 8);
@ -113,6 +114,7 @@ impl AesKey {
/// ///
/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or if /// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or if
/// `out` is not 8 bytes longer than `in_` /// `out` is not 8 bytes longer than `in_`
#[corresponds(AES_wrap_key)]
pub fn wrap_key( pub fn wrap_key(
key: &AesKey, key: &AesKey,
iv: Option<[u8; 8]>, iv: Option<[u8; 8]>,
@ -151,6 +153,7 @@ pub fn wrap_key(
/// ///
/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or /// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or
/// if `in_` is not 8 bytes longer than `out` /// if `in_` is not 8 bytes longer than `out`
#[corresponds(AES_unwrap_key)]
pub fn unwrap_key( pub fn unwrap_key(
key: &AesKey, key: &AesKey,
iv: Option<[u8; 8]>, iv: Option<[u8; 8]>,

View File

@ -41,6 +41,7 @@ use crate::nid::Nid;
use crate::stack::Stackable; use crate::stack::Stackable;
use crate::string::OpensslString; use crate::string::OpensslString;
use crate::{cvt, cvt_p}; use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
foreign_type_and_impl_send_sync! { foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_GENERALIZEDTIME; type CType = ffi::ASN1_GENERALIZEDTIME;
@ -187,10 +188,7 @@ foreign_type_and_impl_send_sync! {
impl Asn1TimeRef { impl Asn1TimeRef {
/// Find difference between two times /// Find difference between two times
/// #[corresponds(ASN1_TIME_diff)]
/// This corresponds to [`ASN1_TIME_diff`].
///
/// [`ASN1_TIME_diff`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_TIME_diff.html
pub fn diff(&self, compare: &Self) -> Result<TimeDiff, ErrorStack> { pub fn diff(&self, compare: &Self) -> Result<TimeDiff, ErrorStack> {
let mut days = 0; let mut days = 0;
let mut secs = 0; let mut secs = 0;
@ -205,12 +203,7 @@ impl Asn1TimeRef {
} }
/// Compare two times /// Compare two times
/// #[corresponds(ASN1_TIME_compare)]
/// This corresponds to [`ASN1_TIME_compare`] but is implemented using [`diff`] so that it is
/// also supported on older versions of OpenSSL.
///
/// [`ASN1_TIME_compare`]: https://www.openssl.org/docs/man1.1.1/man3/ASN1_TIME_compare.html
/// [`diff`]: struct.Asn1TimeRef.html#method.diff
pub fn compare(&self, other: &Self) -> Result<Ordering, ErrorStack> { pub fn compare(&self, other: &Self) -> Result<Ordering, ErrorStack> {
let d = self.diff(other)?; let d = self.diff(other)?;
if d.days > 0 || d.secs > 0 { if d.days > 0 || d.secs > 0 {
@ -240,7 +233,7 @@ impl PartialEq<Asn1Time> for Asn1TimeRef {
} }
} }
impl<'a> PartialEq<Asn1Time> for &'a Asn1TimeRef { impl PartialEq<Asn1Time> for &Asn1TimeRef {
fn eq(&self, other: &Asn1Time) -> bool { fn eq(&self, other: &Asn1Time) -> bool {
self.diff(other) self.diff(other)
.map(|t| t.days == 0 && t.secs == 0) .map(|t| t.days == 0 && t.secs == 0)
@ -260,7 +253,7 @@ impl PartialOrd<Asn1Time> for Asn1TimeRef {
} }
} }
impl<'a> PartialOrd<Asn1Time> for &'a Asn1TimeRef { impl PartialOrd<Asn1Time> for &Asn1TimeRef {
fn partial_cmp(&self, other: &Asn1Time) -> Option<Ordering> { fn partial_cmp(&self, other: &Asn1Time) -> Option<Ordering> {
self.compare(other).ok() self.compare(other).ok()
} }
@ -289,6 +282,7 @@ impl fmt::Debug for Asn1TimeRef {
} }
impl Asn1Time { impl Asn1Time {
#[corresponds(ASN1_TIME_new)]
fn new() -> Result<Asn1Time, ErrorStack> { fn new() -> Result<Asn1Time, ErrorStack> {
ffi::init(); ffi::init();
@ -298,6 +292,7 @@ impl Asn1Time {
} }
} }
#[corresponds(X509_gmtime_adj)]
fn from_period(period: c_long) -> Result<Asn1Time, ErrorStack> { fn from_period(period: c_long) -> Result<Asn1Time, ErrorStack> {
ffi::init(); ffi::init();
@ -313,6 +308,7 @@ impl Asn1Time {
} }
/// Creates a new time from the specified `time_t` value /// Creates a new time from the specified `time_t` value
#[corresponds(ASN1_TIME_set)]
pub fn from_unix(time: time_t) -> Result<Asn1Time, ErrorStack> { pub fn from_unix(time: time_t) -> Result<Asn1Time, ErrorStack> {
ffi::init(); ffi::init();
@ -323,10 +319,7 @@ impl Asn1Time {
} }
/// Creates a new time corresponding to the specified ASN1 time string. /// Creates a new time corresponding to the specified ASN1 time string.
/// #[corresponds(ASN1_TIME_set_string)]
/// This corresponds to [`ASN1_TIME_set_string`].
///
/// [`ASN1_TIME_set_string`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
#[allow(clippy::should_implement_trait)] #[allow(clippy::should_implement_trait)]
pub fn from_str(s: &str) -> Result<Asn1Time, ErrorStack> { pub fn from_str(s: &str) -> Result<Asn1Time, ErrorStack> {
unsafe { unsafe {
@ -401,6 +394,7 @@ impl Asn1StringRef {
/// ASN.1 strings may utilize UTF-16, ASCII, BMP, or UTF8. This is important to /// ASN.1 strings may utilize UTF-16, ASCII, BMP, or UTF8. This is important to
/// consume the string in a meaningful way without knowing the underlying /// consume the string in a meaningful way without knowing the underlying
/// format. /// format.
#[corresponds(ASN1_STRING_to_UTF8)]
pub fn as_utf8(&self) -> Result<OpensslString, ErrorStack> { pub fn as_utf8(&self) -> Result<OpensslString, ErrorStack> {
unsafe { unsafe {
let mut ptr = ptr::null_mut(); let mut ptr = ptr::null_mut();
@ -419,11 +413,13 @@ impl Asn1StringRef {
/// strings in rust, it is preferable to use [`as_utf8`] /// strings in rust, it is preferable to use [`as_utf8`]
/// ///
/// [`as_utf8`]: struct.Asn1String.html#method.as_utf8 /// [`as_utf8`]: struct.Asn1String.html#method.as_utf8
#[corresponds(ASN1_STRING_get0_data)]
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) } unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) }
} }
/// Returns the number of bytes in the string. /// Returns the number of bytes in the string.
#[corresponds(ASN1_STRING_length)]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
unsafe { ffi::ASN1_STRING_length(self.as_ptr()) as usize } unsafe { ffi::ASN1_STRING_length(self.as_ptr()) as usize }
} }
@ -481,10 +477,7 @@ impl Asn1IntegerRef {
} }
/// Converts the integer to a `BigNum`. /// Converts the integer to a `BigNum`.
/// #[corresponds(ASN1_INTEGER_to_BN)]
/// This corresponds to [`ASN1_INTEGER_to_BN`].
///
/// [`ASN1_INTEGER_to_BN`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_get.html
pub fn to_bn(&self) -> Result<BigNum, ErrorStack> { pub fn to_bn(&self) -> Result<BigNum, ErrorStack> {
unsafe { unsafe {
cvt_p(crate::ffi::ASN1_INTEGER_to_BN( cvt_p(crate::ffi::ASN1_INTEGER_to_BN(
@ -498,10 +491,8 @@ impl Asn1IntegerRef {
/// Sets the ASN.1 value to the value of a signed 32-bit integer, for larger numbers /// Sets the ASN.1 value to the value of a signed 32-bit integer, for larger numbers
/// see [`bn`]. /// see [`bn`].
/// ///
/// OpenSSL documentation at [`ASN1_INTEGER_set`]
///
/// [`bn`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer /// [`bn`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer
/// [`ASN1_INTEGER_set`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_set.html #[corresponds(ASN1_INTEGER_set)]
pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> { pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> {
unsafe { cvt(crate::ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) } unsafe { cvt(crate::ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) }
} }
@ -521,11 +512,13 @@ foreign_type_and_impl_send_sync! {
impl Asn1BitStringRef { impl Asn1BitStringRef {
/// Returns the Asn1BitString as a slice. /// Returns the Asn1BitString as a slice.
#[corresponds(ASN1_STRING_get0_data)]
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) } unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) }
} }
/// Returns the number of bytes in the string. /// Returns the number of bytes in the string.
#[corresponds(ASN1_STRING_length)]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize } unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize }
} }
@ -561,12 +554,8 @@ impl Stackable for Asn1Object {
} }
impl Asn1Object { impl Asn1Object {
/// Constructs an ASN.1 Object Identifier from a string representation of /// Constructs an ASN.1 Object Identifier from a string representation of the OID.
/// the OID. #[corresponds(OBJ_txt2obj)]
///
/// This corresponds to [`OBJ_txt2obj`].
///
/// [`OBJ_txt2obj`]: https://www.openssl.org/docs/man1.1.0/man3/OBJ_txt2obj.html
#[allow(clippy::should_implement_trait)] #[allow(clippy::should_implement_trait)]
pub fn from_str(txt: &str) -> Result<Asn1Object, ErrorStack> { pub fn from_str(txt: &str) -> Result<Asn1Object, ErrorStack> {
unsafe { unsafe {

View File

@ -3,16 +3,14 @@ use crate::cvt_n;
use crate::error::ErrorStack; use crate::error::ErrorStack;
use crate::ffi; use crate::ffi;
use libc::c_int; use libc::c_int;
use openssl_macros::corresponds;
/// Encodes a slice of bytes to a base64 string. /// Encodes a slice of bytes to a base64 string.
/// ///
/// This corresponds to [`EVP_EncodeBlock`].
///
/// # Panics /// # Panics
/// ///
/// Panics if the input length or computed output length overflow a signed C integer. /// Panics if the input length or computed output length overflow a signed C integer.
/// #[corresponds(EVP_EncodeBlock)]
/// [`EVP_EncodeBlock`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DecodeBlock.html
pub fn encode_block(src: &[u8]) -> String { pub fn encode_block(src: &[u8]) -> String {
assert!(src.len() <= c_int::MAX as usize); assert!(src.len() <= c_int::MAX as usize);
let src_len = src.len(); let src_len = src.len();
@ -33,13 +31,10 @@ pub fn encode_block(src: &[u8]) -> String {
/// Decodes a base64-encoded string to bytes. /// Decodes a base64-encoded string to bytes.
/// ///
/// This corresponds to [`EVP_DecodeBlock`].
///
/// # Panics /// # Panics
/// ///
/// Panics if the input length or computed output length overflow a signed C integer. /// Panics if the input length or computed output length overflow a signed C integer.
/// #[corresponds(EVP_DecodeBlock)]
/// [`EVP_DecodeBlock`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DecodeBlock.html
pub fn decode_block(src: &str) -> Result<Vec<u8>, ErrorStack> { pub fn decode_block(src: &str) -> Result<Vec<u8>, ErrorStack> {
let src = src.trim(); let src = src.trim();

View File

@ -9,7 +9,7 @@ use crate::error::ErrorStack;
pub struct MemBioSlice<'a>(*mut ffi::BIO, PhantomData<&'a [u8]>); pub struct MemBioSlice<'a>(*mut ffi::BIO, PhantomData<&'a [u8]>);
impl<'a> Drop for MemBioSlice<'a> { impl Drop for MemBioSlice<'_> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
ffi::BIO_free_all(self.0); ffi::BIO_free_all(self.0);

View File

@ -35,6 +35,7 @@ use crate::error::ErrorStack;
use crate::ffi::BN_is_negative; use crate::ffi::BN_is_negative;
use crate::string::OpensslString; use crate::string::OpensslString;
use crate::{cvt, cvt_n, cvt_p}; use crate::{cvt, cvt_n, cvt_p};
use openssl_macros::corresponds;
/// Options for the most significant bits of a randomly generated `BigNum`. /// Options for the most significant bits of a randomly generated `BigNum`.
pub struct MsbOption(c_int); pub struct MsbOption(c_int);
@ -69,10 +70,7 @@ foreign_type_and_impl_send_sync! {
impl BigNumContext { impl BigNumContext {
/// Returns a new `BigNumContext`. /// Returns a new `BigNumContext`.
/// #[corresponds(BN_CTX_new)]
/// See OpenSSL documentation at [`BN_CTX_new`].
///
/// [`BN_CTX_new`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_CTX_new.html
pub fn new() -> Result<BigNumContext, ErrorStack> { pub fn new() -> Result<BigNumContext, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -115,46 +113,31 @@ impl BigNumRef {
/// Erases the memory used by this `BigNum`, resetting its value to 0. /// Erases the memory used by this `BigNum`, resetting its value to 0.
/// ///
/// This can be used to destroy sensitive data such as keys when they are no longer needed. /// This can be used to destroy sensitive data such as keys when they are no longer needed.
/// #[corresponds(BN_clear)]
/// OpenSSL documentation at [`BN_clear`]
///
/// [`BN_clear`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_clear.html
pub fn clear(&mut self) { pub fn clear(&mut self) {
unsafe { ffi::BN_clear(self.as_ptr()) } unsafe { ffi::BN_clear(self.as_ptr()) }
} }
/// Adds a `u32` to `self`. /// Adds a `u32` to `self`.
/// #[corresponds(BN_add_word)]
/// OpenSSL documentation at [`BN_add_word`]
///
/// [`BN_add_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_add_word.html
pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> { pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) } unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
} }
/// Subtracts a `u32` from `self`. /// Subtracts a `u32` from `self`.
/// #[corresponds(BN_sub_word)]
/// OpenSSL documentation at [`BN_sub_word`]
///
/// [`BN_sub_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_sub_word.html
pub fn sub_word(&mut self, w: u32) -> Result<(), ErrorStack> { pub fn sub_word(&mut self, w: u32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) } unsafe { cvt(ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
} }
/// Multiplies a `u32` by `self`. /// Multiplies a `u32` by `self`.
/// #[corresponds(BN_mul_word)]
/// OpenSSL documentation at [`BN_mul_word`]
///
/// [`BN_mul_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mul_word.html
pub fn mul_word(&mut self, w: u32) -> Result<(), ErrorStack> { pub fn mul_word(&mut self, w: u32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) } unsafe { cvt(ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
} }
/// Divides `self` by a `u32`, returning the remainder. /// Divides `self` by a `u32`, returning the remainder.
/// #[corresponds(BN_div_word)]
/// OpenSSL documentation at [`BN_div_word`]
///
/// [`BN_div_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div_word.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> { pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> {
unsafe { unsafe {
@ -168,10 +151,7 @@ impl BigNumRef {
} }
/// Returns the result of `self` modulo `w`. /// Returns the result of `self` modulo `w`.
/// #[corresponds(BN_mod_word)]
/// OpenSSL documentation at [`BN_mod_word`]
///
/// [`BN_mod_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_word.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> { pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> {
unsafe { unsafe {
@ -186,19 +166,13 @@ impl BigNumRef {
/// Places a cryptographically-secure pseudo-random nonnegative /// Places a cryptographically-secure pseudo-random nonnegative
/// number less than `self` in `rnd`. /// number less than `self` in `rnd`.
/// #[corresponds(BN_rand_range)]
/// OpenSSL documentation at [`BN_rand_range`]
///
/// [`BN_rand_range`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rand_range.html
pub fn rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> { pub fn rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
} }
/// The cryptographically weak counterpart to `rand_in_range`. /// The cryptographically weak counterpart to `rand_in_range`.
/// #[corresponds(BN_pseudo_rand_range)]
/// OpenSSL documentation at [`BN_pseudo_rand_range`]
///
/// [`BN_pseudo_rand_range`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_pseudo_rand_range.html
pub fn pseudo_rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> { pub fn pseudo_rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
} }
@ -206,10 +180,7 @@ impl BigNumRef {
/// Sets bit `n`. Equivalent to `self |= (1 << n)`. /// Sets bit `n`. Equivalent to `self |= (1 << n)`.
/// ///
/// When setting a bit outside of `self`, it is expanded. /// When setting a bit outside of `self`, it is expanded.
/// #[corresponds(BN_set_bit)]
/// OpenSSL documentation at [`BN_set_bit`]
///
/// [`BN_set_bit`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_set_bit.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> { pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_set_bit(self.as_ptr(), n.into())).map(|_| ()) } unsafe { cvt(ffi::BN_set_bit(self.as_ptr(), n.into())).map(|_| ()) }
@ -218,20 +189,14 @@ impl BigNumRef {
/// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`. /// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`.
/// ///
/// When clearing a bit outside of `self`, an error is returned. /// When clearing a bit outside of `self`, an error is returned.
/// #[corresponds(BN_clear_bit)]
/// OpenSSL documentation at [`BN_clear_bit`]
///
/// [`BN_clear_bit`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_clear_bit.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> { pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_clear_bit(self.as_ptr(), n.into())).map(|_| ()) } unsafe { cvt(ffi::BN_clear_bit(self.as_ptr(), n.into())).map(|_| ()) }
} }
/// Returns `true` if the `n`th bit of `self` is set to 1, `false` otherwise. /// Returns `true` if the `n`th bit of `self` is set to 1, `false` otherwise.
/// #[corresponds(BN_is_bit_set)]
/// OpenSSL documentation at [`BN_is_bit_set`]
///
/// [`BN_is_bit_set`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_is_bit_set.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn is_bit_set(&self, n: i32) -> bool { pub fn is_bit_set(&self, n: i32) -> bool {
unsafe { ffi::BN_is_bit_set(self.as_ptr(), n.into()) == 1 } unsafe { ffi::BN_is_bit_set(self.as_ptr(), n.into()) == 1 }
@ -240,94 +205,69 @@ impl BigNumRef {
/// Truncates `self` to the lowest `n` bits. /// Truncates `self` to the lowest `n` bits.
/// ///
/// An error occurs if `self` is already shorter than `n` bits. /// An error occurs if `self` is already shorter than `n` bits.
/// #[corresponds(BN_mask_bits)]
/// OpenSSL documentation at [`BN_mask_bits`]
///
/// [`BN_mask_bits`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mask_bits.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> { pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) } unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) }
} }
/// Places `a << 1` in `self`. Equivalent to `self * 2`. /// Places `a << 1` in `self`. Equivalent to `self * 2`.
/// #[corresponds(BN_lshift1)]
/// OpenSSL documentation at [`BN_lshift1`]
///
/// [`BN_lshift1`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_lshift1.html
pub fn lshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> { pub fn lshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
} }
/// Places `a >> 1` in `self`. Equivalent to `self / 2`. /// Places `a >> 1` in `self`. Equivalent to `self / 2`.
/// #[corresponds(BN_rshift1)]
/// OpenSSL documentation at [`BN_rshift1`]
///
/// [`BN_rshift1`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rshift1.html
pub fn rshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> { pub fn rshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_rshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_rshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
} }
/// Places `a + b` in `self`. [`core::ops::Add`] is also implemented for `BigNumRef`. /// Places `a + b` in `self`. [`core::ops::Add`] is also implemented for `BigNumRef`.
/// ///
/// OpenSSL documentation at [`BN_add`]
///
/// [`core::ops::Add`]: struct.BigNumRef.html#method.add /// [`core::ops::Add`]: struct.BigNumRef.html#method.add
/// [`BN_add`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_add.html #[corresponds(BN_add)]
pub fn checked_add(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> { pub fn checked_add(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_add(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_add(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
} }
/// Places `a - b` in `self`. [`core::ops::Sub`] is also implemented for `BigNumRef`. /// Places `a - b` in `self`. [`core::ops::Sub`] is also implemented for `BigNumRef`.
/// ///
/// OpenSSL documentation at [`BN_sub`]
///
/// [`core::ops::Sub`]: struct.BigNumRef.html#method.sub /// [`core::ops::Sub`]: struct.BigNumRef.html#method.sub
/// [`BN_sub`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_sub.html #[corresponds(BN_sub)]
pub fn checked_sub(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> { pub fn checked_sub(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_sub(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_sub(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
} }
/// Places `a << n` in `self`. Equivalent to `a * 2 ^ n`. /// Places `a << n` in `self`. Equivalent to `a * 2 ^ n`.
/// #[corresponds(BN_lshift)]
/// OpenSSL documentation at [`BN_lshift`]
///
/// [`BN_lshift`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_lshift.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn lshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> { pub fn lshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_lshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) } unsafe { cvt(ffi::BN_lshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
} }
/// Places `a >> n` in `self`. Equivalent to `a / 2 ^ n`. /// Places `a >> n` in `self`. Equivalent to `a / 2 ^ n`.
/// #[corresponds(BN_rshift)]
/// OpenSSL documentation at [`BN_rshift`]
///
/// [`BN_rshift`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rshift.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn rshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> { pub fn rshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_rshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) } unsafe { cvt(ffi::BN_rshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
} }
/// Creates a new BigNum with the same value. /// Creates a new BigNum with the same value.
/// #[corresponds(BN_dup)]
/// OpenSSL documentation at [`BN_dup`]
///
/// [`BN_dup`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_dup.html
pub fn to_owned(&self) -> Result<BigNum, ErrorStack> { pub fn to_owned(&self) -> Result<BigNum, ErrorStack> {
unsafe { cvt_p(ffi::BN_dup(self.as_ptr())).map(|b| BigNum::from_ptr(b)) } unsafe { cvt_p(ffi::BN_dup(self.as_ptr())).map(|b| BigNum::from_ptr(b)) }
} }
/// Sets the sign of `self`. Pass true to set `self` to a negative. False sets /// Sets the sign of `self`. Pass true to set `self` to a negative. False sets
/// `self` positive. /// `self` positive.
#[corresponds(BN_set_negative)]
pub fn set_negative(&mut self, negative: bool) { pub fn set_negative(&mut self, negative: bool) {
unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) } unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) }
} }
/// Compare the absolute values of `self` and `oth`. /// Compare the absolute values of `self` and `oth`.
/// ///
/// OpenSSL documentation at [`BN_ucmp`]
///
/// [`BN_ucmp`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_ucmp.html
///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
@ -338,20 +278,19 @@ impl BigNumRef {
/// ///
/// assert_eq!(s.ucmp(&o), Ordering::Equal); /// assert_eq!(s.ucmp(&o), Ordering::Equal);
/// ``` /// ```
#[corresponds(BN_ucmp)]
pub fn ucmp(&self, oth: &BigNumRef) -> Ordering { pub fn ucmp(&self, oth: &BigNumRef) -> Ordering {
unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
} }
/// Returns `true` if `self` is negative. /// Returns `true` if `self` is negative.
#[corresponds(BN_is_negative)]
pub fn is_negative(&self) -> bool { pub fn is_negative(&self) -> bool {
unsafe { BN_is_negative(self.as_ptr()) == 1 } unsafe { BN_is_negative(self.as_ptr()) == 1 }
} }
/// Returns the number of significant bits in `self`. /// Returns the number of significant bits in `self`.
/// #[corresponds(BN_num_bits)]
/// OpenSSL documentation at [`BN_num_bits`]
///
/// [`BN_num_bits`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_num_bits.html
pub fn num_bits(&self) -> i32 { pub fn num_bits(&self) -> i32 {
unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 } unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 }
} }
@ -384,10 +323,8 @@ impl BigNumRef {
/// } /// }
/// ``` /// ```
/// ///
/// OpenSSL documentation at [`BN_rand`]
///
/// [`constants`]: index.html#constants /// [`constants`]: index.html#constants
/// [`BN_rand`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rand.html #[corresponds(BN_rand)]
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> { pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
unsafe { unsafe {
@ -402,10 +339,7 @@ impl BigNumRef {
} }
/// The cryptographically weak counterpart to `rand`. Not suitable for key generation. /// The cryptographically weak counterpart to `rand`. Not suitable for key generation.
/// #[corresponds(BN_pseudo_rand)]
/// OpenSSL documentation at [`BN_pseudo_rand`]
///
/// [`BN_pseudo_rand`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_pseudo_rand.html
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> { pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
unsafe { unsafe {
@ -442,10 +376,7 @@ impl BigNumRef {
/// Ok((big)) /// Ok((big))
/// } /// }
/// ``` /// ```
/// #[corresponds(BN_generate_prime_ex)]
/// OpenSSL documentation at [`BN_generate_prime_ex`]
///
/// [`BN_generate_prime_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_generate_prime_ex.html
pub fn generate_prime( pub fn generate_prime(
&mut self, &mut self,
bits: i32, bits: i32,
@ -469,10 +400,8 @@ impl BigNumRef {
/// Places the result of `a * b` in `self`. /// Places the result of `a * b` in `self`.
/// [`core::ops::Mul`] is also implemented for `BigNumRef`. /// [`core::ops::Mul`] is also implemented for `BigNumRef`.
/// ///
/// OpenSSL documentation at [`BN_mul`]
///
/// [`core::ops::Mul`]: struct.BigNumRef.html#method.mul /// [`core::ops::Mul`]: struct.BigNumRef.html#method.mul
/// [`BN_mul`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mul.html #[corresponds(BN_mul)]
pub fn checked_mul( pub fn checked_mul(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -493,10 +422,8 @@ impl BigNumRef {
/// Places the result of `a / b` in `self`. The remainder is discarded. /// Places the result of `a / b` in `self`. The remainder is discarded.
/// [`core::ops::Div`] is also implemented for `BigNumRef`. /// [`core::ops::Div`] is also implemented for `BigNumRef`.
/// ///
/// OpenSSL documentation at [`BN_div`]
///
/// [`core::ops::Div`]: struct.BigNumRef.html#method.div /// [`core::ops::Div`]: struct.BigNumRef.html#method.div
/// [`BN_div`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div.html #[corresponds(BN_div)]
pub fn checked_div( pub fn checked_div(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -516,10 +443,7 @@ impl BigNumRef {
} }
/// Places the result of `a % b` in `self`. /// Places the result of `a % b` in `self`.
/// #[corresponds(BN_div)]
/// OpenSSL documentation at [`BN_div`]
///
/// [`BN_div`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div.html
pub fn checked_rem( pub fn checked_rem(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -539,10 +463,7 @@ impl BigNumRef {
} }
/// Places the result of `a / b` in `self` and `a % b` in `rem`. /// Places the result of `a / b` in `self` and `a % b` in `rem`.
/// #[corresponds(BN_div)]
/// OpenSSL documentation at [`BN_div`]
///
/// [`BN_div`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div.html
pub fn div_rem( pub fn div_rem(
&mut self, &mut self,
rem: &mut BigNumRef, rem: &mut BigNumRef,
@ -563,20 +484,14 @@ impl BigNumRef {
} }
/// Places the result of `a²` in `self`. /// Places the result of `a²` in `self`.
/// #[corresponds(BN_sqr)]
/// OpenSSL documentation at [`BN_sqr`]
///
/// [`BN_sqr`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_sqr.html
pub fn sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack> { pub fn sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) }
} }
/// Places the result of `a mod m` in `self`. As opposed to `div_rem` /// Places the result of `a mod m` in `self`. As opposed to `div_rem`
/// the result is non-negative. /// the result is non-negative.
/// #[corresponds(BN_nnmod)]
/// OpenSSL documentation at [`BN_nnmod`]
///
/// [`BN_nnmod`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_nnmod.html
pub fn nnmod( pub fn nnmod(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -595,10 +510,7 @@ impl BigNumRef {
} }
/// Places the result of `(a + b) mod m` in `self`. /// Places the result of `(a + b) mod m` in `self`.
/// #[corresponds(BN_mod_add)]
/// OpenSSL documentation at [`BN_mod_add`]
///
/// [`BN_mod_add`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_add.html
pub fn mod_add( pub fn mod_add(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -619,10 +531,7 @@ impl BigNumRef {
} }
/// Places the result of `(a - b) mod m` in `self`. /// Places the result of `(a - b) mod m` in `self`.
/// #[corresponds(BN_mod_sub)]
/// OpenSSL documentation at [`BN_mod_sub`]
///
/// [`BN_mod_sub`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_sub.html
pub fn mod_sub( pub fn mod_sub(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -643,10 +552,7 @@ impl BigNumRef {
} }
/// Places the result of `(a * b) mod m` in `self`. /// Places the result of `(a * b) mod m` in `self`.
/// #[corresponds(BN_mod_mul)]
/// OpenSSL documentation at [`BN_mod_mul`]
///
/// [`BN_mod_mul`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_mul.html
pub fn mod_mul( pub fn mod_mul(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -667,10 +573,7 @@ impl BigNumRef {
} }
/// Places the result of `a² mod m` in `self`. /// Places the result of `a² mod m` in `self`.
/// #[corresponds(BN_mod_sqr)]
/// OpenSSL documentation at [`BN_mod_sqr`]
///
/// [`BN_mod_sqr`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_sqr.html
pub fn mod_sqr( pub fn mod_sqr(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -689,10 +592,7 @@ impl BigNumRef {
} }
/// Places the result of `a^p` in `self`. /// Places the result of `a^p` in `self`.
/// #[corresponds(BN_exp)]
/// OpenSSL documentation at [`BN_exp`]
///
/// [`BN_exp`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_exp.html
pub fn exp( pub fn exp(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -711,10 +611,7 @@ impl BigNumRef {
} }
/// Places the result of `a^p mod m` in `self`. /// Places the result of `a^p mod m` in `self`.
/// #[corresponds(BN_mod_exp)]
/// OpenSSL documentation at [`BN_mod_exp`]
///
/// [`BN_mod_exp`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_exp.html
pub fn mod_exp( pub fn mod_exp(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -735,6 +632,7 @@ impl BigNumRef {
} }
/// Places the inverse of `a` modulo `n` in `self`. /// Places the inverse of `a` modulo `n` in `self`.
#[corresponds(BN_mod_inverse)]
pub fn mod_inverse( pub fn mod_inverse(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -753,10 +651,7 @@ impl BigNumRef {
} }
/// Places the greatest common denominator of `a` and `b` in `self`. /// Places the greatest common denominator of `a` and `b` in `self`.
/// #[corresponds(BN_gcd)]
/// OpenSSL documentation at [`BN_gcd`]
///
/// [`BN_gcd`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_gcd.html
pub fn gcd( pub fn gcd(
&mut self, &mut self,
a: &BigNumRef, a: &BigNumRef,
@ -778,13 +673,10 @@ impl BigNumRef {
/// ///
/// Performs a Miller-Rabin probabilistic primality test with `checks` iterations. /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
/// ///
/// OpenSSL documentation at [`BN_is_prime_ex`]
///
/// [`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_is_prime_ex.html
///
/// # Return Value /// # Return Value
/// ///
/// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`. /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
#[corresponds(BN_is_prime_ex)]
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> { pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> {
unsafe { unsafe {
@ -804,13 +696,10 @@ impl BigNumRef {
/// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks` /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks`
/// iterations. /// iterations.
/// ///
/// OpenSSL documentation at [`BN_is_prime_fasttest_ex`]
///
/// [`BN_is_prime_fasttest_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_is_prime_fasttest_ex.html
///
/// # Return Value /// # Return Value
/// ///
/// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`. /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
#[corresponds(BN_is_prime_fasttest_ex)]
#[allow(clippy::useless_conversion)] #[allow(clippy::useless_conversion)]
pub fn is_prime_fasttest( pub fn is_prime_fasttest(
&self, &self,
@ -842,6 +731,7 @@ impl BigNumRef {
/// let s_vec = s.to_vec(); /// let s_vec = s.to_vec();
/// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r); /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
/// ``` /// ```
#[corresponds(BN_bn2bin)]
pub fn to_vec(&self) -> Vec<u8> { pub fn to_vec(&self) -> Vec<u8> {
let size = self.num_bytes() as usize; let size = self.num_bytes() as usize;
let mut v = Vec::with_capacity(size); let mut v = Vec::with_capacity(size);
@ -890,6 +780,7 @@ impl BigNumRef {
/// ///
/// assert_eq!(&**s.to_dec_str().unwrap(), "-12345"); /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
/// ``` /// ```
#[corresponds(BN_bn2dec)]
pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> { pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> {
unsafe { unsafe {
let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?; let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?;
@ -905,6 +796,7 @@ impl BigNumRef {
/// ///
/// assert_eq!(&**s.to_hex_str().unwrap(), "-99ff"); /// assert_eq!(&**s.to_hex_str().unwrap(), "-99ff");
/// ``` /// ```
#[corresponds(BN_bn2hex)]
pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> { pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
unsafe { unsafe {
let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?; let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?;
@ -913,6 +805,7 @@ impl BigNumRef {
} }
/// Returns an `Asn1Integer` containing the value of `self`. /// Returns an `Asn1Integer` containing the value of `self`.
#[corresponds(BN_to_ASN1_INTEGER)]
pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> { pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
unsafe { unsafe {
cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut())) cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
@ -923,6 +816,7 @@ impl BigNumRef {
impl BigNum { impl BigNum {
/// Creates a new `BigNum` with the value 0. /// Creates a new `BigNum` with the value 0.
#[corresponds(BN_new)]
pub fn new() -> Result<BigNum, ErrorStack> { pub fn new() -> Result<BigNum, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -932,10 +826,7 @@ impl BigNum {
} }
/// Creates a new `BigNum` with the given value. /// Creates a new `BigNum` with the given value.
/// #[corresponds(BN_set_word)]
/// OpenSSL documentation at [`BN_set_word`]
///
/// [`BN_set_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_set_word.html
pub fn from_u32(n: u32) -> Result<BigNum, ErrorStack> { pub fn from_u32(n: u32) -> Result<BigNum, ErrorStack> {
BigNum::new().and_then(|v| unsafe { BigNum::new().and_then(|v| unsafe {
cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v) cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v)
@ -943,10 +834,7 @@ impl BigNum {
} }
/// Creates a `BigNum` from a decimal string. /// Creates a `BigNum` from a decimal string.
/// #[corresponds(BN_dec2bn)]
/// OpenSSL documentation at [`BN_dec2bn`]
///
/// [`BN_dec2bn`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_dec2bn.html
pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> { pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -958,10 +846,7 @@ impl BigNum {
} }
/// Creates a `BigNum` from a hexadecimal string. /// Creates a `BigNum` from a hexadecimal string.
/// #[corresponds(BN_hex2bn)]
/// OpenSSL documentation at [`BN_hex2bn`]
///
/// [`BN_hex2bn`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_hex2bn.html
pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> { pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -984,6 +869,7 @@ impl BigNum {
/// ///
/// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap()); /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
/// ``` /// ```
#[corresponds(BN_bin2bn)]
pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> { pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -1126,7 +1012,7 @@ macro_rules! delegate {
}; };
} }
impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef { impl Add<&BigNumRef> for &BigNumRef {
type Output = BigNum; type Output = BigNum;
fn add(self, oth: &BigNumRef) -> BigNum { fn add(self, oth: &BigNumRef) -> BigNum {
@ -1138,7 +1024,7 @@ impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
delegate!(Add, add); delegate!(Add, add);
impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef { impl Sub<&BigNumRef> for &BigNumRef {
type Output = BigNum; type Output = BigNum;
fn sub(self, oth: &BigNumRef) -> BigNum { fn sub(self, oth: &BigNumRef) -> BigNum {
@ -1150,7 +1036,7 @@ impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
delegate!(Sub, sub); delegate!(Sub, sub);
impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef { impl Mul<&BigNumRef> for &BigNumRef {
type Output = BigNum; type Output = BigNum;
fn mul(self, oth: &BigNumRef) -> BigNum { fn mul(self, oth: &BigNumRef) -> BigNum {
@ -1163,7 +1049,7 @@ impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
delegate!(Mul, mul); delegate!(Mul, mul);
impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef { impl<'b> Div<&'b BigNumRef> for &BigNumRef {
type Output = BigNum; type Output = BigNum;
fn div(self, oth: &'b BigNumRef) -> BigNum { fn div(self, oth: &'b BigNumRef) -> BigNum {
@ -1176,7 +1062,7 @@ impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
delegate!(Div, div); delegate!(Div, div);
impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef { impl<'b> Rem<&'b BigNumRef> for &BigNumRef {
type Output = BigNum; type Output = BigNum;
fn rem(self, oth: &'b BigNumRef) -> BigNum { fn rem(self, oth: &'b BigNumRef) -> BigNum {
@ -1189,7 +1075,7 @@ impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
delegate!(Rem, rem); delegate!(Rem, rem);
impl<'a> Shl<i32> for &'a BigNumRef { impl Shl<i32> for &BigNumRef {
type Output = BigNum; type Output = BigNum;
fn shl(self, n: i32) -> BigNum { fn shl(self, n: i32) -> BigNum {
@ -1199,7 +1085,7 @@ impl<'a> Shl<i32> for &'a BigNumRef {
} }
} }
impl<'a> Shl<i32> for &'a BigNum { impl Shl<i32> for &BigNum {
type Output = BigNum; type Output = BigNum;
fn shl(self, n: i32) -> BigNum { fn shl(self, n: i32) -> BigNum {
@ -1207,7 +1093,7 @@ impl<'a> Shl<i32> for &'a BigNum {
} }
} }
impl<'a> Shr<i32> for &'a BigNumRef { impl Shr<i32> for &BigNumRef {
type Output = BigNum; type Output = BigNum;
fn shr(self, n: i32) -> BigNum { fn shr(self, n: i32) -> BigNum {
@ -1217,7 +1103,7 @@ impl<'a> Shr<i32> for &'a BigNumRef {
} }
} }
impl<'a> Shr<i32> for &'a BigNum { impl Shr<i32> for &BigNum {
type Output = BigNum; type Output = BigNum;
fn shr(self, n: i32) -> BigNum { fn shr(self, n: i32) -> BigNum {
@ -1225,7 +1111,7 @@ impl<'a> Shr<i32> for &'a BigNum {
} }
} }
impl<'a> Neg for &'a BigNumRef { impl Neg for &BigNumRef {
type Output = BigNum; type Output = BigNum;
fn neg(self) -> BigNum { fn neg(self) -> BigNum {
@ -1233,7 +1119,7 @@ impl<'a> Neg for &'a BigNumRef {
} }
} }
impl<'a> Neg for &'a BigNum { impl Neg for &BigNum {
type Output = BigNum; type Output = BigNum;
fn neg(self) -> BigNum { fn neg(self) -> BigNum {

View File

@ -11,10 +11,10 @@ use crate::{cvt, cvt_p};
/// A type used to derive a shared secret between two keys. /// A type used to derive a shared secret between two keys.
pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>); pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>);
unsafe impl<'a> Sync for Deriver<'a> {} unsafe impl Sync for Deriver<'_> {}
unsafe impl<'a> Send for Deriver<'a> {} unsafe impl Send for Deriver<'_> {}
impl<'a> Drop for Deriver<'a> { impl Drop for Deriver<'_> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
ffi::EVP_PKEY_CTX_free(self.0); ffi::EVP_PKEY_CTX_free(self.0);

View File

@ -78,10 +78,10 @@ pub struct Signer<'a> {
_p: PhantomData<&'a ()>, _p: PhantomData<&'a ()>,
} }
unsafe impl<'a> Sync for Signer<'a> {} unsafe impl Sync for Signer<'_> {}
unsafe impl<'a> Send for Signer<'a> {} unsafe impl Send for Signer<'_> {}
impl<'a> Drop for Signer<'a> { impl Drop for Signer<'_> {
fn drop(&mut self) { fn drop(&mut self) {
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it. // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
unsafe { unsafe {
@ -337,7 +337,7 @@ impl<'a> Signer<'a> {
} }
} }
impl<'a> Write for Signer<'a> { impl Write for Signer<'_> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.update(buf)?; self.update(buf)?;
Ok(buf.len()) Ok(buf.len())
@ -354,10 +354,10 @@ pub struct Verifier<'a> {
pkey_pd: PhantomData<&'a ()>, pkey_pd: PhantomData<&'a ()>,
} }
unsafe impl<'a> Sync for Verifier<'a> {} unsafe impl Sync for Verifier<'_> {}
unsafe impl<'a> Send for Verifier<'a> {} unsafe impl Send for Verifier<'_> {}
impl<'a> Drop for Verifier<'a> { impl Drop for Verifier<'_> {
fn drop(&mut self) { fn drop(&mut self) {
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it. // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
unsafe { unsafe {
@ -560,7 +560,7 @@ impl<'a> Verifier<'a> {
} }
} }
impl<'a> Write for Verifier<'a> { impl Write for Verifier<'_> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.update(buf)?; self.update(buf)?;
Ok(buf.len()) Ok(buf.len())

View File

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

View File

@ -64,7 +64,7 @@ fn untrusted_with_set_cert() {
let cert = ssl.peer_certificate().unwrap(); let cert = ssl.peer_certificate().unwrap();
let cert_chain = ssl.peer_cert_chain().unwrap(); let cert_chain = ssl.peer_cert_chain().unwrap();
assert_eq!(store.objects().len(), 0); assert_eq!(store.objects_len(), 0);
X509StoreContext::new() X509StoreContext::new()
.unwrap() .unwrap()
@ -94,7 +94,7 @@ fn trusted_with_set_cert() {
let cert = ssl.peer_certificate().unwrap(); let cert = ssl.peer_certificate().unwrap();
let cert_chain = ssl.peer_cert_chain().unwrap(); let cert_chain = ssl.peer_cert_chain().unwrap();
assert_eq!(store.objects().len(), 1); assert_eq!(store.objects_len(), 1);
X509StoreContext::new() X509StoreContext::new()
.unwrap() .unwrap()

View File

@ -338,7 +338,7 @@ impl<'a, T: Stackable> DoubleEndedIterator for Iter<'a, T> {
} }
} }
impl<'a, T: Stackable> ExactSizeIterator for Iter<'a, T> {} impl<T: Stackable> ExactSizeIterator for Iter<'_, T> {}
/// A mutable iterator over the stack's contents. /// A mutable iterator over the stack's contents.
pub struct IterMut<'a, T: Stackable + 'a> { pub struct IterMut<'a, T: Stackable + 'a> {
@ -372,4 +372,4 @@ impl<'a, T: Stackable> DoubleEndedIterator for IterMut<'a, T> {
} }
} }
impl<'a, T: Stackable> ExactSizeIterator for IterMut<'a, T> {} impl<T: Stackable> ExactSizeIterator for IterMut<'_, T> {}

View File

@ -121,7 +121,7 @@ impl X509StoreContextRef {
{ {
struct Cleanup<'a>(&'a mut X509StoreContextRef); struct Cleanup<'a>(&'a mut X509StoreContextRef);
impl<'a> Drop for Cleanup<'a> { impl Drop for Cleanup<'_> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
ffi::X509_STORE_CTX_cleanup(self.0.as_ptr()); ffi::X509_STORE_CTX_cleanup(self.0.as_ptr());
@ -460,6 +460,7 @@ impl X509Ref {
} }
} }
#[corresponds(X509_get_pubkey)]
pub fn public_key(&self) -> Result<PKey<Public>, ErrorStack> { pub fn public_key(&self) -> Result<PKey<Public>, ErrorStack> {
unsafe { unsafe {
let pkey = cvt_p(ffi::X509_get_pubkey(self.as_ptr()))?; let pkey = cvt_p(ffi::X509_get_pubkey(self.as_ptr()))?;
@ -468,10 +469,7 @@ impl X509Ref {
} }
/// Returns a digest of the DER representation of the certificate. /// Returns a digest of the DER representation of the certificate.
/// #[corresponds(X509_digest)]
/// This corresponds to [`X509_digest`].
///
/// [`X509_digest`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_digest.html
pub fn digest(&self, hash_type: MessageDigest) -> Result<DigestBytes, ErrorStack> { pub fn digest(&self, hash_type: MessageDigest) -> Result<DigestBytes, ErrorStack> {
unsafe { unsafe {
let mut digest = DigestBytes { let mut digest = DigestBytes {
@ -497,6 +495,7 @@ impl X509Ref {
} }
/// Returns the certificate's Not After validity period. /// Returns the certificate's Not After validity period.
#[corresponds(X509_getm_notAfter)]
pub fn not_after(&self) -> &Asn1TimeRef { pub fn not_after(&self) -> &Asn1TimeRef {
unsafe { unsafe {
let date = X509_getm_notAfter(self.as_ptr()); let date = X509_getm_notAfter(self.as_ptr());
@ -506,6 +505,7 @@ impl X509Ref {
} }
/// Returns the certificate's Not Before validity period. /// Returns the certificate's Not Before validity period.
#[corresponds(X509_getm_notBefore)]
pub fn not_before(&self) -> &Asn1TimeRef { pub fn not_before(&self) -> &Asn1TimeRef {
unsafe { unsafe {
let date = X509_getm_notBefore(self.as_ptr()); let date = X509_getm_notBefore(self.as_ptr());
@ -515,6 +515,7 @@ impl X509Ref {
} }
/// Returns the certificate's signature /// Returns the certificate's signature
#[corresponds(X509_get0_signature)]
pub fn signature(&self) -> &Asn1BitStringRef { pub fn signature(&self) -> &Asn1BitStringRef {
unsafe { unsafe {
let mut signature = ptr::null(); let mut signature = ptr::null();
@ -525,6 +526,7 @@ impl X509Ref {
} }
/// Returns the certificate's signature algorithm. /// Returns the certificate's signature algorithm.
#[corresponds(X509_get0_signature)]
pub fn signature_algorithm(&self) -> &X509AlgorithmRef { pub fn signature_algorithm(&self) -> &X509AlgorithmRef {
unsafe { unsafe {
let mut algor = ptr::null(); let mut algor = ptr::null();
@ -536,11 +538,13 @@ impl X509Ref {
/// Returns the list of OCSP responder URLs specified in the certificate's Authority Information /// Returns the list of OCSP responder URLs specified in the certificate's Authority Information
/// Access field. /// Access field.
#[corresponds(X509_get1_ocsp)]
pub fn ocsp_responders(&self) -> Result<Stack<OpensslString>, ErrorStack> { pub fn ocsp_responders(&self) -> Result<Stack<OpensslString>, ErrorStack> {
unsafe { cvt_p(ffi::X509_get1_ocsp(self.as_ptr())).map(|p| Stack::from_ptr(p)) } unsafe { cvt_p(ffi::X509_get1_ocsp(self.as_ptr())).map(|p| Stack::from_ptr(p)) }
} }
/// Checks that this certificate issued `subject`. /// Checks that this certificate issued `subject`.
#[corresponds(X509_check_issued)]
pub fn issued(&self, subject: &X509Ref) -> X509VerifyResult { pub fn issued(&self, subject: &X509Ref) -> X509VerifyResult {
unsafe { unsafe {
let r = ffi::X509_check_issued(self.as_ptr(), subject.as_ptr()); let r = ffi::X509_check_issued(self.as_ptr(), subject.as_ptr());
@ -554,10 +558,7 @@ impl X509Ref {
/// are performed. /// are performed.
/// ///
/// Returns `true` if verification succeeds. /// Returns `true` if verification succeeds.
/// #[corresponds(X509_verify)]
/// This corresponds to [`X509_verify`].
///
/// [`X509_verify`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_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,
@ -566,10 +567,7 @@ impl X509Ref {
} }
/// Returns this certificate's serial number. /// Returns this certificate's serial number.
/// #[corresponds(X509_get_serialNumber)]
/// This corresponds to [`X509_get_serialNumber`].
///
/// [`X509_get_serialNumber`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_get_serialNumber.html
pub fn serial_number(&self) -> &Asn1IntegerRef { pub fn serial_number(&self) -> &Asn1IntegerRef {
unsafe { unsafe {
let r = ffi::X509_get_serialNumber(self.as_ptr()); let r = ffi::X509_get_serialNumber(self.as_ptr());
@ -595,20 +593,14 @@ impl X509Ref {
/// Serializes the certificate into a PEM-encoded X509 structure. /// Serializes the certificate into a PEM-encoded X509 structure.
/// ///
/// The output will have a header of `-----BEGIN CERTIFICATE-----`. /// The output will have a header of `-----BEGIN CERTIFICATE-----`.
/// #[corresponds(PEM_write_bio_X509)]
/// This corresponds to [`PEM_write_bio_X509`].
///
/// [`PEM_write_bio_X509`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_write_bio_X509.html
to_pem, to_pem,
ffi::PEM_write_bio_X509 ffi::PEM_write_bio_X509
} }
to_der! { to_der! {
/// Serializes the certificate into a DER-encoded X509 structure. /// Serializes the certificate into a DER-encoded X509 structure.
/// #[corresponds(i2d_X509)]
/// This corresponds to [`i2d_X509`].
///
/// [`i2d_X509`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_X509.html
to_der, to_der,
ffi::i2d_X509 ffi::i2d_X509
} }
@ -635,10 +627,7 @@ impl X509 {
/// Deserializes a PEM-encoded X509 structure. /// Deserializes a PEM-encoded X509 structure.
/// ///
/// The input should have a header of `-----BEGIN CERTIFICATE-----`. /// The input should have a header of `-----BEGIN CERTIFICATE-----`.
/// #[corresponds(PEM_read_bio_X509)]
/// This corresponds to [`PEM_read_bio_X509`].
///
/// [`PEM_read_bio_X509`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_X509.html
from_pem, from_pem,
X509, X509,
ffi::PEM_read_bio_X509 ffi::PEM_read_bio_X509
@ -646,10 +635,7 @@ impl X509 {
from_der! { from_der! {
/// Deserializes a DER-encoded X509 structure. /// Deserializes a DER-encoded X509 structure.
/// #[corresponds(d2i_X509)]
/// This corresponds to [`d2i_X509`].
///
/// [`d2i_X509`]: https://www.openssl.org/docs/manmaster/man3/d2i_X509.html
from_der, from_der,
X509, X509,
ffi::d2i_X509, ffi::d2i_X509,
@ -657,6 +643,7 @@ impl X509 {
} }
/// Deserializes a list of PEM-formatted certificates. /// Deserializes a list of PEM-formatted certificates.
#[corresponds(PEM_read_bio_X509)]
pub fn stack_from_pem(pem: &[u8]) -> Result<Vec<X509>, ErrorStack> { pub fn stack_from_pem(pem: &[u8]) -> Result<Vec<X509>, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -735,7 +722,7 @@ impl Stackable for X509 {
/// A context object required to construct certain `X509` extension values. /// A context object required to construct certain `X509` extension values.
pub struct X509v3Context<'a>(ffi::X509V3_CTX, PhantomData<(&'a X509Ref, &'a ConfRef)>); pub struct X509v3Context<'a>(ffi::X509V3_CTX, PhantomData<(&'a X509Ref, &'a ConfRef)>);
impl<'a> X509v3Context<'a> { impl X509v3Context<'_> {
pub fn as_ptr(&self) -> *mut ffi::X509V3_CTX { pub fn as_ptr(&self) -> *mut ffi::X509V3_CTX {
&self.0 as *const _ as *mut _ &self.0 as *const _ as *mut _
} }

View File

@ -43,10 +43,11 @@
use crate::error::ErrorStack; use crate::error::ErrorStack;
use crate::ffi; use crate::ffi;
use crate::stack::StackRef; use crate::stack::StackRef;
use crate::x509::verify::{X509Flags, X509VerifyParamRef}; use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef};
use crate::x509::{X509Object, X509}; use crate::x509::{X509Object, X509};
use crate::{cvt, cvt_p}; use crate::{cvt, cvt_p};
use foreign_types::{ForeignType, ForeignTypeRef}; use foreign_types::{ForeignType, ForeignTypeRef};
use openssl_macros::corresponds;
use std::mem; use std::mem;
foreign_type_and_impl_send_sync! { foreign_type_and_impl_send_sync! {
@ -80,6 +81,7 @@ impl X509StoreBuilder {
impl X509StoreBuilderRef { impl X509StoreBuilderRef {
/// Adds a certificate to the certificate store. /// Adds a certificate to the certificate store.
// FIXME should take an &X509Ref // FIXME should take an &X509Ref
#[corresponds(X509_STORE_add_cert)]
pub fn add_cert(&mut self, cert: X509) -> Result<(), ErrorStack> { pub fn add_cert(&mut self, cert: X509) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
} }
@ -89,18 +91,16 @@ impl X509StoreBuilderRef {
/// These locations are read from the `SSL_CERT_FILE` and `SSL_CERT_DIR` /// These locations are read from the `SSL_CERT_FILE` and `SSL_CERT_DIR`
/// environment variables if present, or defaults specified at OpenSSL /// environment variables if present, or defaults specified at OpenSSL
/// build time otherwise. /// build time otherwise.
#[corresponds(X509_STORE_set_default_paths)]
pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> { pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) }
} }
/// Sets verify flags. /// Sets certificate chain validation related flags.
/// #[corresponds(X509_STORE_set_flags)]
/// This corresponds to [`X509_STORE_set_flags`]. pub fn set_flags(&mut self, flags: X509VerifyFlags) {
///
/// [`X509_STORE_set_flags`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_set_flags.html
pub fn set_flags(&mut self, flags: X509Flags) {
unsafe { unsafe {
ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits()); cvt(ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits())).unwrap();
} }
} }
@ -112,6 +112,12 @@ impl X509StoreBuilderRef {
pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef { pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::X509_STORE_get0_param(self.as_ptr())) } unsafe { X509VerifyParamRef::from_ptr_mut(ffi::X509_STORE_get0_param(self.as_ptr())) }
} }
/// Sets certificate chain validation related parameters.
#[corresponds(X509_STORE_set1_param)]
pub fn set_param(&mut self, param: &X509VerifyParamRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_STORE_set1_param(self.as_ptr(), param.as_ptr())).map(|_| ()) }
}
} }
foreign_type_and_impl_send_sync! { foreign_type_and_impl_send_sync! {
@ -123,8 +129,24 @@ foreign_type_and_impl_send_sync! {
} }
impl X509StoreRef { impl X509StoreRef {
/// **Warning: this method is unsound**
///
/// Get a reference to the cache of certificates in this store. /// Get a reference to the cache of certificates in this store.
///
/// # Safety
/// References may be invalidated by any access to the shared cache.
#[deprecated(
note = "This method is unsound https://github.com/sfackler/rust-openssl/issues/2096"
)]
#[corresponds(X509_STORE_get0_objects)]
pub fn objects(&self) -> &StackRef<X509Object> { pub fn objects(&self) -> &StackRef<X509Object> {
unsafe { StackRef::from_ptr(ffi::X509_STORE_get0_objects(self.as_ptr())) } unsafe { StackRef::from_ptr(ffi::X509_STORE_get0_objects(self.as_ptr())) }
} }
/// For testing only, where it doesn't have to expose an unsafe pointer
#[cfg(test)]
#[allow(deprecated)]
pub fn objects_len(&self) -> usize {
self.objects().len()
}
} }

View File

@ -1,14 +1,16 @@
use crate::ffi; use crate::ffi;
use foreign_types::ForeignTypeRef; use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_uint, c_ulong}; use libc::{c_int, c_uint, c_ulong, time_t};
use openssl_macros::corresponds;
use std::net::IpAddr; use std::net::IpAddr;
use crate::cvt;
use crate::error::ErrorStack; use crate::error::ErrorStack;
use crate::{cvt, cvt_p};
bitflags! { bitflags! {
/// Flags used to check an `X509` certificate. /// Flags used to check an `X509` certificate.
#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct X509CheckFlags: c_uint { pub struct X509CheckFlags: c_uint {
const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT as _; const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT as _;
const NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS as _; const NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS as _;
@ -24,11 +26,33 @@ bitflags! {
} }
} }
#[doc(hidden)]
#[deprecated(note = "X509Flags renamed to X509VerifyFlags")]
pub use X509VerifyFlags as X509Flags;
bitflags! { bitflags! {
/// Flags used to check an `X509` certificate. /// Flags used to check an `X509` certificate.
#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
pub struct X509Flags: c_ulong { #[repr(transparent)]
pub struct X509VerifyFlags: c_ulong {
const CB_ISSUER_CHECK = ffi::X509_V_FLAG_CB_ISSUER_CHECK as _;
const USE_CHECK_TIME = ffi::X509_V_FLAG_USE_CHECK_TIME as _;
const CRL_CHECK = ffi::X509_V_FLAG_CRL_CHECK as _;
const CRL_CHECK_ALL = ffi::X509_V_FLAG_CRL_CHECK_ALL as _;
const IGNORE_CRITICAL = ffi::X509_V_FLAG_IGNORE_CRITICAL as _;
const X509_STRICT = ffi::X509_V_FLAG_X509_STRICT as _;
const ALLOW_PROXY_CERTS = ffi::X509_V_FLAG_ALLOW_PROXY_CERTS as _;
const POLICY_CHECK = ffi::X509_V_FLAG_POLICY_CHECK as _;
const EXPLICIT_POLICY = ffi::X509_V_FLAG_EXPLICIT_POLICY as _;
const INHIBIT_ANY = ffi::X509_V_FLAG_INHIBIT_ANY as _;
const INHIBIT_MAP = ffi::X509_V_FLAG_INHIBIT_MAP as _;
const NOTIFY_POLICY = ffi::X509_V_FLAG_NOTIFY_POLICY as _;
const EXTENDED_CRL_SUPPORT = ffi::X509_V_FLAG_EXTENDED_CRL_SUPPORT as _;
const USE_DELTAS = ffi::X509_V_FLAG_USE_DELTAS as _;
const CHECK_SS_SIGNATURE = ffi::X509_V_FLAG_CHECK_SS_SIGNATURE as _;
const TRUSTED_FIRST = ffi::X509_V_FLAG_TRUSTED_FIRST as _; const TRUSTED_FIRST = ffi::X509_V_FLAG_TRUSTED_FIRST as _;
const PARTIAL_CHAIN = ffi::X509_V_FLAG_PARTIAL_CHAIN as _;
const NO_ALT_CHAINS = ffi::X509_V_FLAG_NO_ALT_CHAINS as _;
} }
} }
@ -40,64 +64,91 @@ foreign_type_and_impl_send_sync! {
pub struct X509VerifyParam; pub struct X509VerifyParam;
} }
impl X509VerifyParamRef { impl X509VerifyParam {
/// Set flags. /// Create an X509VerifyParam
/// #[corresponds(X509_VERIFY_PARAM_new)]
/// This corresponds to [`X509_VERIFY_PARAM_set_flags`]. pub fn new() -> Result<Self, ErrorStack> {
///
/// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man3.2/man3/X509_VERIFY_PARAM_set_flags.html
pub fn set_flags(&mut self, flags: X509Flags) {
unsafe { unsafe {
ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits()); ffi::init();
let handle = cvt_p(ffi::X509_VERIFY_PARAM_new())?;
Ok(Self::from_ptr(handle))
}
} }
} }
/// Clear flags. impl X509VerifyParamRef {
/// /// Set verification flags.
/// Useful to clear out default flags, such as `X509Flags::TRUSTED_FIRST` when the fips feature is off. #[corresponds(X509_VERIFY_PARAM_set_flags)]
/// pub fn set_flags(&mut self, flags: X509VerifyFlags) {
/// This corresponds to [`X509_VERIFY_PARAM_clear_flags`].
///
/// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man3.2/man3/X509_VERIFY_PARAM_set_flags.html
pub fn clear_flags(&mut self, flags: X509Flags) {
unsafe { unsafe {
ffi::X509_VERIFY_PARAM_clear_flags(self.as_ptr(), flags.bits()); cvt(ffi::X509_VERIFY_PARAM_set_flags(
self.as_ptr(),
flags.bits(),
))
.unwrap();
}
}
/// Clear verification flags.
#[corresponds(X509_VERIFY_PARAM_clear_flags)]
pub fn clear_flags(&mut self, flags: X509VerifyFlags) {
unsafe {
cvt(ffi::X509_VERIFY_PARAM_clear_flags(
self.as_ptr(),
flags.bits(),
))
.unwrap();
} }
} }
/// ///
/// Set the host flags. /// Set the host flags.
/// #[corresponds(X509_VERIFY_PARAM_set_hostflags)]
/// This corresponds to [`X509_VERIFY_PARAM_set_hostflags`].
///
/// [`X509_VERIFY_PARAM_set_hostflags`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_hostflags.html
pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) {
unsafe { unsafe {
ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits()); ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits());
} }
} }
/// Gets verification flags.
#[corresponds(X509_VERIFY_PARAM_get_flags)]
pub fn flags(&self) -> X509VerifyFlags {
let bits = unsafe { ffi::X509_VERIFY_PARAM_get_flags(self.as_ptr()) };
X509VerifyFlags::from_bits_retain(bits)
}
/// Set the expected DNS hostname. /// Set the expected DNS hostname.
/// #[corresponds(X509_VERIFY_PARAM_set1_host)]
/// This corresponds to [`X509_VERIFY_PARAM_set1_host`].
///
/// [`X509_VERIFY_PARAM_set1_host`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_host.html
pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> {
unsafe { unsafe {
// len == 0 means "run strlen" :(
let raw_host = if host.is_empty() { "\0" } else { host };
cvt(ffi::X509_VERIFY_PARAM_set1_host( cvt(ffi::X509_VERIFY_PARAM_set1_host(
self.as_ptr(), self.as_ptr(),
host.as_ptr() as *const _, raw_host.as_ptr() as *const _,
host.len(), host.len(),
)) ))
.map(|_| ()) .map(|_| ())
} }
} }
/// Set the expected email address.
#[corresponds(X509_VERIFY_PARAM_set1_email)]
pub fn set_email(&mut self, email: &str) -> Result<(), ErrorStack> {
unsafe {
// len == 0 means "run strlen" :(
let raw_email = if email.is_empty() { "\0" } else { email };
cvt(ffi::X509_VERIFY_PARAM_set1_email(
self.as_ptr(),
raw_email.as_ptr() as *const _,
email.len(),
))
.map(|_| ())
}
}
/// Set the expected IPv4 or IPv6 address. /// Set the expected IPv4 or IPv6 address.
/// #[corresponds(X509_VERIFY_PARAM_set1_ip)]
/// This corresponds to [`X509_VERIFY_PARAM_set1_ip`].
///
/// [`X509_VERIFY_PARAM_set1_ip`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_ip.html
pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> { pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> {
unsafe { unsafe {
let mut buf = [0; 16]; let mut buf = [0; 16];
@ -119,4 +170,16 @@ impl X509VerifyParamRef {
.map(|_| ()) .map(|_| ())
} }
} }
/// Set the verification time, where time is of type time_t, traditionaly defined as seconds since the epoch
#[corresponds(X509_VERIFY_PARAM_set_time)]
pub fn set_time(&mut self, time: time_t) {
unsafe { ffi::X509_VERIFY_PARAM_set_time(self.as_ptr(), time) }
}
/// Set the verification depth
#[corresponds(X509_VERIFY_PARAM_set_depth)]
pub fn set_depth(&mut self, depth: c_int) {
unsafe { ffi::X509_VERIFY_PARAM_set_depth(self.as_ptr(), depth) }
}
} }