浏览代码

more work towards encryption

master
Isabelle L. 5 年前
父节点
当前提交
f578c01c44
共有 4 个文件被更改,包括 122 次插入44 次删除
  1. +2
    -1
      README.md
  2. +3
    -6
      src/asymmetric_key.rs
  3. +114
    -29
      src/lib.rs
  4. +3
    -8
      src/message.rs

+ 2
- 1
README.md 查看文件

@@ -7,7 +7,8 @@ but i'm lazy and it seems to work so gonna roll with it lol

| segment size | usage |
|--------------|--------------------------------------------|
| 1 byte | u8 packet type |
| 1 byte | u8 packet kind |
| 1 byte | u8 encrypt kind |
| 8 byte | u64 length of the packet contents |
| 4 byte | CRC32 packet contents checksum |
| 32 byte | SHA256 packet contents integrity check |


+ 3
- 6
src/asymmetric_key.rs 查看文件

@@ -11,18 +11,15 @@ pub struct AsymmetricKey {
impl AsymmetricKey {
pub fn new(public_key: Vec<u8>) -> AsymmetricKey {
let timestamp = Utc::now().timestamp();
AsymmetricKey {
public_key,
timestamp,
}
AsymmetricKey { public_key, timestamp }
}
}

impl crate::Sendable for AsymmetricKey {
fn to_packet(&self) -> Result<Packet> {
fn to_packet(&self, encrypt_kind: crate::EncryptKind) -> Result<Packet> {
let contents: Vec<u8> = serde_json::to_string(&self)?.into_bytes();
let kind = PacketKind::AsymmetricKey;
Ok(Packet::new(kind, contents))
Ok(Packet::new(kind, contents, encrypt_kind))
}

fn from_packet(packet: Packet) -> Result<AsymmetricKey> {


+ 114
- 29
src/lib.rs 查看文件

@@ -7,7 +7,8 @@
//!
//! | segment size | usage |
//! |--------------|--------------------------------------------|
//! | 1 byte | u8 packet type |
//! | 1 byte | u8 packet kind |
//! | 1 byte | u8 encrypt kind |
//! | 8 byte | u64 length of the packet contents |
//! | 4 byte | CRC32 packet contents checksum |
//! | 32 byte | SHA256 packet contents integrity check |
@@ -20,7 +21,7 @@ mod asymmetric_key;
pub use asymmetric_key::AsymmetricKey;

use futures_util::io::{AsyncReadExt, AsyncWriteExt};
use ring::digest;
use ring::{rand, signature::{self, KeyPair},digest};
use std::convert::TryInto;
use std::marker::Unpin;
use thiserror::Error;
@@ -31,26 +32,23 @@ struct NetworkPacket(Vec<u8>);

/// a type of data that can be sent
pub trait Sendable: Sized {
fn to_packet(&self) -> Result<Packet>;
fn to_packet(&self, encrypt_kind: EncryptKind) -> Result<Packet>;
fn from_packet(packet: Packet) -> Result<Self>;
}

/// data to be sent
pub struct Packet {
pub kind: PacketKind,
pub encrypt_kind: EncryptKind,
integrity_hash: Vec<u8>,
contents: Vec<u8>,
}

impl Packet {
/// create a new `Packet`
pub fn new(kind: PacketKind, contents: Vec<u8>) -> Packet {
pub fn new(kind: PacketKind, contents: Vec<u8>, encrypt_kind: EncryptKind) -> Packet {
let integrity_hash = digest::digest(&digest::SHA256, &contents).as_ref().to_vec();
Packet {
kind,
integrity_hash,
contents,
}
Packet { kind, integrity_hash, contents, encrypt_kind }
}

// generate a checksum from the packet
@@ -71,6 +69,9 @@ impl Packet {
// write packet kind byte
contents.push(self.kind as u8);

// write encrypt kind byte
contents.push(self.encrypt_kind as u8);

// write the packet length
let contents_length = self.contents.len() as u64;
contents.extend_from_slice(&contents_length.to_le_bytes());
@@ -88,18 +89,13 @@ impl Packet {

/// verifies SHA256 integrity
pub fn verify_integrity(&self) -> Result<()> {
let expected = digest::digest(&digest::SHA256, &self.contents)
.as_ref()
.to_vec();
let expected = digest::digest(&digest::SHA256, &self.contents).as_ref().to_vec();

if expected == self.integrity_hash {
Ok(())
} else {
Err(IlmpError::BadHashIntegrity {
found: self.integrity_hash.clone(),
expected,
}
.into())
println!("bad integrity");
Err(IlmpError::BadHashIntegrity { found: self.integrity_hash.clone(), expected }.into())
}
}

@@ -110,6 +106,7 @@ impl Packet {
if found == expected {
Ok(())
} else {
println!("bad checksum");
Err(IlmpError::BadChecksumIntegrity { expected, found })
}
}
@@ -134,6 +131,86 @@ impl PacketKind {
}
}

pub trait Encryption {
fn kind(&self) -> EncryptKind;
fn key(&self) -> Option<Vec<u8>>;
}

pub struct AsymmetricEncrypt(Vec<u8>);

impl Encryption for AsymmetricEncrypt {
fn kind(&self) -> EncryptKind {
EncryptKind::Asymmetric
}

fn key(&self) -> Option<Vec<u8>> {
Some(self.0.clone())
}
}

impl AsymmetricEncrypt {
pub fn new(key: Vec<u8>) -> AsymmetricEncrypt {
AsymmetricEncrypt(key)
}
}

pub struct SymmetricEncrypt(Vec<u8>);

impl Encryption for SymmetricEncrypt {
fn kind(&self) -> EncryptKind {
EncryptKind::Symmetric
}

fn key(&self) -> Option<Vec<u8>> {
Some(self.0.clone())
}
}

impl SymmetricEncrypt {
pub fn new(key: Vec<u8>) -> SymmetricEncrypt {
SymmetricEncrypt(key)
}
}

pub struct NoEncrypt;

impl Encryption for NoEncrypt {
fn kind(&self) -> EncryptKind {
EncryptKind::None
}

fn key(&self) -> Option<Vec<u8>> {
None
}
}

impl NoEncrypt {
pub fn new() -> NoEncrypt {
NoEncrypt
}
}

/// encryption kind
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum EncryptKind {
None = 0x00,
Asymmetric = 0x80,
Symmetric = 0xff,
}

impl EncryptKind {
/// returns `EncryptKind` from u8 if returned value is valid
pub fn from_u8(kind: u8) -> Option<EncryptKind> {
match kind {
0x00 => Some(EncryptKind::None),
0x80 => Some(EncryptKind::Asymmetric),
0xff => Some(EncryptKind::Symmetric),
_ => None,
}
}
}

/// ilmp's error type
#[derive(Error, Debug)]
pub enum IlmpError {
@@ -157,15 +234,16 @@ pub async fn read<S>(stream: &mut S) -> Result<Option<Packet>>
where
S: AsyncReadExt + Unpin,
{
let mut info_buf = [0u8; 13];
let mut info_buf = [0u8; 14];
let check = stream.read(&mut info_buf).await?;
if check == 0 {
return Ok(None);
}

let kind = PacketKind::from_u8(info_buf[0]).unwrap();
let length = u64::from_le_bytes(info_buf[1..9].try_into().unwrap()) as usize;
let checksum = u32::from_le_bytes(info_buf[9..13].try_into().unwrap());
let encrypt_kind = EncryptKind::from_u8(info_buf[1]).unwrap();
let length = u64::from_le_bytes(info_buf[2..10].try_into().unwrap()) as usize;
let checksum = u32::from_le_bytes(info_buf[10..14].try_into().unwrap());

let mut integrity_hash: Vec<u8> = vec![0; 32];
stream.read(&mut integrity_hash).await?;
@@ -173,11 +251,7 @@ where
let mut contents: Vec<u8> = vec![0; length];
stream.read(&mut contents).await?;

let packet = Packet {
kind,
contents,
integrity_hash,
};
let packet = Packet { kind, contents, integrity_hash, encrypt_kind };

packet.verify_checksum(checksum)?;
packet.verify_integrity()?;
@@ -186,12 +260,23 @@ where
}

/// writes a `Sendable` packet to a stream
pub async fn write<S, P>(stream: &mut S, packet: P) -> Result<()>
pub async fn write<S, P, E>(stream: &mut S, packet: P, encryption: E) -> Result<()>
where
S: AsyncWriteExt + Unpin,
P: Sendable,
E: Encryption,
{
let network_packet = packet.to_packet()?.to_network_packet();
stream.write(&network_packet.0).await?;
Ok(())
match encryption.kind() {
EncryptKind::None => {
let network_packet = packet.to_packet(encryption.kind())?.to_network_packet();
stream.write(&network_packet.0).await?;
Ok(())
}
EncryptKind::Asymmetric => {
let
let mut packet = packet;
packet.contents
},
EncryptKind::Symmetric => todo!(),
}
}

+ 3
- 8
src/message.rs 查看文件

@@ -18,20 +18,15 @@ impl Message {
let timestamp = Utc::now().timestamp();
let message_id = Uuid::new_v4().as_u128();

Message {
username,
message_id,
timestamp,
contents,
}
Message { username, message_id, timestamp, contents }
}
}

impl crate::Sendable for Message {
fn to_packet(&self) -> Result<Packet> {
fn to_packet(&self, encrypt_kind: crate::EncryptKind) -> Result<Packet> {
let contents: Vec<u8> = serde_json::to_string(&self)?.into_bytes();
let kind = PacketKind::Message;
Ok(Packet::new(kind, contents))
Ok(Packet::new(kind, contents, encrypt_kind))
}

fn from_packet(packet: Packet) -> Result<Self> {


正在加载...
取消
保存