diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c19bd1e..f475d76b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: name: rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install Rust run: rustup update stable && rustup default stable - name: Check formatting @@ -27,7 +27,7 @@ jobs: name: clippy runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' - name: Install Rust @@ -184,7 +184,7 @@ jobs: extra_test_args: --workspace --exclude tokio-boring --exclude hyper-boring steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' - name: Install Rust (rustup) @@ -238,7 +238,7 @@ jobs: name: Test FIPS integration runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' - name: Install Rust (rustup) @@ -250,7 +250,6 @@ jobs: version: "12.0.0" directory: ${{ runner.temp }}/llvm - name: Install golang - uses: actions/checkout@v4 uses: actions/setup-go@v5 with: go-version: '>=1.22.0' @@ -280,7 +279,7 @@ jobs: include: - target: x86_64-unknown-linux-gnu steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' - name: Install Rust (rustup) @@ -298,18 +297,22 @@ jobs: cross-build-fips: name: Cross build from macOS to Linux (FIPS) - runs-on: macos-latest + runs-on: macos-13 # Need an Intel (x86_64) runner for Clang 12.0.0 strategy: matrix: include: - target: x86_64-unknown-linux-gnu steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' - name: Install Rust (rustup) run: rustup update stable --no-self-update && rustup default stable && rustup target add ${{ matrix.target }} shell: bash + - name: Install golang + uses: actions/setup-go@v5 + with: + go-version: '>=1.22.0' - name: Install Clang-12 uses: KyleMayes/install-llvm-action@v1 with: @@ -335,7 +338,7 @@ jobs: name: Test features runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' - name: Install Rust (rustup) diff --git a/boring/src/aes.rs b/boring/src/aes.rs index 12288763..2bf95466 100644 --- a/boring/src/aes.rs +++ b/boring/src/aes.rs @@ -58,7 +58,7 @@ impl AesKey { #[allow(deprecated)] // https://github.com/rust-lang/rust/issues/63566 pub fn new_encrypt(key: &[u8]) -> Result { unsafe { - assert!(key.len() <= c_int::max_value() as usize / 8); + assert!(key.len() <= c_int::MAX as usize / 8); let mut aes_key = MaybeUninit::uninit(); let r = ffi::AES_set_encrypt_key( @@ -82,7 +82,7 @@ impl AesKey { #[allow(deprecated)] // https://github.com/rust-lang/rust/issues/63566 pub fn new_decrypt(key: &[u8]) -> Result { unsafe { - assert!(key.len() <= c_int::max_value() as usize / 8); + assert!(key.len() <= c_int::MAX as usize / 8); let mut aes_key = MaybeUninit::uninit(); let r = ffi::AES_set_decrypt_key( diff --git a/boring/src/base64.rs b/boring/src/base64.rs index 2e9ef17d..9b556384 100644 --- a/boring/src/base64.rs +++ b/boring/src/base64.rs @@ -14,7 +14,7 @@ use libc::c_int; /// /// [`EVP_EncodeBlock`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DecodeBlock.html pub fn encode_block(src: &[u8]) -> String { - assert!(src.len() <= c_int::max_value() as usize); + assert!(src.len() <= c_int::MAX as usize); let src_len = src.len(); let len = encoded_len(src_len).unwrap(); @@ -48,7 +48,7 @@ pub fn decode_block(src: &str) -> Result, ErrorStack> { return Ok(vec![]); } - assert!(src.len() <= c_int::max_value() as usize); + assert!(src.len() <= c_int::MAX as usize); let src_len = src.len(); let len = decoded_len(src_len).unwrap(); diff --git a/boring/src/bio.rs b/boring/src/bio.rs index 55870ded..b6d52e09 100644 --- a/boring/src/bio.rs +++ b/boring/src/bio.rs @@ -26,7 +26,7 @@ impl<'a> MemBioSlice<'a> { ffi::init(); - assert!(buf.len() <= BufLen::max_value() as usize); + assert!(buf.len() <= BufLen::MAX as usize); let bio = unsafe { cvt_p(BIO_new_mem_buf( buf.as_ptr() as *const _, diff --git a/boring/src/bn.rs b/boring/src/bn.rs index 3990048d..b5b02077 100644 --- a/boring/src/bn.rs +++ b/boring/src/bn.rs @@ -159,7 +159,7 @@ impl BigNumRef { pub fn div_word(&mut self, w: u32) -> Result { unsafe { let r = ffi::BN_div_word(self.as_ptr(), w.into()); - if r == ffi::BN_ULONG::max_value() { + if r == ffi::BN_ULONG::MAX { Err(ErrorStack::get()) } else { Ok(r.into()) @@ -176,7 +176,7 @@ impl BigNumRef { pub fn mod_word(&self, w: u32) -> Result { unsafe { let r = ffi::BN_mod_word(self.as_ptr(), w.into()); - if r == ffi::BN_ULONG::max_value() { + if r == ffi::BN_ULONG::MAX { Err(ErrorStack::get()) } else { Ok(r.into()) @@ -987,7 +987,7 @@ impl BigNum { pub fn from_slice(n: &[u8]) -> Result { unsafe { ffi::init(); - assert!(n.len() <= c_int::max_value() as usize); + assert!(n.len() <= c_int::MAX as usize); cvt_p(ffi::BN_bin2bn( n.as_ptr(), n.len() as size_t, diff --git a/boring/src/ecdsa.rs b/boring/src/ecdsa.rs index 0d333003..782dbf20 100644 --- a/boring/src/ecdsa.rs +++ b/boring/src/ecdsa.rs @@ -35,7 +35,7 @@ impl EcdsaSig { T: HasPrivate, { unsafe { - assert!(data.len() <= c_int::max_value() as usize); + assert!(data.len() <= c_int::MAX as usize); let sig = cvt_p(ffi::ECDSA_do_sign( data.as_ptr(), data.len() as size_t, @@ -94,7 +94,7 @@ impl EcdsaSigRef { T: HasPublic, { unsafe { - assert!(data.len() <= c_int::max_value() as usize); + assert!(data.len() <= c_int::MAX as usize); cvt_n(ffi::ECDSA_do_verify( data.as_ptr(), data.len() as size_t, diff --git a/boring/src/macros.rs b/boring/src/macros.rs index 0dcc5fae..b6cbeb8f 100644 --- a/boring/src/macros.rs +++ b/boring/src/macros.rs @@ -59,7 +59,7 @@ macro_rules! private_key_to_pem { ) -> Result, crate::error::ErrorStack> { unsafe { let bio = crate::bio::MemBio::new()?; - assert!(passphrase.len() <= ::libc::c_int::max_value() as usize); + assert!(passphrase.len() <= ::libc::c_int::MAX as usize); cvt($f(bio.as_ptr(), self.as_ptr(), cipher.as_ptr(), @@ -108,7 +108,7 @@ macro_rules! from_der { pub fn $n(der: &[u8]) -> Result<$t, crate::error::ErrorStack> { unsafe { crate::ffi::init(); - let len = ::std::cmp::min(der.len(), <$len_ty>::max_value() as usize) as $len_ty; + let len = ::std::cmp::min(der.len(), <$len_ty>::MAX as usize) as $len_ty; crate::cvt_p($f(::std::ptr::null_mut(), &mut der.as_ptr(), len)) .map(|p| ::foreign_types::ForeignType::from_ptr(p)) } diff --git a/boring/src/nid.rs b/boring/src/nid.rs index 8f9b400a..a3b0f11a 100644 --- a/boring/src/nid.rs +++ b/boring/src/nid.rs @@ -1050,6 +1050,10 @@ impl Nid { pub const AES_128_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_128_cbc_hmac_sha1); pub const AES_192_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_192_cbc_hmac_sha1); pub const AES_256_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_256_cbc_hmac_sha1); + pub const AUTH_RSA: Nid = Nid(ffi::NID_auth_rsa); + pub const AUTH_ECDSA: Nid = Nid(ffi::NID_auth_ecdsa); + pub const AUTH_PSK: Nid = Nid(ffi::NID_auth_psk); + pub const AUTH_ANY: Nid = Nid(ffi::NID_auth_any); } #[cfg(test)] diff --git a/boring/src/pkcs5.rs b/boring/src/pkcs5.rs index 8503d0b3..91684661 100644 --- a/boring/src/pkcs5.rs +++ b/boring/src/pkcs5.rs @@ -32,7 +32,7 @@ pub fn bytes_to_key( count: u32, ) -> Result { unsafe { - assert!(data.len() <= c_int::max_value() as usize); + assert!(data.len() <= c_int::MAX as usize); let salt_ptr = match salt { Some(salt) => { pub const PKCS5_SALT_LEN: c_int = 8; @@ -90,9 +90,9 @@ pub fn pbkdf2_hmac( key: &mut [u8], ) -> Result<(), ErrorStack> { unsafe { - assert!(pass.len() <= c_int::max_value() as usize); - assert!(salt.len() <= c_int::max_value() as usize); - assert!(key.len() <= c_int::max_value() as usize); + assert!(pass.len() <= c_int::MAX as usize); + assert!(salt.len() <= c_int::MAX as usize); + assert!(key.len() <= c_int::MAX as usize); ffi::init(); cvt(ffi::PKCS5_PBKDF2_HMAC( diff --git a/boring/src/pkey.rs b/boring/src/pkey.rs index e1c31855..b8a157f6 100644 --- a/boring/src/pkey.rs +++ b/boring/src/pkey.rs @@ -411,7 +411,7 @@ impl PKey { pub fn private_key_from_pkcs8(der: &[u8]) -> Result, ErrorStack> { unsafe { ffi::init(); - let len = der.len().min(c_long::max_value() as usize) as c_long; + let len = der.len().min(c_long::MAX as usize) as c_long; let p8inf = cvt_p(ffi::d2i_PKCS8_PRIV_KEY_INFO( ptr::null_mut(), &mut der.as_ptr(), diff --git a/boring/src/rand.rs b/boring/src/rand.rs index c551b2f9..e5b843e0 100644 --- a/boring/src/rand.rs +++ b/boring/src/rand.rs @@ -35,7 +35,7 @@ use crate::error::ErrorStack; pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> { unsafe { ffi::init(); - assert!(buf.len() <= c_int::max_value() as usize); + assert!(buf.len() <= c_int::MAX as usize); cvt(ffi::RAND_bytes(buf.as_mut_ptr(), buf.len())).map(|_| ()) } } diff --git a/boring/src/rsa.rs b/boring/src/rsa.rs index c17b36a3..5b85e9e1 100644 --- a/boring/src/rsa.rs +++ b/boring/src/rsa.rs @@ -151,7 +151,7 @@ where to: &mut [u8], padding: Padding, ) -> Result { - assert!(from.len() <= i32::max_value() as usize); + assert!(from.len() <= i32::MAX as usize); assert!(to.len() >= self.size() as usize); unsafe { @@ -178,7 +178,7 @@ where to: &mut [u8], padding: Padding, ) -> Result { - assert!(from.len() <= i32::max_value() as usize); + assert!(from.len() <= i32::MAX as usize); assert!(to.len() >= self.size() as usize); unsafe { @@ -378,7 +378,7 @@ where to: &mut [u8], padding: Padding, ) -> Result { - assert!(from.len() <= i32::max_value() as usize); + assert!(from.len() <= i32::MAX as usize); assert!(to.len() >= self.size() as usize); unsafe { @@ -404,7 +404,7 @@ where to: &mut [u8], padding: Padding, ) -> Result { - assert!(from.len() <= i32::max_value() as usize); + assert!(from.len() <= i32::MAX as usize); assert!(to.len() >= self.size() as usize); unsafe { diff --git a/boring/src/ssl/bio.rs b/boring/src/ssl/bio.rs index b88fdaff..04f43558 100644 --- a/boring/src/ssl/bio.rs +++ b/boring/src/ssl/bio.rs @@ -84,7 +84,7 @@ pub unsafe extern "C" fn take_stream(bio: *mut BIO) -> S { } pub unsafe fn set_dtls_mtu_size(bio: *mut BIO, mtu_size: usize) { - if mtu_size as u64 > c_long::max_value() as u64 { + if mtu_size as u64 > c_long::MAX as u64 { panic!( "Given MTU size {} can't be represented in a positive `c_long` range", mtu_size diff --git a/boring/src/ssl/mod.rs b/boring/src/ssl/mod.rs index aa57bff0..037c0f29 100644 --- a/boring/src/ssl/mod.rs +++ b/boring/src/ssl/mod.rs @@ -669,6 +669,12 @@ impl SslSignatureAlgorithm { pub const ED25519: SslSignatureAlgorithm = SslSignatureAlgorithm(ffi::SSL_SIGN_ED25519 as _); } +impl From for SslSignatureAlgorithm { + fn from(value: u16) -> Self { + Self(value) + } +} + /// A TLS Curve. #[repr(transparent)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -1060,16 +1066,14 @@ impl SslContextBuilder { } } - /// Sets the mode used by the context, returning the previous mode. + /// Sets the mode used by the context, returning the new bit-mask after adding mode. /// /// This corresponds to [`SSL_CTX_set_mode`]. /// - /// [`SSL_CTX_set_mode`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_mode.html + /// [`SSL_CTX_set_mode`]: https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_mode.html pub fn set_mode(&mut self, mode: SslMode) -> SslMode { - unsafe { - let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits()); - SslMode::from_bits_retain(bits) - } + let bits = unsafe { ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits()) }; + SslMode::from_bits_retain(bits) } /// Sets the parameters to be used during ephemeral Diffie-Hellman key exchange. @@ -1170,7 +1174,7 @@ impl SslContextBuilder { /// [`SSL_CTX_set_session_id_context`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_session_id_context.html pub fn set_session_id_context(&mut self, sid_ctx: &[u8]) -> Result<(), ErrorStack> { unsafe { - assert!(sid_ctx.len() <= c_uint::max_value() as usize); + assert!(sid_ctx.len() <= c_uint::MAX as usize); cvt(ffi::SSL_CTX_set_session_id_context( self.as_ptr(), sid_ctx.as_ptr(), @@ -1366,12 +1370,12 @@ impl SslContextBuilder { /// Sets the minimum supported protocol version. /// - /// A value of `None` will enable protocol versions down the the lowest version supported by - /// OpenSSL. + /// If version is `None`, the default minimum version is used. For BoringSSL this defaults to + /// TLS 1.0. /// /// This corresponds to [`SSL_CTX_set_min_proto_version`]. /// - /// [`SSL_CTX_set_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html + /// [`SSL_CTX_set_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_min_proto_version.html pub fn set_min_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_min_proto_version( @@ -1384,12 +1388,11 @@ impl SslContextBuilder { /// Sets the maximum supported protocol version. /// - /// A value of `None` will enable protocol versions down the the highest version supported by - /// OpenSSL. + /// If version is `None`, the default maximum version is used. For BoringSSL this is TLS 1.3. /// /// This corresponds to [`SSL_CTX_set_max_proto_version`]. /// - /// [`SSL_CTX_set_max_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html + /// [`SSL_CTX_set_max_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_max_proto_version.html pub fn set_max_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_max_proto_version( @@ -1402,12 +1405,9 @@ impl SslContextBuilder { /// Gets the minimum supported protocol version. /// - /// A value of `None` indicates that all versions down the the lowest version supported by - /// OpenSSL are enabled. - /// /// This corresponds to [`SSL_CTX_get_min_proto_version`]. /// - /// [`SSL_CTX_get_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html + /// [`SSL_CTX_get_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_get_min_proto_version.html pub fn min_proto_version(&mut self) -> Option { unsafe { let r = ffi::SSL_CTX_get_min_proto_version(self.as_ptr()); @@ -1421,12 +1421,9 @@ impl SslContextBuilder { /// Gets the maximum supported protocol version. /// - /// A value of `None` indicates that all versions down the the highest version supported by - /// OpenSSL are enabled. - /// /// This corresponds to [`SSL_CTX_get_max_proto_version`]. /// - /// [`SSL_CTX_get_max_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html + /// [`SSL_CTX_get_max_proto_version`]: https://www.openssl.org/docs/man3.1/man3/SSL_CTX_get_max_proto_version.html pub fn max_proto_version(&mut self) -> Option { unsafe { let r = ffi::SSL_CTX_get_max_proto_version(self.as_ptr()); @@ -1452,7 +1449,7 @@ impl SslContextBuilder { unsafe { #[cfg_attr(not(feature = "fips"), allow(clippy::unnecessary_cast))] { - assert!(protocols.len() <= ProtosLen::max_value() as usize); + assert!(protocols.len() <= ProtosLen::MAX as usize); } let r = ffi::SSL_CTX_set_alpn_protos( self.as_ptr(), @@ -2264,11 +2261,29 @@ impl ClientHello<'_> { pub fn random(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.0.random, self.0.random_len) } } + + /// Returns the raw list of ciphers supported by the client in its Client Hello record. + pub fn ciphers(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.0.cipher_suites, self.0.cipher_suites_len) } + } } /// Information about a cipher. pub struct SslCipher(*mut ffi::SSL_CIPHER); +impl SslCipher { + pub fn from_value(value: u16) -> Option { + unsafe { + let ptr = ffi::SSL_get_cipher_by_value(value); + if ptr.is_null() { + None + } else { + Some(Self::from_ptr(ptr as *mut ffi::SSL_CIPHER)) + } + } + } +} + impl Stackable for SslCipher { type StackType = ffi::stack_st_SSL_CIPHER; } @@ -2385,6 +2400,29 @@ impl SslCipherRef { } } + /// Returns one if the cipher uses an AEAD cipher. + /// + /// This corresponds to [`SSL_CIPHER_is_aead`]. + /// + /// [`SSL_CIPHER_is_aead`]: https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_is_aead.html + pub fn cipher_is_aead(&self) -> bool { + unsafe { ffi::SSL_CIPHER_is_aead(self.as_ptr()) != 0 } + } + + /// Returns the NID corresponding to the cipher's authentication type. + /// + /// This corresponds to [`SSL_CIPHER_get_auth_nid`]. + /// + /// [`SSL_CIPHER_get_auth_nid`]: https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_auth_nid.html + pub fn cipher_auth_nid(&self) -> Option { + let n = unsafe { ffi::SSL_CIPHER_get_auth_nid(self.as_ptr()) }; + if n == 0 { + None + } else { + Some(Nid::from_raw(n)) + } + } + /// Returns the NID corresponding to the cipher. /// /// This corresponds to [`SSL_CIPHER_get_cipher_nid`]. @@ -2913,7 +2951,7 @@ impl SslRef { unsafe { #[cfg_attr(not(feature = "fips"), allow(clippy::unnecessary_cast))] { - assert!(protocols.len() <= ProtosLen::max_value() as usize); + assert!(protocols.len() <= ProtosLen::MAX as usize); } let r = ffi::SSL_set_alpn_protos( self.as_ptr(), @@ -2929,6 +2967,18 @@ impl SslRef { } } + /// Returns the stack of available SslCiphers for `SSL`, sorted by preference. + /// + /// This corresponds to [`SSL_get_ciphers`]. + /// + /// [`SSL_get_ciphers`]: https://www.openssl.org/docs/man1.0.2/man3/SSL_get_ciphers.html + pub fn ciphers(&self) -> &StackRef { + unsafe { + let cipher_list = ffi::SSL_get_ciphers(self.as_ptr()); + StackRef::from_ptr(cipher_list) + } + } + /// Returns the current cipher if the session is active. /// /// This corresponds to [`SSL_get_current_cipher`]. @@ -3109,6 +3159,71 @@ impl SslRef { str::from_utf8(version.to_bytes()).unwrap() } + /// Sets the minimum supported protocol version. + /// + /// If version is `None`, the default minimum version is used. For BoringSSL this defaults to + /// TLS 1.0. + /// + /// This corresponds to [`SSL_set_min_proto_version`]. + /// + /// [`SSL_set_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html + pub fn set_min_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_set_min_proto_version( + self.as_ptr(), + version.map_or(0, |v| v.0 as _), + )) + .map(|_| ()) + } + } + + /// Sets the maximum supported protocol version. + /// + /// If version is `None`, the default maximum version is used. For BoringSSL this is TLS 1.3. + /// + /// This corresponds to [`SSL_set_max_proto_version`]. + /// + /// [`SSL_set_max_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_max_proto_version.html + pub fn set_max_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_set_max_proto_version( + self.as_ptr(), + version.map_or(0, |v| v.0 as _), + )) + .map(|_| ()) + } + } + + /// Gets the minimum supported protocol version. + /// + /// This corresponds to [`SSL_get_min_proto_version`]. + /// + /// [`SSL_get_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html + pub fn min_proto_version(&mut self) -> Option { + unsafe { + let r = ffi::SSL_get_min_proto_version(self.as_ptr()); + if r == 0 { + None + } else { + Some(SslVersion(r)) + } + } + } + + /// Gets the maximum supported protocol version. + /// + /// This corresponds to [`SSL_get_max_proto_version`]. + /// + /// [`SSL_get_max_proto_version`]: https://www.openssl.org/docs/man3.1/man3/SSL_get_max_proto_version.html + pub fn max_proto_version(&self) -> Option { + let r = unsafe { ffi::SSL_get_max_proto_version(self.as_ptr()) }; + if r == 0 { + None + } else { + Some(SslVersion(r)) + } + } + /// Returns the protocol selected via Application Layer Protocol Negotiation (ALPN). /// /// The protocol's name is returned is an opaque sequence of bytes. It is up to the client @@ -3437,7 +3552,7 @@ impl SslRef { /// [`SSL_set_tlsext_status_ocsp_resp`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_tlsext_status_type.html pub fn set_ocsp_status(&mut self, response: &[u8]) -> Result<(), ErrorStack> { unsafe { - assert!(response.len() <= c_int::max_value() as usize); + assert!(response.len() <= c_int::MAX as usize); let p = cvt_p(ffi::OPENSSL_malloc(response.len() as _))?; ptr::copy_nonoverlapping(response.as_ptr(), p as *mut u8, response.len()); cvt(ffi::SSL_set_tlsext_status_ocsp_resp( @@ -3601,6 +3716,37 @@ impl SslRef { { unsafe { cvt(ffi::SSL_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } } + + /// Enables all modes set in `mode` in `SSL`. Returns a bitmask representing the resulting + /// enabled modes. + /// + /// This corresponds to [`SSL_set_mode`]. + /// + /// [`SSL_set_mode`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_mode.html + pub fn set_mode(&mut self, mode: SslMode) -> SslMode { + let bits = unsafe { ffi::SSL_set_mode(self.as_ptr(), mode.bits()) }; + SslMode::from_bits_retain(bits) + } + + /// Disables all modes set in `mode` in `SSL`. Returns a bitmask representing the resulting + /// enabled modes. + /// + /// This corresponds to [`SSL_clear_mode`]. + /// + /// [`SSL_clear_mode`]: https://www.openssl.org/docs/man3.1/man3/SSL_clear_mode.html + pub fn clear_mode(&mut self, mode: SslMode) -> SslMode { + let bits = unsafe { ffi::SSL_clear_mode(self.as_ptr(), mode.bits()) }; + SslMode::from_bits_retain(bits) + } + + /// Appends `cert` to the chain associated with the current certificate of `SSL`. + /// + /// This corresponds to [`SSL_add1_chain_cert`]. + /// + /// [`SSL_add1_chain_cert`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_add1_chain_cert.html + pub fn add_chain_cert(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_add1_chain_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) } + } } /// An SSL stream midway through the handshake process. @@ -3787,7 +3933,7 @@ impl SslStream { return Ok(0); } - let len = usize::min(c_int::max_value() as usize, buf.len()) as c_int; + let len = usize::min(c_int::MAX as usize, buf.len()) as c_int; let ret = unsafe { ffi::SSL_read(self.ssl().as_ptr(), buf.as_mut_ptr().cast(), len) }; if ret > 0 { Ok(ret as usize) @@ -3809,7 +3955,7 @@ impl SslStream { return Ok(0); } - let len = usize::min(c_int::max_value() as usize, buf.len()) as c_int; + let len = usize::min(c_int::MAX as usize, buf.len()) as c_int; let ret = unsafe { ffi::SSL_write(self.ssl().as_ptr(), buf.as_ptr().cast(), len) }; if ret > 0 { Ok(ret as usize) diff --git a/boring/src/symm.rs b/boring/src/symm.rs index 55a60999..6e230f0d 100644 --- a/boring/src/symm.rs +++ b/boring/src/symm.rs @@ -323,7 +323,7 @@ impl Crypter { mode, ))?; - assert!(key.len() <= c_int::max_value() as usize); + assert!(key.len() <= c_int::MAX as usize); cvt(ffi::EVP_CIPHER_CTX_set_key_length( crypter.ctx, key.len() as c_uint, @@ -333,7 +333,7 @@ impl Crypter { let iv = match (iv, t.iv_len()) { (Some(iv), Some(len)) => { if iv.len() != len { - assert!(iv.len() <= c_int::max_value() as usize); + assert!(iv.len() <= c_int::MAX as usize); cvt(ffi::EVP_CIPHER_CTX_ctrl( crypter.ctx, ffi::EVP_CTRL_GCM_SET_IVLEN, @@ -374,7 +374,7 @@ impl Crypter { /// When decrypting cipher text using an AEAD cipher, this must be called before `finalize`. pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> { unsafe { - assert!(tag.len() <= c_int::max_value() as usize); + assert!(tag.len() <= c_int::MAX as usize); // NB: this constant is actually more general than just GCM. cvt(ffi::EVP_CIPHER_CTX_ctrl( self.ctx, @@ -392,7 +392,7 @@ impl Crypter { /// to use a value different than the default 12 bytes. pub fn set_tag_len(&mut self, tag_len: usize) -> Result<(), ErrorStack> { unsafe { - assert!(tag_len <= c_int::max_value() as usize); + assert!(tag_len <= c_int::MAX as usize); // NB: this constant is actually more general than just GCM. cvt(ffi::EVP_CIPHER_CTX_ctrl( self.ctx, @@ -410,7 +410,7 @@ impl Crypter { /// CCM mode. pub fn set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack> { unsafe { - assert!(data_len <= c_int::max_value() as usize); + assert!(data_len <= c_int::MAX as usize); let mut len = 0; cvt(ffi::EVP_CipherUpdate( self.ctx, @@ -430,7 +430,7 @@ impl Crypter { /// `update`. pub fn aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack> { unsafe { - assert!(input.len() <= c_int::max_value() as usize); + assert!(input.len() <= c_int::MAX as usize); let mut len = 0; cvt(ffi::EVP_CipherUpdate( self.ctx, @@ -456,7 +456,7 @@ impl Crypter { /// Panics for block ciphers if `output.len() < input.len() + block_size`, /// where `block_size` is the block size of the cipher (see `Cipher::block_size`). /// - /// Panics if `output.len() > c_int::max_value()`. + /// Panics if `output.len() > c_int::MAX`. pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result { unsafe { let block_size = if self.block_size > 1 { @@ -465,7 +465,7 @@ impl Crypter { 0 }; assert!(output.len() >= input.len() + block_size); - assert!(output.len() <= c_int::max_value() as usize); + assert!(output.len() <= c_int::MAX as usize); let mut outl = output.len() as c_int; let inl = input.len() as c_int; @@ -497,7 +497,7 @@ impl Crypter { if self.block_size > 1 { assert!(output.len() >= self.block_size); } - let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int; + let mut outl = cmp::min(output.len(), c_int::MAX as usize) as c_int; cvt(ffi::EVP_CipherFinal_ex( self.ctx, @@ -519,7 +519,7 @@ impl Crypter { /// bytes, for example. pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> { unsafe { - assert!(tag.len() <= c_int::max_value() as usize); + assert!(tag.len() <= c_int::MAX as usize); cvt(ffi::EVP_CIPHER_CTX_ctrl( self.ctx, ffi::EVP_CTRL_GCM_GET_TAG, diff --git a/boring/src/x509/mod.rs b/boring/src/x509/mod.rs index 988428f4..50750d66 100644 --- a/boring/src/x509/mod.rs +++ b/boring/src/x509/mod.rs @@ -592,6 +592,19 @@ impl X509Ref { } } + pub fn check_host(&self, host: &str) -> Result { + unsafe { + cvt_n(ffi::X509_check_host( + self.as_ptr(), + host.as_ptr() as _, + host.len(), + 0, + std::ptr::null_mut(), + )) + .map(|n| n != 0) + } + } + to_pem! { /// Serializes the certificate into a PEM-encoded X509 structure. /// @@ -885,7 +898,7 @@ impl X509NameBuilder { pub fn append_entry_by_text(&mut self, field: &str, value: &str) -> Result<(), ErrorStack> { unsafe { let field = CString::new(field).unwrap(); - assert!(value.len() <= ValueLen::max_value() as usize); + assert!(value.len() <= ValueLen::MAX as usize); cvt(ffi::X509_NAME_add_entry_by_txt( self.0.as_ptr(), field.as_ptr() as *mut _, @@ -912,7 +925,7 @@ impl X509NameBuilder { ) -> Result<(), ErrorStack> { unsafe { let field = CString::new(field).unwrap(); - assert!(value.len() <= ValueLen::max_value() as usize); + assert!(value.len() <= ValueLen::MAX as usize); cvt(ffi::X509_NAME_add_entry_by_txt( self.0.as_ptr(), field.as_ptr() as *mut _, @@ -933,7 +946,7 @@ impl X509NameBuilder { /// [`X509_NAME_add_entry_by_NID`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_NAME_add_entry_by_NID.html pub fn append_entry_by_nid(&mut self, field: Nid, value: &str) -> Result<(), ErrorStack> { unsafe { - assert!(value.len() <= ValueLen::max_value() as usize); + assert!(value.len() <= ValueLen::MAX as usize); cvt(ffi::X509_NAME_add_entry_by_NID( self.0.as_ptr(), field.as_raw(), @@ -959,7 +972,7 @@ impl X509NameBuilder { ty: Asn1Type, ) -> Result<(), ErrorStack> { unsafe { - assert!(value.len() <= ValueLen::max_value() as usize); + assert!(value.len() <= ValueLen::MAX as usize); cvt(ffi::X509_NAME_add_entry_by_NID( self.0.as_ptr(), field.as_raw(),