Protocol encryption/decryption

This commit is contained in:
Armin Friedl 2020-01-13 01:22:46 +01:00
parent 119ff2903f
commit d2a113e5a4
Signed by: armin
GPG key ID: 48C726EEE7FBCBC8
2 changed files with 67 additions and 42 deletions

View file

@ -3,6 +3,8 @@
#[allow(unused_imports)] #[allow(unused_imports)]
use log::{debug, error, info, trace, warn}; use log::{debug, error, info, trace, warn};
use serde::{Serialize, Deserialize};
use quick_error::quick_error; use quick_error::quick_error;
quick_error! { quick_error! {
@ -21,7 +23,7 @@ quick_error! {
pub type CofferResult<T> = Result<T, CofferError>; pub type CofferResult<T> = Result<T, CofferError>;
/// Values supported by a `Coffer` /// Values supported by a `Coffer`
#[derive(Clone, Debug)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub enum CofferValue { pub enum CofferValue {
/// A UTF-8 encoded string /// A UTF-8 encoded string
String(String), String(String),
@ -32,7 +34,7 @@ pub enum CofferValue {
} }
/// A path to a value /// A path to a value
#[derive(Clone, Eq, PartialEq, Hash, Debug)] #[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
pub struct CofferPath(pub Vec<String>); pub struct CofferPath(pub Vec<String>);
/// Interface for interacting with a `Coffer` /// Interface for interacting with a `Coffer`

View file

@ -6,12 +6,12 @@ use std::convert::TryInto;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::net::Shutdown; use std::net::Shutdown;
use bytes::BytesMut;
use tokio::prelude::*; use tokio::prelude::*;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use serde_cbor;
use quick_error::quick_error; use quick_error::quick_error;
use coffer_common::coffer::Coffer; use coffer_common::coffer::Coffer;
@ -42,23 +42,20 @@ enum State {
#[derive(Debug)] #[derive(Debug)]
enum Request { enum Request {
Hello, Hello(Vec<u8>),
Put(Vec<u8>), Put(Vec<u8>),
Get(Vec<u8>), Get(Vec<u8>),
Bye, Bye,
Error Error
} }
enum Response {
OkGet(Vec<u8>)
}
pub struct Protocol<C> pub struct Protocol<C>
where C: Coffer where C: Coffer
{ {
stream: TcpStream, stream: TcpStream,
coffer: Arc<RwLock<C>>, coffer: Arc<RwLock<C>>,
keyring: Arc<RwLock<Keyring>>, keyring: Arc<RwLock<Keyring>>,
client: Option<Vec<u8>>,
state: State state: State
} }
@ -73,7 +70,8 @@ where C: Coffer
{ {
let state = State::Start; let state = State::Start;
Protocol {stream, coffer, keyring, state} let client = None;
Protocol {stream, coffer, keyring, client, state}
} }
pub async fn run(mut self) { pub async fn run(mut self) {
@ -102,9 +100,9 @@ where C: Coffer
.unwrap(); .unwrap();
match msg_type { match msg_type {
0x00 => Request::Hello, 0x00 => Request::Hello(message),
0x02 => Request::Put((*message).into()), 0x02 => Request::Put(message),
0x03 => Request::Get((*message).into()), 0x03 => Request::Get(message),
0x63 => Request::Bye, 0x63 => Request::Bye,
0xff => Request::Error, 0xff => Request::Error,
_ => Request::Error _ => Request::Error
@ -167,44 +165,69 @@ where C: Coffer
async fn transit(&mut self, event: Request) { async fn transit(&mut self, event: Request) {
match (&self.state, event) { match (&self.state, event) {
(State::Start, Request::Hello) => self.state = State::Link, (State::Start, Request::Hello(pk)) => {
(State::Link, Request::Get(_)) => { debug!{"Reading public key"}
debug!{"Writing response"} self.keyring.write().await
let get_res = self.coffer.read().await .add_known_key(&pk)
.get(CofferPath(vec!["a".into(), "b".into(), "c".into()]))
.unwrap(); .unwrap();
self.client = Some(pk);
if let CofferValue::Blob(b) = get_res {
let response = Response::OkGet(b);
Self::write_response(response, &mut self.stream).await;
self.state = State::Link;
}
}
(State::Link, Request::Put(p)) => {
self.coffer.write().await
.put(CofferPath(vec!["a".into(), "b".into(), "c".into()]),
CofferValue::Blob(p));
self.state = State::Link; self.state = State::Link;
} }
(State::Link, Request::Get(req)) => {
debug!{"Writing response"}
let req = serde_cbor::from_slice(
&self.keyring.read().await
.open(&req)
.unwrap()
).unwrap();
let res = self.coffer.read().await
.get(req)
.unwrap();
let response = self.keyring.read().await
.seal(
&self.client.as_ref().unwrap(),
&serde_cbor::to_vec(&res).unwrap()
).unwrap();
// TODO magic number
let frame = Self::framed(0x05u8, response).await;
trace!{"OkGet Frame: {:?}", frame}
// TODO Proper result handling
self.stream.write_all(&frame).await.unwrap();
self.state = State::Link;
}
(State::Link, Request::Put(put)) => {
debug!{"Putting secrets"}
let put: Vec<(CofferPath, CofferValue)> =
serde_cbor::from_slice(
&self.keyring.read().await
.open(&put)
.unwrap()
).unwrap();
for (coffer_path, coffer_value) in put {
self.coffer.write().await
.put(coffer_path, coffer_value)
.unwrap();
}
self.state = State::Link;
}
(_, Request::Bye) => self.state = State::End, (_, Request::Bye) => self.state = State::End,
(_, Request::Error) => self.state = State::End, (_, Request::Error) => self.state = State::End,
_ => self.state = State::End _ => self.state = State::End
} }
} }
async fn write_response<T>(response: Response, writer: &mut T) async fn framed(msg_type: u8, data: Vec<u8>) -> Vec<u8> {
where T: AsyncWrite + Unpin
{
match response {
Response::OkGet(get) => {
let frame = Self::make_frame(0x05u8, get).await;
trace!{"OkGet Frame: {:?}", frame}
writer.write_all(&frame).await.unwrap();
}
}
}
async fn make_frame(msg_type: u8, data: Vec<u8>) -> Vec<u8> {
trace!{"Creating frame for type: {:?}, data: {:?}", msg_type, data} trace!{"Creating frame for type: {:?}, data: {:?}", msg_type, data}
// TODO magic number // TODO magic number