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::{