d9d549fd0f
* Changed identity keypair to use ed25519 * Encryption key is now x25519 based + compatibiltiy with sphinx * Pathing and import fixes * Moved all asymmetric keys to sub-module in crypto * Extracted aes to separate module * kdf module in crypto * Ability to perform diffie hellman on encryption keys * ecdsa on identity keys * Extremely rough and incomplete registration handshake * Authentication primitives * Creating new random authenticationIV * Wrapper type for the derived shared key * Removed AuthToken in favour of using SharedKey for authentication * Gateway identity keys * Registration handshake without error mapping * Gateway address in client config * Added extra key for gateway presence * Updated pemstore to work on borrows instead * Gateway client trying to perform the handshake * Gateway changes to allow for handshake and shared key * Debug trait on sharedkey * native client using updated gateway client * Slightly updated gateway API * Minor cleanup * Fixed pemstore to correctly save multiple keypairs * Gateway actually deriving shared key during handshake * Gateway sending correct mid-handshake message * Missing quotation mark in client config template * Fixed template for correct shared key serialization * Fixed gateway authentication * Fixed tests * Using correct gateway key when converting to sphinx node * "get_all_clients" takes them from gateways as opposed to providers now * cargo fmt * Renamed pemstore methods * Unused import * Encryption of forward requests between client and gateway * Updated sphinx dependency to use public revision * Sending 'error' on handshake processing error * Removed some dead code * Dead code I forgot to remove before * Extracted AckAes128Key into a struct * Slight pemstore revamp allowing for symmetric key store * ibid. * PemStorableKey for SharedKey * Introduced single location responsible for key management for client * WIP * Sphinx version update * Stop using NodeAddressBytes for two distinct and confusing purposes * Abstracting away SocketAddr from sphinx forwarding * Passing the bool for reply surbs * Attack plan for replies + encryption * Comment + removed variable binding * ReplySURB usage * Topology import in nymsphinx * Sphinx version update * Changed 'Recipient' to contain client's encryption key * Message preparation taking shape! * reply surb also containing the encryption key * Very initial message receiver * Sphinx version update * A possibly working way of receiving surbs * Fixed incorrect field name in client config template * camel casing all request arguments * Renamed and moved `MessageMode` to more appropriate file * Restored reconstruction tests * Removed dead code from chunking * Made rust examples compilable * reply SURB key storage * Replies as an InputMessage * Forgotten commented code * No retransmission processing for cover or replies * Received reply processing * Renamed client pathfinder to something more appropriate * Made HasherOutputSize public * Added key store path to config * Reply surb attaching key digest when used * Changes due to previous renaming * Removed comment * Fixed insert_encryption_key * Assigning initial value of key store path * Computing key digest with correct algorithm * Initial and presumably temporary request serialization * hacky way of introducing 'FragmentIdentifier' for replies * Moved responsibility of reply encryption, padding, etc, to message preparer * Optional recipient in try_get_valid_topology_ref * Handling new reply surbs with acks and padding * Updated go and python examples to include replies in text and binary cases * Updated rust examples + binaryserverresponse * Helpers in rust examples * And updated JS example * Moved shared key generation function to crypto crate * Cover traffic encryption! * hmac computation in crypto * Updated aes imports due to new dependencies * hkdf made more generic * crypto cleanup + algorithms in params * Clippy cleanup pass * Generating encryption+mac shared keys between client and gateway * MACs attached to forward requests to gateway * Gateway messages encrypted and mac'd * Lowered logging level * compiler warning cleanup * Some minor cleanup * Generic stream cipher * Generic shared key derivation + algorithm definitions * Project-wide AES clean-up * Comment fix * Removed commented imports * Updated comments * Fixed topology test fixture
109 lines
3.7 KiB
Rust
109 lines
3.7 KiB
Rust
use futures::{SinkExt, StreamExt};
|
|
use nym_client::websocket::{ClientTextRequest, ReceivedTextMessage, ServerTextResponse};
|
|
use std::convert::TryFrom;
|
|
use tokio::net::TcpStream;
|
|
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message, WebSocketStream};
|
|
|
|
// just helpers functions that work in this very particular context because we are sending to ourselves
|
|
// and hence will always get a response back (i.e. the message we sent)
|
|
async fn send_message_and_get_response<M: Into<Message>>(
|
|
ws_stream: &mut WebSocketStream<TcpStream>,
|
|
req: M,
|
|
) -> ReceivedTextMessage {
|
|
ws_stream.send(req.into()).await.unwrap();
|
|
let raw_message = ws_stream.next().await.unwrap().unwrap();
|
|
let message = match raw_message {
|
|
Message::Text(txt_msg) => ServerTextResponse::try_from(txt_msg).unwrap(),
|
|
_ => panic!("received an unexpected response type!"),
|
|
};
|
|
|
|
match message {
|
|
ServerTextResponse::Received(received_message) => received_message,
|
|
_ => panic!("received an unexpected response type!"),
|
|
}
|
|
}
|
|
|
|
async fn get_self_address(ws_stream: &mut WebSocketStream<TcpStream>) -> String {
|
|
let self_address_request = ClientTextRequest::SelfAddress;
|
|
ws_stream.send(self_address_request.into()).await.unwrap();
|
|
|
|
let raw_response = ws_stream.next().await.unwrap().unwrap();
|
|
// what we received now is just a json, but we know it's exact format
|
|
// so might as well use that
|
|
let response = match raw_response {
|
|
Message::Text(txt_msg) => ServerTextResponse::try_from(txt_msg).unwrap(),
|
|
_ => panic!("received an unexpected response type!"),
|
|
};
|
|
|
|
match response {
|
|
ServerTextResponse::SelfAddress { address } => address,
|
|
_ => panic!("received an unexpected response type!"),
|
|
}
|
|
}
|
|
|
|
async fn send_text_with_reply() {
|
|
let message = "Hello Nym!".to_string();
|
|
|
|
let uri = "ws://localhost:1977";
|
|
let (mut ws_stream, _) = connect_async(uri).await.unwrap();
|
|
|
|
let recipient = get_self_address(&mut ws_stream).await;
|
|
println!("our full address is: {}", recipient.to_string());
|
|
|
|
let send_request = ClientTextRequest::Send {
|
|
message: message.clone(),
|
|
recipient,
|
|
with_reply_surb: true,
|
|
};
|
|
println!(
|
|
"sending {:?} (*with* reply SURB) over the mix network...",
|
|
message
|
|
);
|
|
|
|
let response = send_message_and_get_response(&mut ws_stream, send_request).await;
|
|
println!("received {:#?} from the mix network!", response);
|
|
|
|
let reply_message = "hello from reply SURB!";
|
|
let reply_request = ClientTextRequest::Reply {
|
|
message: reply_message.to_string(),
|
|
reply_surb: response.reply_surb.unwrap(),
|
|
};
|
|
|
|
println!(
|
|
"sending {:?} (using reply SURB!) over the mix network...",
|
|
reply_message
|
|
);
|
|
|
|
let response = send_message_and_get_response(&mut ws_stream, reply_request).await;
|
|
println!("received {:#?} from the mix network!", response);
|
|
}
|
|
|
|
async fn send_text_without_reply() {
|
|
let message = "Hello Nym!".to_string();
|
|
|
|
let uri = "ws://localhost:1977";
|
|
let (mut ws_stream, _) = connect_async(uri).await.unwrap();
|
|
|
|
let recipient = get_self_address(&mut ws_stream).await;
|
|
println!("our full address is: {}", recipient.to_string());
|
|
|
|
let send_request = ClientTextRequest::Send {
|
|
message: message.clone(),
|
|
recipient,
|
|
with_reply_surb: false,
|
|
};
|
|
println!(
|
|
"sending {:?} (*without reply SURB) over the mix network...",
|
|
message
|
|
);
|
|
let response = send_message_and_get_response(&mut ws_stream, send_request).await;
|
|
|
|
println!("received {:#?} from the mix network!", response);
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
// send_text_without_reply().await;
|
|
send_text_with_reply().await;
|
|
}
|