Open source Loco protocol implemention made with rust
| name | size | |-----------|-------------------| | header | (Header) 22 bytes | | data | header.data_size |
| name | size | |-----------|----------| | id | 4 bytes | | status | 2 bytes | | name | 11 bytes | | datatype | 1 bytes | | datasize | 4 bytes |
| name | size | |----------------|--------------------| | header | (Header) 20 bytes | | encrypted data | header.size - 16 |
| name | size | |-----------|----------| | iv | 16 bytes | | size | 4 bytes |
| name | size | |------------------|------------| | key size | 4 bytes | | keyencrypttype | 4 bytes | | encrypt_type | 4 bytes | | key | 256 bytes |
Note: current implemention only supports RSA-AES
```rust use std::{net::{TcpListener, TcpStream}, thread, io}; use openssl::rsa::Rsa; use loco_protocol::{command::{Command, Error, Header, processor::CommandProcessor}, io::SecureClientStream, io::SecureServerStream, secure::CryptoStore};
fn main() { let key = Rsa::generate(2048).expect("Cannot generate rsa key pairs.");
let socket = TcpListener::bind("127.0.0.1:5022").expect("Cannot bind tcp server");
socket.set_nonblocking(true).expect("Cannot set socket to unblocked mode");
let tcp = TcpStream::connect("127.0.0.1:5022").expect("Cannot connect tcp stream");
tcp.set_nonblocking(true).expect("Cannot set client stream to unblocked mode");
let mut client = CommandProcessor::new(
SecureClientStream::new(
CryptoStore::new().unwrap(),
key.clone(),
tcp
)
);
let command = Command {
header: Header {
id: 0,
status: 0,
name: [72_u8, 101, 108, 108, 111, 0, 0, 0, 0, 0, 0],
data_type: 0,
data_size: 5
},
data: "Hello".as_bytes().into(),
};
client.write_commmand(command.clone()).expect("Failed to send command");
println!("CLIENT -> {:?}", command.clone());
loop {
match socket.accept() {
Ok(connection) => {
let key = key.clone();
thread::spawn(move || {
let mut server = CommandProcessor::new(
SecureServerStream::new(
CryptoStore::new().unwrap(),
key,
connection.0
)
);
println!("Connected from {}", connection.1);
loop {
match server.read_commmand() {
Ok(readed) => {
if readed.is_some() {
let received = readed.unwrap();
println!("SERVER <- {:?}", received.clone());
server.write_commmand(received.clone()).expect("Command failed to write");
println!("SERVER -> {:?}", received.clone());
break;
}
}
Err(err) => panic!(format!("{}", err))
}
}
});
}
Err(err) if err.kind() == io::ErrorKind::WouldBlock => { }
Err(err) => panic!(format!("{}", err))
}
match client.read_commmand() {
Ok(readed) => {
match readed {
Some(received) => {
println!("CLIENT <- {:?}", received);
return;
}
None => {}
}
}
Err(err) => {
match err {
Error::Io(io_err) if io_err.kind() == io::ErrorKind::WouldBlock => {}
_ => panic!(format!("{}", err))
}
}
}
}
} ```
loco-protocol is following MIT License.