59 lines
1.8 KiB
Rust
59 lines
1.8 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 salt.
|
|
///
|
|
/// All salts returned are of size ```digest::SHA512_OUTPUT_LEN/2```, 32 bytes.
|
|
/// Should be used in contexts that return ```io::Result```.
|
|
/// Should be used in Async contexts.
|
|
///
|
|
/// Arguments:
|
|
/// socket - The TLS stream to use for the salt.
|
|
///
|
|
/// Returns: a ```io::Result<[u8; 32]>```.
|
|
///
|
|
/// Example:
|
|
/// ```rust
|
|
/// let server_salt: [u8; digest::SHA512_OUTPUT_LEN/2] = get_server_salt(tls_client)?;
|
|
/// ```
|
|
pub async fn get_server_salt(socket: &mut TlsStream<TcpStream>) -> std::io::Result<SaltString> {
|
|
/*
|
|
* request to generate a salt from the server.
|
|
* */
|
|
Message::new()
|
|
.command(Command::GenHashSalt)
|
|
.send(socket)
|
|
.await?;
|
|
|
|
let ret_msg = Message::receive(socket).await?;
|
|
|
|
/* assert received message */
|
|
if !ret_msg.assert_command(Command::Success) || !ret_msg.assert_data() {
|
|
Err(io::Error::new(
|
|
io::ErrorKind::InvalidData,
|
|
"Failed getting generated server Salt, received an invalid message.",
|
|
))
|
|
} else {
|
|
let salt_raw: String = ret_msg.get_data().map_err(|_| {
|
|
io::Error::new(
|
|
io::ErrorKind::InvalidData,
|
|
"Failed getting generated server Salt, received an invalid message.",
|
|
)
|
|
})?;
|
|
|
|
/* verify that the salt is actually valid */
|
|
SaltString::new(salt_raw.as_str()).map_err(|_| {
|
|
io::Error::new(
|
|
io::ErrorKind::InvalidData,
|
|
"Failed getting generated server Salt, received an invalid message.",
|
|
)
|
|
})
|
|
}
|
|
}
|