From 56833dab21112d2c436ec3eb35c8ea91224ae956 Mon Sep 17 00:00:00 2001 From: Kornel Date: Mon, 29 Dec 2025 19:40:59 +0000 Subject: [PATCH] Handle overflows in FFI integer conversions --- boring/src/aes.rs | 6 +-- boring/src/bio.rs | 15 +++---- boring/src/bn.rs | 2 +- boring/src/dsa.rs | 5 ++- boring/src/ec.rs | 3 +- boring/src/hash.rs | 8 ++-- boring/src/lib.rs | 9 ++++ boring/src/macros.rs | 3 +- boring/src/pkcs5.rs | 11 ++--- boring/src/pkey.rs | 3 +- boring/src/rsa.rs | 3 +- boring/src/ssl/bio.rs | 12 +++++- boring/src/ssl/mod.rs | 97 +++++++++++++++++++++--------------------- boring/src/symm.rs | 33 +++++--------- boring/src/x509/mod.rs | 22 +++------- 15 files changed, 112 insertions(+), 120 deletions(-) diff --git a/boring/src/aes.rs b/boring/src/aes.rs index 2a46b6125..e535fa217 100644 --- a/boring/src/aes.rs +++ b/boring/src/aes.rs @@ -38,7 +38,7 @@ //! ``` //! use crate::ffi; -use libc::{c_int, c_uint}; +use libc::c_int; use openssl_macros::corresponds; use std::mem::MaybeUninit; use std::ptr; @@ -64,7 +64,7 @@ impl AesKey { let mut aes_key = MaybeUninit::uninit(); let r = ffi::AES_set_encrypt_key( key.as_ptr(), - key.len() as c_uint * 8, + (key.len() * 8).try_into().map_err(|_| KeyError(()))?, aes_key.as_mut_ptr(), ); if r == 0 { @@ -88,7 +88,7 @@ impl AesKey { let mut aes_key = MaybeUninit::uninit(); let r = ffi::AES_set_decrypt_key( key.as_ptr(), - key.len() as c_uint * 8, + (key.len() * 8).try_into().map_err(|_| KeyError(()))?, aes_key.as_mut_ptr(), ); diff --git a/boring/src/bio.rs b/boring/src/bio.rs index ff1e83e29..bb4aa1a54 100644 --- a/boring/src/bio.rs +++ b/boring/src/bio.rs @@ -1,11 +1,12 @@ -use crate::ffi; -use crate::ffi::BIO_new_mem_buf; use std::marker::PhantomData; use std::ptr; use std::slice; use crate::cvt_p; use crate::error::ErrorStack; +use crate::ffi; +use crate::ffi::BIO_new_mem_buf; +use crate::try_int; pub struct MemBioSlice<'a>(*mut ffi::BIO, PhantomData<&'a [u8]>); @@ -19,15 +20,9 @@ impl Drop for MemBioSlice<'_> { impl<'a> MemBioSlice<'a> { pub fn new(buf: &'a [u8]) -> Result, ErrorStack> { - #[cfg(not(feature = "legacy-compat-deprecated"))] - type BufLen = isize; - #[cfg(feature = "legacy-compat-deprecated")] - type BufLen = libc::c_int; - ffi::init(); - assert!(buf.len() <= BufLen::MAX as usize); - let bio = unsafe { cvt_p(BIO_new_mem_buf(buf.as_ptr().cast(), buf.len() as BufLen))? }; + let bio = unsafe { cvt_p(BIO_new_mem_buf(buf.as_ptr().cast(), try_int(buf.len())?))? }; Ok(MemBioSlice(bio, PhantomData)) } @@ -63,7 +58,7 @@ impl MemBio { unsafe { let mut ptr = ptr::null_mut(); let len = ffi::BIO_get_mem_data(self.0, &mut ptr); - if ptr.is_null() { + if ptr.is_null() || len < 0 { return &[]; } slice::from_raw_parts(ptr.cast_const().cast(), len as usize) diff --git a/boring/src/bn.rs b/boring/src/bn.rs index 659d516e4..545eb3487 100644 --- a/boring/src/bn.rs +++ b/boring/src/bn.rs @@ -390,7 +390,7 @@ impl BigNumRef { unsafe { cvt(ffi::BN_generate_prime_ex( self.as_ptr(), - bits as c_int, + c_int::from(bits), c_int::from(safe), add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()), rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()), diff --git a/boring/src/dsa.rs b/boring/src/dsa.rs index bc6068add..36562699e 100644 --- a/boring/src/dsa.rs +++ b/boring/src/dsa.rs @@ -5,7 +5,6 @@ //! using the private key that can be validated with the public key but not be generated //! without the private key. -use crate::ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::c_uint; use openssl_macros::corresponds; @@ -15,7 +14,9 @@ use std::ptr; use crate::bn::{BigNum, BigNumRef}; use crate::error::ErrorStack; +use crate::ffi; use crate::pkey::{HasParams, HasPrivate, HasPublic, Private, Public}; +use crate::try_int; use crate::{cvt, cvt_p}; generic_foreign_type_and_impl_send_sync! { @@ -195,7 +196,7 @@ impl Dsa { let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); cvt(ffi::DSA_generate_parameters_ex( dsa.0, - bits as c_uint, + c_uint::from(bits), ptr::null(), 0, ptr::null_mut(), diff --git a/boring/src/ec.rs b/boring/src/ec.rs index 745b81fcb..477f6d063 100644 --- a/boring/src/ec.rs +++ b/boring/src/ec.rs @@ -15,7 +15,6 @@ //! [`EcGroup`]: struct.EcGroup.html //! [`Nid`]: ../nid/struct.Nid.html //! [Eliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography -use crate::ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::c_int; use openssl_macros::corresponds; @@ -24,8 +23,10 @@ use std::ptr; use crate::bn::{BigNumContextRef, BigNumRef}; use crate::error::ErrorStack; +use crate::ffi; use crate::nid::Nid; use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public}; +use crate::try_int; use crate::{cvt, cvt_n, cvt_p, init}; /// Compressed or Uncompressed conversion diff --git a/boring/src/hash.rs b/boring/src/hash.rs index 5035edc31..543e401fd 100644 --- a/boring/src/hash.rs +++ b/boring/src/hash.rs @@ -1,6 +1,4 @@ -use crate::ffi; use openssl_macros::corresponds; -use std::convert::TryInto; use std::ffi::c_uint; use std::fmt; use std::io; @@ -9,8 +7,10 @@ use std::ops::{Deref, DerefMut}; use std::ptr; use crate::error::ErrorStack; +use crate::ffi; use crate::ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; use crate::nid::Nid; +use crate::try_int; use crate::{cvt, cvt_p}; #[derive(Copy, Clone, PartialEq, Eq)] @@ -210,7 +210,7 @@ impl Hasher { self.init()?; } unsafe { - let mut len = ffi::EVP_MAX_MD_SIZE.try_into().unwrap(); + let mut len = try_int(ffi::EVP_MAX_MD_SIZE)?; let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize]; cvt(ffi::EVP_DigestFinal_ex( self.ctx, @@ -220,7 +220,7 @@ impl Hasher { self.state = Finalized; Ok(DigestBytes { buf, - len: len as usize, + len: try_int(len)?, }) } } diff --git a/boring/src/lib.rs b/boring/src/lib.rs index a93f9d692..d1d87e595 100644 --- a/boring/src/lib.rs +++ b/boring/src/lib.rs @@ -201,6 +201,15 @@ fn cvt_n(r: c_int) -> Result { } } +fn try_int(from: F) -> Result +where + F: TryInto + Send + Sync + Copy + 'static, + T: Send + Sync + Copy + 'static, +{ + from.try_into() + .map_err(|_| ErrorStack::internal_error_str("int overflow")) +} + unsafe extern "C" fn free_data_box( _parent: *mut c_void, ptr: *mut c_void, diff --git a/boring/src/macros.rs b/boring/src/macros.rs index e2da938aa..f5bffae2f 100644 --- a/boring/src/macros.rs +++ b/boring/src/macros.rs @@ -60,12 +60,11 @@ macro_rules! private_key_to_pem { ) -> Result, crate::error::ErrorStack> { unsafe { let bio = crate::bio::MemBio::new()?; - assert!(passphrase.len() <= ::libc::c_int::MAX as usize); cvt($f(bio.as_ptr(), self.as_ptr(), cipher.as_ptr(), passphrase.as_ptr() as *const _ as *mut _, - passphrase.len() as ::libc::c_int, + try_int(passphrase.len())?, None, ptr::null_mut()))?; Ok(bio.get_buf().to_owned()) diff --git a/boring/src/pkcs5.rs b/boring/src/pkcs5.rs index 1b78c520e..1e1665bc5 100644 --- a/boring/src/pkcs5.rs +++ b/boring/src/pkcs5.rs @@ -1,11 +1,11 @@ use crate::ffi; -use libc::{c_int, c_uint}; +use std::ffi::c_int; use std::ptr; use crate::error::ErrorStack; use crate::hash::MessageDigest; use crate::symm::Cipher; -use crate::{cvt, cvt_nz}; +use crate::{cvt, cvt_nz, try_int}; #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct KeyIvPair { @@ -90,17 +90,14 @@ pub fn pbkdf2_hmac( key: &mut [u8], ) -> Result<(), ErrorStack> { unsafe { - 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( pass.as_ptr().cast(), pass.len(), salt.as_ptr(), salt.len(), - iter as c_uint, + try_int(iter)?, hash.as_ptr(), key.len(), key.as_mut_ptr(), diff --git a/boring/src/pkey.rs b/boring/src/pkey.rs index b141f5bda..0ab9c5288 100644 --- a/boring/src/pkey.rs +++ b/boring/src/pkey.rs @@ -40,7 +40,6 @@ //! println!("{:?}", str::from_utf8(pub_key.as_slice()).unwrap()); //! ``` -use crate::ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_int, c_long}; use openssl_macros::corresponds; @@ -54,7 +53,9 @@ use crate::dh::Dh; use crate::dsa::Dsa; use crate::ec::EcKey; use crate::error::ErrorStack; +use crate::ffi; use crate::rsa::Rsa; +use crate::try_int; use crate::util::{invoke_passwd_cb, CallbackState}; use crate::{cvt, cvt_0i, cvt_p}; diff --git a/boring/src/rsa.rs b/boring/src/rsa.rs index 79dfa6df9..413048cc3 100644 --- a/boring/src/rsa.rs +++ b/boring/src/rsa.rs @@ -23,7 +23,6 @@ //! let mut buf = vec![0; rsa.size() as usize]; //! let encrypted_len = rsa.public_encrypt(data, &mut buf, Padding::PKCS1).unwrap(); //! ``` -use crate::ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::c_int; use openssl_macros::corresponds; @@ -33,7 +32,9 @@ use std::ptr; use crate::bn::{BigNum, BigNumRef}; use crate::error::ErrorStack; +use crate::ffi; use crate::pkey::{HasPrivate, HasPublic, Private, Public}; +use crate::try_int; use crate::{cvt, cvt_n, cvt_p}; pub const EVP_PKEY_OP_SIGN: c_int = 1 << 3; diff --git a/boring/src/ssl/bio.rs b/boring/src/ssl/bio.rs index 82695853f..3bae8a79b 100644 --- a/boring/src/ssl/bio.rs +++ b/boring/src/ssl/bio.rs @@ -101,8 +101,12 @@ unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState { unsafe extern "C" fn bwrite(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int { BIO_clear_retry_flags(bio); + let Ok(len) = usize::try_from(len) else { + return -1; + }; + let state = state::(bio); - let buf = slice::from_raw_parts(buf.cast(), len as usize); + let buf = slice::from_raw_parts(buf.cast(), len); match catch_unwind(AssertUnwindSafe(|| state.stream.write(buf))) { Ok(Ok(len)) => len as c_int, @@ -123,8 +127,12 @@ unsafe extern "C" fn bwrite(bio: *mut BIO, buf: *const c_char, len: c_ unsafe extern "C" fn bread(bio: *mut BIO, buf: *mut c_char, len: c_int) -> c_int { BIO_clear_retry_flags(bio); + let Ok(len) = usize::try_from(len) else { + return -1; + }; + let state = state::(bio); - let buf = slice::from_raw_parts_mut(buf.cast(), len as usize); + let buf = slice::from_raw_parts_mut(buf.cast(), len); match catch_unwind(AssertUnwindSafe(|| state.stream.read(buf))) { Ok(Ok(len)) => len as c_int, diff --git a/boring/src/ssl/mod.rs b/boring/src/ssl/mod.rs index ff228ba9b..802e09390 100644 --- a/boring/src/ssl/mod.rs +++ b/boring/src/ssl/mod.rs @@ -92,6 +92,7 @@ use crate::ssl::callbacks::*; use crate::ssl::error::InnerError; use crate::stack::{Stack, StackRef, Stackable}; use crate::symm::CipherCtxRef; +use crate::try_int; use crate::x509::store::{X509Store, X509StoreBuilder, X509StoreBuilderRef, X509StoreRef}; use crate::x509::verify::X509VerifyParamRef; use crate::x509::{ @@ -783,9 +784,9 @@ pub fn select_next_proto<'a>(server: &'a [u8], client: &'a [u8]) -> Option<&'a [ &mut out, &mut outlen, server.as_ptr(), - server.len() as c_uint, + try_int(server.len()).ok()?, client.as_ptr(), - client.len() as c_uint, + try_int(client.len()).ok()?, ); if r == ffi::OPENSSL_NPN_NEGOTIATED { @@ -1018,7 +1019,7 @@ impl SslContextBuilder { self.ctx.check_x509(); unsafe { - ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits() as c_int, None); + ffi::SSL_CTX_set_verify(self.as_ptr(), c_int::from(mode.bits()), None); } } @@ -1047,7 +1048,11 @@ impl SslContextBuilder { unsafe { self.replace_ex_data(SslContext::cached_ex_index::(), callback); - ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits() as c_int, Some(raw_verify::)); + ffi::SSL_CTX_set_verify( + self.as_ptr(), + c_int::from(mode.bits()), + Some(raw_verify::), + ); } } @@ -1074,7 +1079,7 @@ impl SslContextBuilder { self.replace_ex_data(SslContext::cached_ex_index::(), callback); ffi::SSL_CTX_set_custom_verify( self.as_ptr(), - mode.bits() as c_int, + c_int::from(mode.bits()), Some(raw_custom_verify::), ); } @@ -1175,11 +1180,10 @@ impl SslContextBuilder { self.ctx.check_x509(); unsafe { - cvt( - ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), cert_store.into_ptr()) as c_int, - )?; - - Ok(()) + cvt(ffi::SSL_CTX_set0_verify_cert_store( + self.as_ptr(), + cert_store.into_ptr(), + )) } } @@ -1241,13 +1245,13 @@ impl SslContextBuilder { /// Sets the parameters to be used during ephemeral Diffie-Hellman key exchange. #[corresponds(SSL_CTX_set_tmp_dh)] pub fn set_tmp_dh(&mut self, dh: &DhRef) -> Result<(), ErrorStack> { - unsafe { cvt(ffi::SSL_CTX_set_tmp_dh(self.as_ptr(), dh.as_ptr()) as c_int) } + unsafe { cvt(ffi::SSL_CTX_set_tmp_dh(self.as_ptr(), dh.as_ptr())) } } /// Sets the parameters to be used during ephemeral elliptic curve Diffie-Hellman key exchange. #[corresponds(SSL_CTX_set_tmp_ecdh)] pub fn set_tmp_ecdh(&mut self, key: &EcKeyRef) -> Result<(), ErrorStack> { - unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int) } + unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr())) } } /// Use the default locations of trusted certificates for verification. @@ -1383,8 +1387,10 @@ impl SslContextBuilder { self.ctx.check_x509(); unsafe { - cvt(ffi::SSL_CTX_add_extra_chain_cert(self.as_ptr(), cert.into_ptr()) as c_int)?; - Ok(()) + cvt(ffi::SSL_CTX_add_extra_chain_cert( + self.as_ptr(), + cert.into_ptr(), + )) } } @@ -1558,17 +1564,10 @@ impl SslContextBuilder { #[corresponds(SSL_CTX_set_alpn_protos)] pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> { unsafe { - #[cfg_attr( - not(feature = "legacy-compat-deprecated"), - allow(clippy::unnecessary_cast) - )] - { - assert!(protocols.len() <= ProtosLen::MAX as usize); - } let r = ffi::SSL_CTX_set_alpn_protos( self.as_ptr(), protocols.as_ptr(), - protocols.len() as ProtosLen, + try_int(protocols.len())?, ); // fun fact, SSL_CTX_set_alpn_protos has a reversed return code D: if r == 0 { @@ -1757,10 +1756,10 @@ impl SslContextBuilder { { unsafe { self.replace_ex_data(SslContext::cached_ex_index::(), callback); - cvt( - ffi::SSL_CTX_set_tlsext_status_cb(self.as_ptr(), Some(raw_tlsext_status::)) - as c_int, - ) + cvt(ffi::SSL_CTX_set_tlsext_status_cb( + self.as_ptr(), + Some(raw_tlsext_status::), + )) } } @@ -1938,7 +1937,12 @@ impl SslContextBuilder { #[corresponds(SSL_CTX_set1_sigalgs_list)] pub fn set_sigalgs_list(&mut self, sigalgs: &str) -> Result<(), ErrorStack> { let sigalgs = CString::new(sigalgs).map_err(ErrorStack::internal_error)?; - unsafe { cvt(ffi::SSL_CTX_set1_sigalgs_list(self.as_ptr(), sigalgs.as_ptr()) as c_int) } + unsafe { + cvt(ffi::SSL_CTX_set1_sigalgs_list( + self.as_ptr(), + sigalgs.as_ptr(), + )) + } } /// Set's whether the context should enable GREASE. @@ -2362,11 +2366,6 @@ impl SslContextRef { #[derive(Debug)] pub struct GetSessionPendingError; -#[cfg(not(feature = "legacy-compat-deprecated"))] -type ProtosLen = usize; -#[cfg(feature = "legacy-compat-deprecated")] -type ProtosLen = libc::c_uint; - /// Information about the state of a cipher. pub struct CipherBits { /// The number of secret bits used for the cipher. @@ -2941,7 +2940,7 @@ impl SslRef { pub fn set_verify(&mut self, mode: SslVerifyMode) { self.ssl_context().check_x509(); - unsafe { ffi::SSL_set_verify(self.as_ptr(), mode.bits() as c_int, None) } + unsafe { ffi::SSL_set_verify(self.as_ptr(), c_int::from(mode.bits()), None) } } /// Sets the certificate verification depth. @@ -2994,7 +2993,7 @@ impl SslRef { self.replace_ex_data(Ssl::cached_ex_index(), Arc::new(callback)); ffi::SSL_set_verify( self.as_ptr(), - mode.bits() as c_int, + c_int::from(mode.bits()), Some(ssl_raw_verify::), ); } @@ -3006,8 +3005,10 @@ impl SslRef { self.ssl_context().check_x509(); unsafe { - cvt(ffi::SSL_set0_verify_cert_store(self.as_ptr(), cert_store.into_ptr()) as c_int)?; - Ok(()) + cvt(ffi::SSL_set0_verify_cert_store( + self.as_ptr(), + cert_store.into_ptr(), + )) } } @@ -3028,7 +3029,7 @@ impl SslRef { self.replace_ex_data(Ssl::cached_ex_index(), Arc::new(callback)); ffi::SSL_set_custom_verify( self.as_ptr(), - mode.bits() as c_int, + c_int::from(mode.bits()), Some(ssl_raw_custom_verify::), ); } @@ -3039,7 +3040,7 @@ impl SslRef { /// [`SslContextBuilder::set_tmp_dh`]: struct.SslContextBuilder.html#method.set_tmp_dh #[corresponds(SSL_set_tmp_dh)] pub fn set_tmp_dh(&mut self, dh: &DhRef) -> Result<(), ErrorStack> { - unsafe { cvt(ffi::SSL_set_tmp_dh(self.as_ptr(), dh.as_ptr()) as c_int) } + unsafe { cvt(ffi::SSL_set_tmp_dh(self.as_ptr(), dh.as_ptr())) } } /// Like [`SslContextBuilder::set_tmp_ecdh`]. @@ -3047,7 +3048,7 @@ impl SslRef { /// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh #[corresponds(SSL_set_tmp_ecdh)] pub fn set_tmp_ecdh(&mut self, key: &EcKeyRef) -> Result<(), ErrorStack> { - unsafe { cvt(ffi::SSL_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int) } + unsafe { cvt(ffi::SSL_set_tmp_ecdh(self.as_ptr(), key.as_ptr())) } } /// Configures whether ClientHello extensions should be permuted. @@ -3062,17 +3063,10 @@ impl SslRef { #[corresponds(SSL_set_alpn_protos)] pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> { unsafe { - #[cfg_attr( - not(feature = "legacy-compat-deprecated"), - allow(clippy::unnecessary_cast) - )] - { - assert!(protocols.len() <= ProtosLen::MAX as usize); - } let r = ffi::SSL_set_alpn_protos( self.as_ptr(), protocols.as_ptr(), - protocols.len() as ProtosLen, + try_int(protocols.len())?, ); // fun fact, SSL_set_alpn_protos has a reversed return code D: if r == 0 { @@ -3544,7 +3538,12 @@ impl SslRef { /// Sets the status response a client wishes the server to reply with. #[corresponds(SSL_set_tlsext_status_type)] pub fn set_status_type(&mut self, type_: StatusType) -> Result<(), ErrorStack> { - unsafe { cvt(ffi::SSL_set_tlsext_status_type(self.as_ptr(), type_.as_raw()) as c_int) } + unsafe { + cvt(ffi::SSL_set_tlsext_status_type( + self.as_ptr(), + type_.as_raw(), + )) + } } /// Returns the server's OCSP response, if present. @@ -3673,7 +3672,7 @@ impl SslRef { /// Sets the MTU used for DTLS connections. #[corresponds(SSL_set_mtu)] pub fn set_mtu(&mut self, mtu: u32) -> Result<(), ErrorStack> { - unsafe { cvt(ffi::SSL_set_mtu(self.as_ptr(), mtu as c_uint) as c_int) } + unsafe { cvt(ffi::SSL_set_mtu(self.as_ptr(), mtu as c_uint)) } } /// Sets the certificate. diff --git a/boring/src/symm.rs b/boring/src/symm.rs index 419468689..1604b70bd 100644 --- a/boring/src/symm.rs +++ b/boring/src/symm.rs @@ -54,14 +54,14 @@ use crate::ffi; use foreign_types::ForeignTypeRef; -use libc::{c_int, c_uint}; use openssl_macros::corresponds; use std::cmp; +use std::ffi::c_int; use std::ptr; use crate::error::ErrorStack; use crate::nid::Nid; -use crate::{cvt, cvt_p}; +use crate::{cvt, cvt_p, try_int}; #[derive(Copy, Clone)] pub enum Mode { @@ -419,20 +419,18 @@ impl Crypter { mode, ))?; - assert!(key.len() <= c_int::MAX as usize); cvt(ffi::EVP_CIPHER_CTX_set_key_length( crypter.ctx, - key.len() as c_uint, + try_int(key.len())?, ))?; let iv = match (iv, t.iv_len()) { (Some(iv), Some(len)) => { if iv.len() != len { - assert!(iv.len() <= c_int::MAX as usize); cvt(ffi::EVP_CIPHER_CTX_ctrl( crypter.ctx, ffi::EVP_CTRL_GCM_SET_IVLEN, - iv.len() as c_int, + try_int(iv.len())?, ptr::null_mut(), ))?; } @@ -469,12 +467,11 @@ 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 as usize); // NB: this constant is actually more general than just GCM. cvt(ffi::EVP_CIPHER_CTX_ctrl( self.ctx, ffi::EVP_CTRL_GCM_SET_TAG, - tag.len() as c_int, + try_int(tag.len())?, tag.as_ptr().cast_mut().cast(), )) } @@ -486,12 +483,11 @@ 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 as usize); // NB: this constant is actually more general than just GCM. cvt(ffi::EVP_CIPHER_CTX_ctrl( self.ctx, ffi::EVP_CTRL_GCM_SET_TAG, - tag_len as c_int, + try_int(tag_len)?, ptr::null_mut(), )) } @@ -503,14 +499,13 @@ impl Crypter { /// CCM mode. pub fn set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack> { unsafe { - assert!(data_len <= c_int::MAX as usize); let mut len = 0; cvt(ffi::EVP_CipherUpdate( self.ctx, ptr::null_mut(), &mut len, ptr::null_mut(), - data_len as c_int, + try_int(data_len)?, )) } } @@ -522,14 +517,13 @@ impl Crypter { /// `update`. pub fn aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack> { unsafe { - assert!(input.len() <= c_int::MAX as usize); let mut len = 0; cvt(ffi::EVP_CipherUpdate( self.ctx, ptr::null_mut(), &mut len, input.as_ptr(), - input.len() as c_int, + try_int(input.len())?, )) } } @@ -546,8 +540,6 @@ 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`. pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result { unsafe { let block_size = if self.block_size > 1 { @@ -556,16 +548,14 @@ impl Crypter { 0 }; assert!(output.len() >= input.len() + block_size); - assert!(output.len() <= c_int::MAX as usize); - let mut outl = output.len() as c_int; - let inl = input.len() as c_int; + let mut outl = try_int(output.len())?; cvt(ffi::EVP_CipherUpdate( self.ctx, output.as_mut_ptr(), &mut outl, input.as_ptr(), - inl, + try_int(input.len())?, ))?; Ok(outl as usize) @@ -610,11 +600,10 @@ impl Crypter { /// bytes, for example. pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> { unsafe { - assert!(tag.len() <= c_int::MAX as usize); cvt(ffi::EVP_CIPHER_CTX_ctrl( self.ctx, ffi::EVP_CTRL_GCM_GET_TAG, - tag.len() as c_int, + try_int(tag.len())?, tag.as_mut_ptr().cast(), )) } diff --git a/boring/src/x509/mod.rs b/boring/src/x509/mod.rs index 49372e26f..d10871178 100644 --- a/boring/src/x509/mod.rs +++ b/boring/src/x509/mod.rs @@ -36,6 +36,7 @@ use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public}; use crate::ssl::SslRef; use crate::stack::{Stack, StackRef, Stackable}; use crate::string::OpensslString; +use crate::try_int; use crate::util::ForeignTypeRefExt; use crate::x509::verify::{X509VerifyParam, X509VerifyParamRef}; use crate::{cvt, cvt_n, cvt_p}; @@ -610,14 +611,14 @@ impl X509Ref { buf: [0; ffi::EVP_MAX_MD_SIZE as usize], len: ffi::EVP_MAX_MD_SIZE as usize, }; - let mut len = ffi::EVP_MAX_MD_SIZE.try_into().unwrap(); + let mut len = try_int(ffi::EVP_MAX_MD_SIZE)?; cvt(ffi::X509_digest( self.as_ptr(), hash_type.as_ptr(), digest.buf.as_mut_ptr(), &mut len, ))?; - digest.len = len as usize; + digest.len = try_int(len)?; Ok(digest) } @@ -1015,13 +1016,12 @@ impl X509NameBuilder { pub fn append_entry_by_text(&mut self, field: &str, value: &str) -> Result<(), ErrorStack> { unsafe { let field = CString::new(field).map_err(ErrorStack::internal_error)?; - assert!(value.len() <= ValueLen::MAX as usize); cvt(ffi::X509_NAME_add_entry_by_txt( self.0.as_ptr(), field.as_ptr().cast_mut(), ffi::MBSTRING_UTF8, value.as_ptr(), - value.len() as ValueLen, + try_int(value.len())?, -1, 0, )) @@ -1038,13 +1038,12 @@ impl X509NameBuilder { ) -> Result<(), ErrorStack> { unsafe { let field = CString::new(field).map_err(ErrorStack::internal_error)?; - assert!(value.len() <= ValueLen::MAX as usize); cvt(ffi::X509_NAME_add_entry_by_txt( self.0.as_ptr(), field.as_ptr().cast_mut(), ty.as_raw(), value.as_ptr(), - value.len() as ValueLen, + try_int(value.len())?, -1, 0, )) @@ -1055,13 +1054,12 @@ impl X509NameBuilder { #[corresponds(X509_NAME_add_entry_by_NID)] pub fn append_entry_by_nid(&mut self, field: Nid, value: &str) -> Result<(), ErrorStack> { unsafe { - assert!(value.len() <= ValueLen::MAX as usize); cvt(ffi::X509_NAME_add_entry_by_NID( self.0.as_ptr(), field.as_raw(), ffi::MBSTRING_UTF8, value.as_ptr().cast_mut(), - value.len() as ValueLen, + try_int(value.len())?, -1, 0, )) @@ -1077,13 +1075,12 @@ impl X509NameBuilder { ty: Asn1Type, ) -> Result<(), ErrorStack> { unsafe { - assert!(value.len() <= ValueLen::MAX as usize); cvt(ffi::X509_NAME_add_entry_by_NID( self.0.as_ptr(), field.as_raw(), ty.as_raw(), value.as_ptr().cast_mut(), - value.len() as ValueLen, + try_int(value.len())?, -1, 0, )) @@ -1100,11 +1097,6 @@ impl X509NameBuilder { } } -#[cfg(not(feature = "legacy-compat-deprecated"))] -type ValueLen = isize; -#[cfg(feature = "legacy-compat-deprecated")] -type ValueLen = i32; - foreign_type_and_impl_send_sync! { type CType = ffi::X509_NAME; fn drop = ffi::X509_NAME_free;