rust: bssl-tls: Share some credential configs with builder In some applications there is a need to re-configure authentications according to feedbacks. In the future we may judiciarily move more options into the in-handshake typestate as per request. Signed-off-by: Xiangfei Ding <xfding@google.com> Change-Id: If53122e2672740a0fcfdea957641df306a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/97247 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/rust/bssl-tls/src/connection.rs b/rust/bssl-tls/src/connection.rs index 62137b1..35b2c2d 100644 --- a/rust/bssl-tls/src/connection.rs +++ b/rust/bssl-tls/src/connection.rs
@@ -107,32 +107,25 @@ } } - fn get_connection_methods(&mut self) -> &mut methods::RustConnectionMethods<M> { - unsafe { - // Safety: the validity of the handle `self.0` is witnessed by - // `self`. - get_connection_methods(self.ptr()) - } - } - /// Disable session creation. pub fn disable_session(&mut self) -> &mut Self { - let ptr = self.ptr(); - unsafe { - // Safety: the validity of the handle `ptr` is witnessed by `self`. - bssl_sys::SSL_set_mode(ptr, ConnectionMode::MODE_NO_SESSION_CREATION.bits()); - } + self.as_in_handshake().disable_session(); self } /// Set the session for resumption. pub fn with_session(&mut self, session: &TlsSession) -> &mut Self { - unsafe { - // Safety: self.ptr and session.0 are valid. - bssl_sys::SSL_set_session(self.ptr.as_ptr(), session.0.as_ptr()); - } + self.as_in_handshake().set_session(session); self } + + pub(crate) fn as_in_handshake(&mut self) -> lifecycle::TlsConnectionInHandshake<'_, R, M> { + unsafe { + // Safety: `TlsConnectionBuilder` and `TlsConnection` have identical memory layout. + // Both are wrappers around `NonNull<bssl_sys::SSL>`. + lifecycle::TlsConnectionInHandshake(core::mem::transmute(self)) + } + } } /// TLS Connection
diff --git a/rust/bssl-tls/src/connection/credentials.rs b/rust/bssl-tls/src/connection/credentials.rs index 4caceec..1071e35 100644 --- a/rust/bssl-tls/src/connection/credentials.rs +++ b/rust/bssl-tls/src/connection/credentials.rs
@@ -21,7 +21,10 @@ ptr::null, // }; -use bssl_x509::{params::CertificateVerificationParams, store::X509Store}; +use bssl_x509::{ + params::CertificateVerificationParams, + store::X509Store, // +}; use super::{ Client, @@ -60,11 +63,8 @@ &mut self, mode: CertificateVerificationMode, ) -> &mut Self { - let ctx = self.ptr(); - unsafe { - // Safety: this method only updates the mode value. - bssl_sys::SSL_set_verify(ctx, mode as _, None); - } + self.as_in_handshake() + .set_certificate_verification_mode(mode); self } @@ -85,27 +85,14 @@ where V: VerifyCertificate + 'static, { - let ctx = self.ptr(); - unsafe { - // Safety: we only install our own vtable. - bssl_sys::SSL_set_custom_verify( - ctx, - mode as _, - Some(cert_cb::<super::methods::RustConnectionMethods<M>>), - ); - } - self.get_connection_methods().verify_certificate_methods = Some(Box::new(verifier) as _); + self.as_in_handshake() + .set_certificate_verifier(mode, verifier); self } /// Remove custom certificate verifier. pub fn without_certificate_verifier(&mut self, mode: CertificateVerificationMode) -> &mut Self { - let ctx = self.ptr(); - unsafe { - // Safety: we only uninstall the vtable. - bssl_sys::SSL_set_custom_verify(ctx, mode as _, None); - } - self.get_connection_methods().verify_certificate_methods = None; + self.as_in_handshake().remove_certificate_verifier(mode); self } } @@ -133,10 +120,56 @@ } /// # Custom certificate verification -impl<M> TlsConnectionInHandshake<'_, Client, M> +impl<R, M> TlsConnectionInHandshake<'_, R, M> where M: HasTlsConnectionMethod, { + /// Configure the certificate verification mode. + pub fn set_certificate_verification_mode( + &mut self, + mode: CertificateVerificationMode, + ) -> &mut Self { + let ctx = self.ptr(); + unsafe { + // Safety: this method only updates the mode value. + bssl_sys::SSL_set_verify(ctx, mode as _, None); + } + self + } + + /// Configure the certificate verifier. + pub fn set_certificate_verifier<V>( + &mut self, + mode: CertificateVerificationMode, + verifier: V, + ) -> &mut Self + where + V: VerifyCertificate + 'static, + { + let ctx = self.ptr(); + unsafe { + // Safety: we only install our own vtable. + bssl_sys::SSL_set_custom_verify( + ctx, + mode as _, + Some(cert_cb::<super::methods::RustConnectionMethods<M>>), + ); + } + self.get_connection_methods().verify_certificate_methods = Some(Box::new(verifier) as _); + self + } + + /// Remove custom certificate verifier. + pub fn remove_certificate_verifier(&mut self, mode: CertificateVerificationMode) -> &mut Self { + let ctx = self.ptr(); + unsafe { + // Safety: we only uninstall the vtable. + bssl_sys::SSL_set_custom_verify(ctx, mode as _, None); + } + self.get_connection_methods().verify_certificate_methods = None; + self + } + /// Get the certificate verification mode set by [`Self::set_certificate_verification_mode`]. pub fn get_certificate_verification_mode(&self) -> Option<CertificateVerificationMode> { unsafe { @@ -286,6 +319,28 @@ } } +/// # Sessions +impl<R, M> TlsConnectionInHandshake<'_, R, M> { + /// Disable session creation. + pub fn disable_session(&mut self) -> &mut Self { + let ptr = self.ptr(); + unsafe { + // Safety: the validity of the handle `ptr` is witnessed by `self`. + bssl_sys::SSL_set_mode(ptr, super::ConnectionMode::MODE_NO_SESSION_CREATION.bits()); + } + self + } + + /// Set the session for resumption. + pub fn set_session(&mut self, session: &crate::sessions::TlsSession) -> &mut Self { + unsafe { + // Safety: self.ptr and session.0 are valid. + bssl_sys::SSL_set_session(self.ptr.as_ptr(), session.0.as_ptr()); + } + self + } +} + impl<'a, R, M> EstablishedTlsConnection<'a, R, M> { /// Export keying material from this connection into a buffer of a chosen length, /// as per [RFC 5705].
diff --git a/rust/bssl-tls/src/credentials.rs b/rust/bssl-tls/src/credentials.rs index a67650c..5c93bd0 100644 --- a/rust/bssl-tls/src/credentials.rs +++ b/rust/bssl-tls/src/credentials.rs
@@ -52,7 +52,10 @@ call_slice_getter, check_lib_error, config::ConfigurationError, - connection::methods::{verify_cert_task_from_ssl, waker_data_from_ssl}, + connection::methods::{ + verify_cert_task_from_ssl, + waker_data_from_ssl, // + }, context::CertificateCache, crypto_buffer_wrapper, errors::{