rust: bssl-tls: Reinstate preshared key tests

Unfortunately test was merged in a wrong order, its dependency on
application I/O was not met.

Signed-off-by: Xiangfei Ding <xfding@google.com>
Change-Id: Iafbffab72ad18d24afb9e2c2b8c7476d6a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/93008
Reviewed-by: Adam Langley <agl@google.com>
Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/rust/bssl-tls/src/credentials/tests.rs b/rust/bssl-tls/src/credentials/tests.rs
index abe40eb..ab10393 100644
--- a/rust/bssl-tls/src/credentials/tests.rs
+++ b/rust/bssl-tls/src/credentials/tests.rs
@@ -134,3 +134,103 @@
         Some(PrivateKeyAlgorithm::Rsa)
     ));
 }
+
+#[cfg(feature = "tokio_net")]
+#[tokio::test]
+async fn psk_tls13_handshake() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
+    use crate::credentials::{PskHash, TlsCredential};
+    use crate::io::tokio::TokioIo;
+
+    let _ = tracing_subscriber::fmt()
+        .with_max_level(tracing::Level::DEBUG)
+        .try_init();
+
+    let key = b"test-key-test-key-test-key-test-key";
+    let identity = b"test-identity";
+    let context = b"test-context";
+
+    let cred = TlsCredential::new_pre_shared_key(key, identity, PskHash::Sha256, context)?;
+
+    let mut server_ctx = crate::context::TlsContextBuilder::new_tls();
+    server_ctx.with_credential(cred.clone())?;
+
+    let mut client_ctx = crate::context::TlsContextBuilder::new_tls();
+    client_ctx.with_credential(cred)?;
+
+    let server_ctx = server_ctx.build();
+    let client_ctx = client_ctx.build();
+
+    let (client_io, server_io) = tokio::io::duplex(1024);
+
+    let mut client_conn = client_ctx.new_client_connection(None)?.build();
+    let mut server_conn = server_ctx.new_server_connection(None)?.build();
+
+    client_conn.set_io(TokioIo(client_io))?;
+    server_conn.set_io(TokioIo(server_io))?;
+
+    let client_task = tokio::spawn(async move {
+        let mut in_handshake = client_conn.in_handshake().unwrap();
+        in_handshake.async_handshake().await?;
+        Ok::<_, Box<dyn std::error::Error + Send + Sync>>(())
+    });
+
+    let server_task = tokio::spawn(async move {
+        let mut in_handshake = server_conn.in_handshake().unwrap();
+        in_handshake.async_handshake().await?;
+        Ok::<_, Box<dyn std::error::Error + Send + Sync>>(())
+    });
+
+    let (client_task, server_task) = tokio::try_join!(client_task, server_task)?;
+    client_task?;
+    server_task?;
+    Ok(())
+}
+
+#[cfg(all(unix, feature = "std"))]
+#[test]
+fn psk_tls13_handshake_sync() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
+    use crate::credentials::{PskHash, TlsCredential};
+    use crate::io::sync_io::{NoAsync, StdIoWithReactor};
+    use std::io::pipe;
+
+    let (server_rx, client_tx) = pipe().unwrap();
+    let (client_rx, server_tx) = pipe().unwrap();
+
+    let client_reader = StdIoWithReactor::new(client_rx, NoAsync);
+    let client_writer = StdIoWithReactor::new(client_tx, NoAsync);
+    let server_reader = StdIoWithReactor::new(server_rx, NoAsync);
+    let server_writer = StdIoWithReactor::new(server_tx, NoAsync);
+
+    let key = b"test-key-test-key-test-key-test-key";
+    let identity = b"test-identity";
+    let context = b"test-context";
+
+    let cred = TlsCredential::new_pre_shared_key(key, identity, PskHash::Sha256, context)?;
+
+    let mut server_ctx = crate::context::TlsContextBuilder::new_tls();
+    server_ctx.with_credential(cred.clone())?;
+    let server_ctx = server_ctx.build();
+
+    let mut client_ctx = crate::context::TlsContextBuilder::new_tls();
+    client_ctx.with_credential(cred)?;
+    let client_ctx = client_ctx.build();
+
+    let mut client_conn = client_ctx.new_client_connection(None)?.build();
+    let mut server_conn = server_ctx.new_server_connection(None)?.build();
+
+    client_conn.set_split_io(client_reader, client_writer)?;
+    server_conn.set_split_io(server_reader, server_writer)?;
+
+    let server_thread = std::thread::spawn(move || {
+        let mut in_handshake = server_conn.in_handshake().unwrap();
+        in_handshake.do_handshake().unwrap();
+        server_conn
+    });
+
+    let mut in_handshake = client_conn.in_handshake().unwrap();
+    in_handshake.do_handshake().unwrap();
+
+    let _server_conn = server_thread.join().unwrap();
+
+    Ok(())
+}