Protocol encryption/decryption
This commit is contained in:
parent
119ff2903f
commit
d2a113e5a4
2 changed files with 67 additions and 42 deletions
|
@ -3,6 +3,8 @@
|
|||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use quick_error::quick_error;
|
||||
|
||||
quick_error! {
|
||||
|
@ -21,7 +23,7 @@ quick_error! {
|
|||
pub type CofferResult<T> = Result<T, CofferError>;
|
||||
|
||||
/// Values supported by a `Coffer`
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum CofferValue {
|
||||
/// A UTF-8 encoded string
|
||||
String(String),
|
||||
|
@ -32,7 +34,7 @@ pub enum CofferValue {
|
|||
}
|
||||
|
||||
/// 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>);
|
||||
|
||||
/// Interface for interacting with a `Coffer`
|
||||
|
|
|
@ -6,12 +6,12 @@ use std::convert::TryInto;
|
|||
use std::convert::TryFrom;
|
||||
use std::net::Shutdown;
|
||||
|
||||
use bytes::BytesMut;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::net::TcpStream;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use serde_cbor;
|
||||
|
||||
use quick_error::quick_error;
|
||||
|
||||
use coffer_common::coffer::Coffer;
|
||||
|
@ -42,23 +42,20 @@ enum State {
|
|||
|
||||
#[derive(Debug)]
|
||||
enum Request {
|
||||
Hello,
|
||||
Hello(Vec<u8>),
|
||||
Put(Vec<u8>),
|
||||
Get(Vec<u8>),
|
||||
Bye,
|
||||
Error
|
||||
}
|
||||
|
||||
enum Response {
|
||||
OkGet(Vec<u8>)
|
||||
}
|
||||
|
||||
pub struct Protocol<C>
|
||||
where C: Coffer
|
||||
{
|
||||
stream: TcpStream,
|
||||
coffer: Arc<RwLock<C>>,
|
||||
keyring: Arc<RwLock<Keyring>>,
|
||||
client: Option<Vec<u8>>,
|
||||
state: State
|
||||
}
|
||||
|
||||
|
@ -73,7 +70,8 @@ where C: Coffer
|
|||
{
|
||||
|
||||
let state = State::Start;
|
||||
Protocol {stream, coffer, keyring, state}
|
||||
let client = None;
|
||||
Protocol {stream, coffer, keyring, client, state}
|
||||
}
|
||||
|
||||
pub async fn run(mut self) {
|
||||
|
@ -102,9 +100,9 @@ where C: Coffer
|
|||
.unwrap();
|
||||
|
||||
match msg_type {
|
||||
0x00 => Request::Hello,
|
||||
0x02 => Request::Put((*message).into()),
|
||||
0x03 => Request::Get((*message).into()),
|
||||
0x00 => Request::Hello(message),
|
||||
0x02 => Request::Put(message),
|
||||
0x03 => Request::Get(message),
|
||||
0x63 => Request::Bye,
|
||||
0xff => Request::Error,
|
||||
_ => Request::Error
|
||||
|
@ -167,44 +165,69 @@ where C: Coffer
|
|||
|
||||
async fn transit(&mut self, event: Request) {
|
||||
match (&self.state, event) {
|
||||
(State::Start, Request::Hello) => self.state = State::Link,
|
||||
(State::Link, Request::Get(_)) => {
|
||||
(State::Start, Request::Hello(pk)) => {
|
||||
debug!{"Reading public key"}
|
||||
self.keyring.write().await
|
||||
.add_known_key(&pk)
|
||||
.unwrap();
|
||||
self.client = Some(pk);
|
||||
self.state = State::Link;
|
||||
}
|
||||
|
||||
(State::Link, Request::Get(req)) => {
|
||||
debug!{"Writing response"}
|
||||
let get_res = self.coffer.read().await
|
||||
.get(CofferPath(vec!["a".into(), "b".into(), "c".into()]))
|
||||
let req = serde_cbor::from_slice(
|
||||
&self.keyring.read().await
|
||||
.open(&req)
|
||||
.unwrap()
|
||||
).unwrap();
|
||||
|
||||
let res = self.coffer.read().await
|
||||
.get(req)
|
||||
.unwrap();
|
||||
|
||||
if let CofferValue::Blob(b) = get_res {
|
||||
let response = Response::OkGet(b);
|
||||
Self::write_response(response, &mut self.stream).await;
|
||||
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(p)) => {
|
||||
|
||||
(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(CofferPath(vec!["a".into(), "b".into(), "c".into()]),
|
||||
CofferValue::Blob(p));
|
||||
.put(coffer_path, coffer_value)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
self.state = State::Link;
|
||||
}
|
||||
|
||||
(_, Request::Bye) => self.state = State::End,
|
||||
|
||||
(_, Request::Error) => self.state = State::End,
|
||||
|
||||
_ => self.state = State::End
|
||||
}
|
||||
}
|
||||
|
||||
async fn write_response<T>(response: Response, writer: &mut T)
|
||||
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> {
|
||||
async fn framed(msg_type: u8, data: Vec<u8>) -> Vec<u8> {
|
||||
trace!{"Creating frame for type: {:?}, data: {:?}", msg_type, data}
|
||||
|
||||
// TODO magic number
|
||||
|
|
Loading…
Reference in a new issue