71 lines
2.1 KiB
Rust
71 lines
2.1 KiB
Rust
use std::io;
|
|
|
|
use argon2::password_hash::SaltString;
|
|
|
|
use crate::common::message::*;
|
|
|
|
use tokio::net::TcpStream;
|
|
use tokio_rustls::client::TlsStream;
|
|
|
|
/// Issues a command to the connected TLS server to obtain a stored salt for either email or
|
|
/// password.
|
|
///
|
|
/// All salts returned are of size ```digest::SHA512_OUTPUT_LEN``` or 64 bytes.
|
|
/// Should be used in contexts that return ```io::Result```.
|
|
/// Should be used in Async contexts.
|
|
///
|
|
/// Arguments:
|
|
/// socket - The TLS client to use for the salt.
|
|
/// username - The username to obtain the salt.
|
|
/// salt_type - The CommmandInst, either GetEmailSalt, or GetPasswordSalt.
|
|
///
|
|
/// Returns: a ```io::Result<[u8; 64]>```.
|
|
/// Example:
|
|
/// ```rust
|
|
/// let server_salt: [u8; digest::SHA512_OUTPUT_LEN/2] = req_server_salt(tls_client, "n1ckn8me",
|
|
/// CommandInst::GetEmailSalt)?;
|
|
/// ```
|
|
pub async fn req_server_salt(
|
|
socket: &mut TlsStream<TcpStream>,
|
|
username: &str,
|
|
salt_type: Command,
|
|
) -> std::io::Result<SaltString> {
|
|
/* enforce salt_type to be either email or password */
|
|
assert_eq!(
|
|
(salt_type == Command::GetEmailSalt) || (salt_type == Command::GetPasswordSalt),
|
|
true
|
|
);
|
|
|
|
/* generate message to send */
|
|
Message::new()
|
|
.command(salt_type)
|
|
.data(username)
|
|
.send(socket)
|
|
.await?;
|
|
|
|
let ret_msg = Message::receive(socket).await?;
|
|
|
|
/* assert received message */
|
|
if !ret_msg.assert_command(Command::Success) || !ret_msg.assert_data() {
|
|
return Err(io::Error::new(
|
|
io::ErrorKind::InvalidData,
|
|
"Recieved invalid Salt from server.",
|
|
));
|
|
}
|
|
|
|
let salt_raw: String = ret_msg.get_data().map_err(|_| {
|
|
io::Error::new(
|
|
io::ErrorKind::InvalidData,
|
|
"Could not get server salt, received invalid data.",
|
|
)
|
|
})?;
|
|
|
|
/* verify that the salt is actually valid */
|
|
SaltString::new(salt_raw.as_str()).map_err(|_| {
|
|
io::Error::new(
|
|
io::ErrorKind::InvalidData,
|
|
format!("Could not get server salt, received invalid salt length."),
|
|
)
|
|
})
|
|
}
|