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)]
|
#[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`
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue