From 7ce333d8012c64c168c55d2d4089083bc537a700 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 20 Nov 2021 19:10:20 -0500 Subject: [PATCH 1/3] More corresponds from openssl --- boring/src/aes.rs | 7 +- boring/src/asn1.rs | 43 +++----- boring/src/base64.rs | 11 +- boring/src/bn.rs | 220 +++++++++----------------------------- boring/src/x509/mod.rs | 43 +++----- boring/src/x509/store.rs | 5 + boring/src/x509/verify.rs | 18 ++-- 7 files changed, 103 insertions(+), 244 deletions(-) diff --git a/boring/src/aes.rs b/boring/src/aes.rs index 2bf95466..376d356a 100644 --- a/boring/src/aes.rs +++ b/boring/src/aes.rs @@ -41,6 +41,7 @@ use crate::ffi; use libc::{c_int, c_uint, size_t}; use std::mem::MaybeUninit; use std::ptr; +use openssl_macros::corresponds; /// Provides Error handling for parsing keys. #[derive(Debug)] @@ -55,7 +56,7 @@ impl AesKey { /// # Failure /// /// 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 { unsafe { assert!(key.len() <= c_int::MAX as usize / 8); @@ -79,7 +80,7 @@ impl AesKey { /// # Failure /// /// 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 { unsafe { 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 /// `out` is not 8 bytes longer than `in_` +#[corresponds(AES_wrap_key)] pub fn wrap_key( key: &AesKey, 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 /// if `in_` is not 8 bytes longer than `out` +#[corresponds(AES_unwrap_key)] pub fn unwrap_key( key: &AesKey, iv: Option<[u8; 8]>, diff --git a/boring/src/asn1.rs b/boring/src/asn1.rs index 8a196a7d..9fb3fcaf 100644 --- a/boring/src/asn1.rs +++ b/boring/src/asn1.rs @@ -41,6 +41,7 @@ use crate::nid::Nid; use crate::stack::Stackable; use crate::string::OpensslString; use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; foreign_type_and_impl_send_sync! { type CType = ffi::ASN1_GENERALIZEDTIME; @@ -187,10 +188,7 @@ foreign_type_and_impl_send_sync! { impl Asn1TimeRef { /// Find difference between two times - /// - /// This corresponds to [`ASN1_TIME_diff`]. - /// - /// [`ASN1_TIME_diff`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_TIME_diff.html + #[corresponds(ASN1_TIME_diff)] pub fn diff(&self, compare: &Self) -> Result { let mut days = 0; let mut secs = 0; @@ -205,12 +203,7 @@ impl Asn1TimeRef { } /// Compare two times - /// - /// 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 + #[corresponds(ASN1_TIME_compare)] pub fn compare(&self, other: &Self) -> Result { let d = self.diff(other)?; if d.days > 0 || d.secs > 0 { @@ -289,6 +282,7 @@ impl fmt::Debug for Asn1TimeRef { } impl Asn1Time { + #[corresponds(ASN1_TIME_new)] fn new() -> Result { ffi::init(); @@ -298,6 +292,7 @@ impl Asn1Time { } } + #[corresponds(X509_gmtime_adj)] fn from_period(period: c_long) -> Result { ffi::init(); @@ -313,6 +308,7 @@ impl Asn1Time { } /// Creates a new time from the specified `time_t` value + #[corresponds(ASN1_TIME_set)] pub fn from_unix(time: time_t) -> Result { ffi::init(); @@ -323,10 +319,7 @@ impl Asn1Time { } /// Creates a new time corresponding to the specified ASN1 time string. - /// - /// This corresponds to [`ASN1_TIME_set_string`]. - /// - /// [`ASN1_TIME_set_string`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html + #[corresponds(ASN1_TIME_set_string)] #[allow(clippy::should_implement_trait)] pub fn from_str(s: &str) -> Result { unsafe { @@ -401,6 +394,7 @@ impl Asn1StringRef { /// 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 /// format. + #[corresponds(ASN1_STRING_to_UTF8)] pub fn as_utf8(&self) -> Result { unsafe { let mut ptr = ptr::null_mut(); @@ -419,11 +413,13 @@ impl Asn1StringRef { /// strings in rust, it is preferable to use [`as_utf8`] /// /// [`as_utf8`]: struct.Asn1String.html#method.as_utf8 + #[corresponds(ASN1_STRING_get0_data)] pub fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) } } /// Returns the number of bytes in the string. + #[corresponds(ASN1_STRING_length)] pub fn len(&self) -> usize { unsafe { ffi::ASN1_STRING_length(self.as_ptr()) as usize } } @@ -481,10 +477,7 @@ impl Asn1IntegerRef { } /// Converts the integer to a `BigNum`. - /// - /// This corresponds to [`ASN1_INTEGER_to_BN`]. - /// - /// [`ASN1_INTEGER_to_BN`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_get.html + #[corresponds(ASN1_INTEGER_to_BN)] pub fn to_bn(&self) -> Result { unsafe { 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 /// see [`bn`]. /// - /// OpenSSL documentation at [`ASN1_INTEGER_set`] - /// /// [`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> { 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 { /// Returns the Asn1BitString as a slice. + #[corresponds(ASN1_STRING_get0_data)] pub fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) } } /// Returns the number of bytes in the string. + #[corresponds(ASN1_STRING_length)] pub fn len(&self) -> usize { unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize } } @@ -561,12 +554,8 @@ impl Stackable for Asn1Object { } impl Asn1Object { - /// Constructs an ASN.1 Object Identifier from a string representation of - /// the OID. - /// - /// This corresponds to [`OBJ_txt2obj`]. - /// - /// [`OBJ_txt2obj`]: https://www.openssl.org/docs/man1.1.0/man3/OBJ_txt2obj.html + /// Constructs an ASN.1 Object Identifier from a string representation of the OID. + #[corresponds(OBJ_txt2obj)] #[allow(clippy::should_implement_trait)] pub fn from_str(txt: &str) -> Result { unsafe { diff --git a/boring/src/base64.rs b/boring/src/base64.rs index 9b556384..75cc9cc8 100644 --- a/boring/src/base64.rs +++ b/boring/src/base64.rs @@ -3,16 +3,14 @@ use crate::cvt_n; use crate::error::ErrorStack; use crate::ffi; use libc::c_int; +use openssl_macros::corresponds; /// Encodes a slice of bytes to a base64 string. /// -/// This corresponds to [`EVP_EncodeBlock`]. -/// /// # Panics /// /// Panics if the input length or computed output length overflow a signed C integer. -/// -/// [`EVP_EncodeBlock`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DecodeBlock.html +#[corresponds(EVP_EncodeBlock)] pub fn encode_block(src: &[u8]) -> String { assert!(src.len() <= c_int::MAX as usize); let src_len = src.len(); @@ -33,13 +31,10 @@ pub fn encode_block(src: &[u8]) -> String { /// Decodes a base64-encoded string to bytes. /// -/// This corresponds to [`EVP_DecodeBlock`]. -/// /// # Panics /// /// Panics if the input length or computed output length overflow a signed C integer. -/// -/// [`EVP_DecodeBlock`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DecodeBlock.html +#[corresponds(EVP_DecodeBlock)] pub fn decode_block(src: &str) -> Result, ErrorStack> { let src = src.trim(); diff --git a/boring/src/bn.rs b/boring/src/bn.rs index 27fdeb32..58edbabb 100644 --- a/boring/src/bn.rs +++ b/boring/src/bn.rs @@ -35,6 +35,7 @@ use crate::error::ErrorStack; use crate::ffi::BN_is_negative; use crate::string::OpensslString; use crate::{cvt, cvt_n, cvt_p}; +use openssl_macros::corresponds; /// Options for the most significant bits of a randomly generated `BigNum`. pub struct MsbOption(c_int); @@ -69,10 +70,7 @@ foreign_type_and_impl_send_sync! { impl BigNumContext { /// Returns a new `BigNumContext`. - /// - /// See OpenSSL documentation at [`BN_CTX_new`]. - /// - /// [`BN_CTX_new`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_CTX_new.html + #[corresponds(BN_CTX_new)] pub fn new() -> Result { unsafe { ffi::init(); @@ -115,46 +113,31 @@ impl BigNumRef { /// 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. - /// - /// OpenSSL documentation at [`BN_clear`] - /// - /// [`BN_clear`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_clear.html + #[corresponds(BN_clear)] pub fn clear(&mut self) { unsafe { ffi::BN_clear(self.as_ptr()) } } /// Adds a `u32` to `self`. - /// - /// OpenSSL documentation at [`BN_add_word`] - /// - /// [`BN_add_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_add_word.html + #[corresponds(BN_add_word)] 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(|_| ()) } } /// Subtracts a `u32` from `self`. - /// - /// OpenSSL documentation at [`BN_sub_word`] - /// - /// [`BN_sub_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_sub_word.html + #[corresponds(BN_sub_word)] 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(|_| ()) } } /// Multiplies a `u32` by `self`. - /// - /// OpenSSL documentation at [`BN_mul_word`] - /// - /// [`BN_mul_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mul_word.html + #[corresponds(BN_mul_word)] 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(|_| ()) } } /// Divides `self` by a `u32`, returning the remainder. - /// - /// OpenSSL documentation at [`BN_div_word`] - /// - /// [`BN_div_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div_word.html + #[corresponds(BN_div_word)] #[allow(clippy::useless_conversion)] pub fn div_word(&mut self, w: u32) -> Result { unsafe { @@ -168,10 +151,7 @@ impl BigNumRef { } /// Returns the result of `self` modulo `w`. - /// - /// OpenSSL documentation at [`BN_mod_word`] - /// - /// [`BN_mod_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_word.html + #[corresponds(BN_mod_word)] #[allow(clippy::useless_conversion)] pub fn mod_word(&self, w: u32) -> Result { unsafe { @@ -186,19 +166,13 @@ impl BigNumRef { /// Places a cryptographically-secure pseudo-random nonnegative /// number less than `self` in `rnd`. - /// - /// OpenSSL documentation at [`BN_rand_range`] - /// - /// [`BN_rand_range`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rand_range.html + #[corresponds(BN_rand_range)] pub fn rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) } } /// The cryptographically weak counterpart to `rand_in_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 + #[corresponds(BN_pseudo_rand_range)] 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(|_| ()) } } @@ -206,10 +180,7 @@ impl BigNumRef { /// Sets bit `n`. Equivalent to `self |= (1 << n)`. /// /// When setting a bit outside of `self`, it is expanded. - /// - /// OpenSSL documentation at [`BN_set_bit`] - /// - /// [`BN_set_bit`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_set_bit.html + #[corresponds(BN_set_bit)] #[allow(clippy::useless_conversion)] pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> { 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)`. /// /// When clearing a bit outside of `self`, an error is returned. - /// - /// OpenSSL documentation at [`BN_clear_bit`] - /// - /// [`BN_clear_bit`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_clear_bit.html + #[corresponds(BN_clear_bit)] #[allow(clippy::useless_conversion)] pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> { 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. - /// - /// 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 + #[corresponds(BN_is_bit_set)] #[allow(clippy::useless_conversion)] pub fn is_bit_set(&self, n: i32) -> bool { 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. /// /// An error occurs if `self` is already shorter than `n` bits. - /// - /// OpenSSL documentation at [`BN_mask_bits`] - /// - /// [`BN_mask_bits`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mask_bits.html + #[corresponds(BN_mask_bits)] #[allow(clippy::useless_conversion)] pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) } } /// Places `a << 1` in `self`. Equivalent to `self * 2`. - /// - /// OpenSSL documentation at [`BN_lshift1`] - /// - /// [`BN_lshift1`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_lshift1.html + #[corresponds(BN_lshift1)] pub fn lshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) } } /// Places `a >> 1` in `self`. Equivalent to `self / 2`. - /// - /// OpenSSL documentation at [`BN_rshift1`] - /// - /// [`BN_rshift1`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rshift1.html + #[corresponds(BN_rshift1)] pub fn rshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> { 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`. /// - /// OpenSSL documentation at [`BN_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> { 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`. /// - /// OpenSSL documentation at [`BN_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> { 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`. - /// - /// OpenSSL documentation at [`BN_lshift`] - /// - /// [`BN_lshift`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_lshift.html + #[corresponds(BN_lshift)] #[allow(clippy::useless_conversion)] 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(|_| ()) } } /// Places `a >> n` in `self`. Equivalent to `a / 2 ^ n`. - /// - /// OpenSSL documentation at [`BN_rshift`] - /// - /// [`BN_rshift`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rshift.html + #[corresponds(BN_rshift)] #[allow(clippy::useless_conversion)] 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(|_| ()) } } /// Creates a new BigNum with the same value. - /// - /// OpenSSL documentation at [`BN_dup`] - /// - /// [`BN_dup`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_dup.html + #[corresponds(BN_dup)] pub fn to_owned(&self) -> Result { 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 /// `self` positive. + #[corresponds(BN_set_negative)] pub fn set_negative(&mut self, negative: bool) { unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) } } /// 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 /// /// ``` @@ -338,20 +278,19 @@ impl BigNumRef { /// /// assert_eq!(s.ucmp(&o), Ordering::Equal); /// ``` + #[corresponds(BN_ucmp)] pub fn ucmp(&self, oth: &BigNumRef) -> Ordering { unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } } /// Returns `true` if `self` is negative. + #[corresponds(BN_is_negative)] pub fn is_negative(&self) -> bool { unsafe { BN_is_negative(self.as_ptr()) == 1 } } /// Returns the number of significant bits in `self`. - /// - /// OpenSSL documentation at [`BN_num_bits`] - /// - /// [`BN_num_bits`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_num_bits.html + #[corresponds(BN_num_bits)] pub fn num_bits(&self) -> 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 - /// [`BN_rand`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rand.html + #[corresponds(BN_rand)] #[allow(clippy::useless_conversion)] pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> { unsafe { @@ -402,10 +339,7 @@ impl BigNumRef { } /// The cryptographically weak counterpart to `rand`. Not suitable for key generation. - /// - /// OpenSSL documentation at [`BN_pseudo_rand`] - /// - /// [`BN_pseudo_rand`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_pseudo_rand.html + #[corresponds(BN_pseudo_rand)] #[allow(clippy::useless_conversion)] pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> { unsafe { @@ -442,10 +376,7 @@ impl BigNumRef { /// Ok((big)) /// } /// ``` - /// - /// 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 + #[corresponds(BN_generate_prime_ex)] pub fn generate_prime( &mut self, bits: i32, @@ -469,10 +400,8 @@ impl BigNumRef { /// Places the result of `a * b` in `self`. /// [`core::ops::Mul`] is also implemented for `BigNumRef`. /// - /// OpenSSL documentation at [`BN_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( &mut self, a: &BigNumRef, @@ -493,10 +422,8 @@ impl BigNumRef { /// Places the result of `a / b` in `self`. The remainder is discarded. /// [`core::ops::Div`] is also implemented for `BigNumRef`. /// - /// OpenSSL documentation at [`BN_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( &mut self, a: &BigNumRef, @@ -516,10 +443,7 @@ impl BigNumRef { } /// Places the result of `a % b` in `self`. - /// - /// OpenSSL documentation at [`BN_div`] - /// - /// [`BN_div`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div.html + #[corresponds(BN_div)] pub fn checked_rem( &mut self, a: &BigNumRef, @@ -539,10 +463,7 @@ impl BigNumRef { } /// Places the result of `a / b` in `self` and `a % b` in `rem`. - /// - /// OpenSSL documentation at [`BN_div`] - /// - /// [`BN_div`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div.html + #[corresponds(BN_div)] pub fn div_rem( &mut self, rem: &mut BigNumRef, @@ -563,20 +484,14 @@ impl BigNumRef { } /// Places the result of `a²` in `self`. - /// - /// OpenSSL documentation at [`BN_sqr`] - /// - /// [`BN_sqr`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_sqr.html + #[corresponds(BN_sqr)] 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(|_| ()) } } /// Places the result of `a mod m` in `self`. As opposed to `div_rem` /// the result is non-negative. - /// - /// OpenSSL documentation at [`BN_nnmod`] - /// - /// [`BN_nnmod`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_nnmod.html + #[corresponds(BN_nnmod)] pub fn nnmod( &mut self, a: &BigNumRef, @@ -595,10 +510,7 @@ impl BigNumRef { } /// Places the result of `(a + b) mod m` in `self`. - /// - /// OpenSSL documentation at [`BN_mod_add`] - /// - /// [`BN_mod_add`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_add.html + #[corresponds(BN_mod_add)] pub fn mod_add( &mut self, a: &BigNumRef, @@ -619,10 +531,7 @@ impl BigNumRef { } /// Places the result of `(a - b) mod m` in `self`. - /// - /// OpenSSL documentation at [`BN_mod_sub`] - /// - /// [`BN_mod_sub`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_sub.html + #[corresponds(BN_mod_sub)] pub fn mod_sub( &mut self, a: &BigNumRef, @@ -643,10 +552,7 @@ impl BigNumRef { } /// Places the result of `(a * b) mod m` in `self`. - /// - /// OpenSSL documentation at [`BN_mod_mul`] - /// - /// [`BN_mod_mul`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_mul.html + #[corresponds(BN_mod_mul)] pub fn mod_mul( &mut self, a: &BigNumRef, @@ -667,10 +573,7 @@ impl BigNumRef { } /// Places the result of `a² mod m` in `self`. - /// - /// OpenSSL documentation at [`BN_mod_sqr`] - /// - /// [`BN_mod_sqr`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_sqr.html + #[corresponds(BN_mod_sqr)] pub fn mod_sqr( &mut self, a: &BigNumRef, @@ -689,10 +592,7 @@ impl BigNumRef { } /// Places the result of `a^p` in `self`. - /// - /// OpenSSL documentation at [`BN_exp`] - /// - /// [`BN_exp`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_exp.html + #[corresponds(BN_exp)] pub fn exp( &mut self, a: &BigNumRef, @@ -711,10 +611,7 @@ impl BigNumRef { } /// Places the result of `a^p mod m` in `self`. - /// - /// OpenSSL documentation at [`BN_mod_exp`] - /// - /// [`BN_mod_exp`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_exp.html + #[corresponds(BN_mod_exp)] pub fn mod_exp( &mut self, a: &BigNumRef, @@ -735,6 +632,7 @@ impl BigNumRef { } /// Places the inverse of `a` modulo `n` in `self`. + #[corresponds(BN_mod_inverse)] pub fn mod_inverse( &mut self, a: &BigNumRef, @@ -753,10 +651,7 @@ impl BigNumRef { } /// Places the greatest common denominator of `a` and `b` in `self`. - /// - /// OpenSSL documentation at [`BN_gcd`] - /// - /// [`BN_gcd`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_gcd.html + #[corresponds(BN_gcd)] pub fn gcd( &mut self, a: &BigNumRef, @@ -778,13 +673,10 @@ impl BigNumRef { /// /// 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 /// /// 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)] pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result { unsafe { @@ -804,13 +696,10 @@ impl BigNumRef { /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks` /// 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 /// /// 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)] pub fn is_prime_fasttest( &self, @@ -842,6 +731,7 @@ impl BigNumRef { /// let s_vec = s.to_vec(); /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r); /// ``` + #[corresponds(BN_bn2bin)] pub fn to_vec(&self) -> Vec { let size = self.num_bytes() as usize; let mut v = Vec::with_capacity(size); @@ -890,6 +780,7 @@ impl BigNumRef { /// /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345"); /// ``` + #[corresponds(BN_bn2dec)] pub fn to_dec_str(&self) -> Result { unsafe { let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?; @@ -905,6 +796,7 @@ impl BigNumRef { /// /// assert_eq!(&**s.to_hex_str().unwrap(), "-99ff"); /// ``` + #[corresponds(BN_bn2hex)] pub fn to_hex_str(&self) -> Result { unsafe { let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?; @@ -913,6 +805,7 @@ impl BigNumRef { } /// Returns an `Asn1Integer` containing the value of `self`. + #[corresponds(BN_to_ASN1_INTEGER)] pub fn to_asn1_integer(&self) -> Result { unsafe { cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut())) @@ -923,6 +816,7 @@ impl BigNumRef { impl BigNum { /// Creates a new `BigNum` with the value 0. + #[corresponds(BN_new)] pub fn new() -> Result { unsafe { ffi::init(); @@ -932,10 +826,7 @@ impl BigNum { } /// Creates a new `BigNum` with the given value. - /// - /// OpenSSL documentation at [`BN_set_word`] - /// - /// [`BN_set_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_set_word.html + #[corresponds(BN_set_word)] pub fn from_u32(n: u32) -> Result { BigNum::new().and_then(|v| unsafe { 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. - /// - /// OpenSSL documentation at [`BN_dec2bn`] - /// - /// [`BN_dec2bn`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_dec2bn.html + #[corresponds(BN_dec2bn)] pub fn from_dec_str(s: &str) -> Result { unsafe { ffi::init(); @@ -958,10 +846,7 @@ impl BigNum { } /// Creates a `BigNum` from a hexadecimal string. - /// - /// OpenSSL documentation at [`BN_hex2bn`] - /// - /// [`BN_hex2bn`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_hex2bn.html + #[corresponds(BN_hex2bn)] pub fn from_hex_str(s: &str) -> Result { unsafe { ffi::init(); @@ -984,6 +869,7 @@ impl BigNum { /// /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap()); /// ``` + #[corresponds(BN_bin2bn)] pub fn from_slice(n: &[u8]) -> Result { unsafe { ffi::init(); diff --git a/boring/src/x509/mod.rs b/boring/src/x509/mod.rs index eca2eca9..c09f4df8 100644 --- a/boring/src/x509/mod.rs +++ b/boring/src/x509/mod.rs @@ -460,6 +460,7 @@ impl X509Ref { } } + #[corresponds(X509_get_pubkey)] pub fn public_key(&self) -> Result, ErrorStack> { unsafe { 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. - /// - /// This corresponds to [`X509_digest`]. - /// - /// [`X509_digest`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_digest.html + #[corresponds(X509_digest)] pub fn digest(&self, hash_type: MessageDigest) -> Result { unsafe { let mut digest = DigestBytes { @@ -497,6 +495,7 @@ impl X509Ref { } /// Returns the certificate's Not After validity period. + #[corresponds(X509_getm_notAfter)] pub fn not_after(&self) -> &Asn1TimeRef { unsafe { let date = X509_getm_notAfter(self.as_ptr()); @@ -506,6 +505,7 @@ impl X509Ref { } /// Returns the certificate's Not Before validity period. + #[corresponds(X509_getm_notBefore)] pub fn not_before(&self) -> &Asn1TimeRef { unsafe { let date = X509_getm_notBefore(self.as_ptr()); @@ -515,6 +515,7 @@ impl X509Ref { } /// Returns the certificate's signature + #[corresponds(X509_get0_signature)] pub fn signature(&self) -> &Asn1BitStringRef { unsafe { let mut signature = ptr::null(); @@ -525,6 +526,7 @@ impl X509Ref { } /// Returns the certificate's signature algorithm. + #[corresponds(X509_get0_signature)] pub fn signature_algorithm(&self) -> &X509AlgorithmRef { unsafe { 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 /// Access field. + #[corresponds(X509_get1_ocsp)] pub fn ocsp_responders(&self) -> Result, ErrorStack> { unsafe { cvt_p(ffi::X509_get1_ocsp(self.as_ptr())).map(|p| Stack::from_ptr(p)) } } /// Checks that this certificate issued `subject`. + #[corresponds(X509_check_issued)] pub fn issued(&self, subject: &X509Ref) -> X509VerifyResult { unsafe { let r = ffi::X509_check_issued(self.as_ptr(), subject.as_ptr()); @@ -554,10 +558,7 @@ impl X509Ref { /// are performed. /// /// Returns `true` if verification succeeds. - /// - /// This corresponds to [`X509_verify`]. - /// - /// [`X509_verify`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_verify.html + #[corresponds(X509_verify)] pub fn verify(&self, key: &PKeyRef) -> Result where T: HasPublic, @@ -566,10 +567,7 @@ impl X509Ref { } /// Returns this certificate's serial number. - /// - /// This corresponds to [`X509_get_serialNumber`]. - /// - /// [`X509_get_serialNumber`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_get_serialNumber.html + #[corresponds(X509_get_serialNumber)] pub fn serial_number(&self) -> &Asn1IntegerRef { unsafe { let r = ffi::X509_get_serialNumber(self.as_ptr()); @@ -595,20 +593,14 @@ impl X509Ref { /// Serializes the certificate into a PEM-encoded X509 structure. /// /// The output will have a header of `-----BEGIN CERTIFICATE-----`. - /// - /// 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 + #[corresponds(PEM_write_bio_X509)] to_pem, ffi::PEM_write_bio_X509 } to_der! { /// Serializes the certificate into a DER-encoded X509 structure. - /// - /// This corresponds to [`i2d_X509`]. - /// - /// [`i2d_X509`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_X509.html + #[corresponds(i2d_X509)] to_der, ffi::i2d_X509 } @@ -635,10 +627,7 @@ impl X509 { /// Deserializes a PEM-encoded X509 structure. /// /// The input should have a header of `-----BEGIN CERTIFICATE-----`. - /// - /// 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 + #[corresponds(PEM_read_bio_X509)] from_pem, X509, ffi::PEM_read_bio_X509 @@ -646,10 +635,7 @@ impl X509 { from_der! { /// Deserializes a DER-encoded X509 structure. - /// - /// This corresponds to [`d2i_X509`]. - /// - /// [`d2i_X509`]: https://www.openssl.org/docs/manmaster/man3/d2i_X509.html + #[corresponds(d2i_X509)] from_der, X509, ffi::d2i_X509, @@ -657,6 +643,7 @@ impl X509 { } /// Deserializes a list of PEM-formatted certificates. + #[corresponds(PEM_read_bio_X509)] pub fn stack_from_pem(pem: &[u8]) -> Result, ErrorStack> { unsafe { ffi::init(); diff --git a/boring/src/x509/store.rs b/boring/src/x509/store.rs index ee3fb52f..2c55d705 100644 --- a/boring/src/x509/store.rs +++ b/boring/src/x509/store.rs @@ -48,6 +48,7 @@ use crate::x509::{X509Object, X509}; use crate::{cvt, cvt_p}; use foreign_types::{ForeignType, ForeignTypeRef}; use std::mem; +use openssl_macros::corresponds; foreign_type_and_impl_send_sync! { type CType = ffi::X509_STORE; @@ -80,6 +81,7 @@ impl X509StoreBuilder { impl X509StoreBuilderRef { /// Adds a certificate to the certificate store. // FIXME should take an &X509Ref + #[corresponds(X509_STORE_add_cert)] pub fn add_cert(&mut self, cert: X509) -> Result<(), ErrorStack> { unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) } } @@ -89,6 +91,7 @@ impl X509StoreBuilderRef { /// These locations are read from the `SSL_CERT_FILE` and `SSL_CERT_DIR` /// environment variables if present, or defaults specified at OpenSSL /// build time otherwise. + #[corresponds(X509_STORE_set_default_paths)] pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> { unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) } } @@ -98,6 +101,7 @@ impl X509StoreBuilderRef { /// This corresponds to [`X509_STORE_set_flags`]. /// /// [`X509_STORE_set_flags`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_set_flags.html + #[corresponds(X509_STORE_set_flags)] pub fn set_flags(&mut self, flags: X509Flags) { unsafe { ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits()); @@ -124,6 +128,7 @@ foreign_type_and_impl_send_sync! { impl X509StoreRef { /// Get a reference to the cache of certificates in this store. + #[corresponds(X509_STORE_get0_objects)] pub fn objects(&self) -> &StackRef { unsafe { StackRef::from_ptr(ffi::X509_STORE_get0_objects(self.as_ptr())) } } diff --git a/boring/src/x509/verify.rs b/boring/src/x509/verify.rs index 7ea4ddeb..933fbfe4 100644 --- a/boring/src/x509/verify.rs +++ b/boring/src/x509/verify.rs @@ -2,6 +2,7 @@ use crate::ffi; use foreign_types::ForeignTypeRef; use libc::{c_uint, c_ulong}; use std::net::IpAddr; +use openssl_macros::corresponds; use crate::cvt; use crate::error::ErrorStack; @@ -46,6 +47,7 @@ impl X509VerifyParamRef { /// This corresponds to [`X509_VERIFY_PARAM_set_flags`]. /// /// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man3.2/man3/X509_VERIFY_PARAM_set_flags.html + #[corresponds(X509_VERIFY_PARAM_set_flags)] pub fn set_flags(&mut self, flags: X509Flags) { unsafe { ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits()); @@ -59,6 +61,7 @@ impl X509VerifyParamRef { /// 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 + #[corresponds(X509_VERIFY_PARAM_clear_flags)] pub fn clear_flags(&mut self, flags: X509Flags) { unsafe { ffi::X509_VERIFY_PARAM_clear_flags(self.as_ptr(), flags.bits()); @@ -67,10 +70,7 @@ impl X509VerifyParamRef { /// /// Set the host flags. - /// - /// 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 + #[corresponds(X509_VERIFY_PARAM_set_hostflags)] pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { unsafe { ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits()); @@ -78,10 +78,7 @@ impl X509VerifyParamRef { } /// Set the expected DNS hostname. - /// - /// 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 + #[corresponds(X509_VERIFY_PARAM_set1_host)] pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { unsafe { cvt(ffi::X509_VERIFY_PARAM_set1_host( @@ -94,10 +91,7 @@ impl X509VerifyParamRef { } /// Set the expected IPv4 or IPv6 address. - /// - /// 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 + #[corresponds(X509_VERIFY_PARAM_set1_ip)] pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> { unsafe { let mut buf = [0; 16]; From 8990844b3206c3da9af0df73f9775f6958663ea8 Mon Sep 17 00:00:00 2001 From: Kornel Date: Tue, 26 Nov 2024 14:34:18 +0000 Subject: [PATCH 2/3] Sync X509VerifyFlags with openssl --- boring/src/x509/verify.rs | 103 ++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/boring/src/x509/verify.rs b/boring/src/x509/verify.rs index 933fbfe4..1968e4db 100644 --- a/boring/src/x509/verify.rs +++ b/boring/src/x509/verify.rs @@ -1,15 +1,16 @@ use crate::ffi; -use foreign_types::ForeignTypeRef; -use libc::{c_uint, c_ulong}; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::{c_int, c_uint, c_ulong, time_t}; use std::net::IpAddr; use openssl_macros::corresponds; -use crate::cvt; use crate::error::ErrorStack; +use crate::{cvt, cvt_p}; bitflags! { /// Flags used to check an `X509` certificate. #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] + #[repr(transparent)] pub struct X509CheckFlags: c_uint { const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT as _; const NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS as _; @@ -25,11 +26,33 @@ bitflags! { } } +#[doc(hidden)] +#[deprecated(note = "X509Flags renamed to X509VerifyFlags")] +pub use X509VerifyFlags as X509Flags; + bitflags! { /// Flags used to check an `X509` certificate. #[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 PARTIAL_CHAIN = ffi::X509_V_FLAG_PARTIAL_CHAIN as _; + const NO_ALT_CHAINS = ffi::X509_V_FLAG_NO_ALT_CHAINS as _; } } @@ -41,30 +64,32 @@ foreign_type_and_impl_send_sync! { pub struct X509VerifyParam; } +impl X509VerifyParam { + /// Create an X509VerifyParam + #[corresponds(X509_VERIFY_PARAM_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + let handle = cvt_p(ffi::X509_VERIFY_PARAM_new())?; + Ok(Self::from_ptr(handle)) + } + } +} + impl X509VerifyParamRef { - /// Set flags. - /// - /// This corresponds to [`X509_VERIFY_PARAM_set_flags`]. - /// - /// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man3.2/man3/X509_VERIFY_PARAM_set_flags.html + /// Set verification flags. #[corresponds(X509_VERIFY_PARAM_set_flags)] - pub fn set_flags(&mut self, flags: X509Flags) { + pub fn set_flags(&mut self, flags: X509VerifyFlags) { unsafe { - ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits()); + cvt(ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits())).unwrap(); } } - /// Clear flags. - /// - /// Useful to clear out default flags, such as `X509Flags::TRUSTED_FIRST` when the fips feature is off. - /// - /// 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 + /// Clear verification flags. #[corresponds(X509_VERIFY_PARAM_clear_flags)] - pub fn clear_flags(&mut self, flags: X509Flags) { + pub fn clear_flags(&mut self, flags: X509VerifyFlags) { unsafe { - ffi::X509_VERIFY_PARAM_clear_flags(self.as_ptr(), flags.bits()); + cvt(ffi::X509_VERIFY_PARAM_clear_flags(self.as_ptr(), flags.bits())).unwrap(); } } @@ -77,19 +102,43 @@ impl X509VerifyParamRef { } } + /// 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. #[corresponds(X509_VERIFY_PARAM_set1_host)] pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { unsafe { + // len == 0 means "run strlen" :( + let raw_host = if host.is_empty() { "\0" } else { host }; cvt(ffi::X509_VERIFY_PARAM_set1_host( self.as_ptr(), - host.as_ptr() as *const _, + raw_host.as_ptr() as *const _, host.len(), )) .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. #[corresponds(X509_VERIFY_PARAM_set1_ip)] pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> { @@ -113,4 +162,16 @@ impl X509VerifyParamRef { .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) } + } } From ade1b678fca06d900505349f343bb9a25c46a295 Mon Sep 17 00:00:00 2001 From: Kornel Date: Tue, 26 Nov 2024 15:30:49 +0000 Subject: [PATCH 3/3] Sync X509StoreBuilder with openssl --- boring/src/aes.rs | 2 +- boring/src/ssl/test/custom_verify.rs | 4 ++-- boring/src/x509/store.rs | 35 +++++++++++++++++++++------- boring/src/x509/verify.rs | 14 ++++++++--- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/boring/src/aes.rs b/boring/src/aes.rs index 376d356a..8a47cbaf 100644 --- a/boring/src/aes.rs +++ b/boring/src/aes.rs @@ -39,9 +39,9 @@ //! use crate::ffi; use libc::{c_int, c_uint, size_t}; +use openssl_macros::corresponds; use std::mem::MaybeUninit; use std::ptr; -use openssl_macros::corresponds; /// Provides Error handling for parsing keys. #[derive(Debug)] diff --git a/boring/src/ssl/test/custom_verify.rs b/boring/src/ssl/test/custom_verify.rs index e7feb56c..64e8f89b 100644 --- a/boring/src/ssl/test/custom_verify.rs +++ b/boring/src/ssl/test/custom_verify.rs @@ -64,7 +64,7 @@ fn untrusted_with_set_cert() { let cert = ssl.peer_certificate().unwrap(); let cert_chain = ssl.peer_cert_chain().unwrap(); - assert_eq!(store.objects().len(), 0); + assert_eq!(store.objects_len(), 0); X509StoreContext::new() .unwrap() @@ -94,7 +94,7 @@ fn trusted_with_set_cert() { let cert = ssl.peer_certificate().unwrap(); let cert_chain = ssl.peer_cert_chain().unwrap(); - assert_eq!(store.objects().len(), 1); + assert_eq!(store.objects_len(), 1); X509StoreContext::new() .unwrap() diff --git a/boring/src/x509/store.rs b/boring/src/x509/store.rs index 2c55d705..068c759c 100644 --- a/boring/src/x509/store.rs +++ b/boring/src/x509/store.rs @@ -43,12 +43,12 @@ use crate::error::ErrorStack; use crate::ffi; use crate::stack::StackRef; -use crate::x509::verify::{X509Flags, X509VerifyParamRef}; +use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef}; use crate::x509::{X509Object, X509}; use crate::{cvt, cvt_p}; use foreign_types::{ForeignType, ForeignTypeRef}; -use std::mem; use openssl_macros::corresponds; +use std::mem; foreign_type_and_impl_send_sync! { type CType = ffi::X509_STORE; @@ -96,15 +96,11 @@ impl X509StoreBuilderRef { unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) } } - /// Sets verify flags. - /// - /// This corresponds to [`X509_STORE_set_flags`]. - /// - /// [`X509_STORE_set_flags`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_set_flags.html + /// Sets certificate chain validation related flags. #[corresponds(X509_STORE_set_flags)] - pub fn set_flags(&mut self, flags: X509Flags) { + pub fn set_flags(&mut self, flags: X509VerifyFlags) { unsafe { - ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits()); + cvt(ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits())).unwrap(); } } @@ -116,6 +112,12 @@ impl X509StoreBuilderRef { pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef { 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! { @@ -127,9 +129,24 @@ foreign_type_and_impl_send_sync! { } impl X509StoreRef { + /// **Warning: this method is unsound** + /// /// 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 { 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() + } } diff --git a/boring/src/x509/verify.rs b/boring/src/x509/verify.rs index 1968e4db..7546442d 100644 --- a/boring/src/x509/verify.rs +++ b/boring/src/x509/verify.rs @@ -1,8 +1,8 @@ use crate::ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_int, c_uint, c_ulong, time_t}; -use std::net::IpAddr; use openssl_macros::corresponds; +use std::net::IpAddr; use crate::error::ErrorStack; use crate::{cvt, cvt_p}; @@ -81,7 +81,11 @@ impl X509VerifyParamRef { #[corresponds(X509_VERIFY_PARAM_set_flags)] pub fn set_flags(&mut self, flags: X509VerifyFlags) { unsafe { - cvt(ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits())).unwrap(); + cvt(ffi::X509_VERIFY_PARAM_set_flags( + self.as_ptr(), + flags.bits(), + )) + .unwrap(); } } @@ -89,7 +93,11 @@ impl X509VerifyParamRef { #[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(); + cvt(ffi::X509_VERIFY_PARAM_clear_flags( + self.as_ptr(), + flags.bits(), + )) + .unwrap(); } }