mirror of https://github.com/dswd/vpncloud.git
Changed encryption a little
This commit is contained in:
parent
938b060ad0
commit
553526299c
|
@ -14,7 +14,7 @@ use super::types::{Table, Protocol, Range, Error, NetworkId};
|
||||||
use super::device::Device;
|
use super::device::Device;
|
||||||
use super::udpmessage::{encode, decode, Options, Message};
|
use super::udpmessage::{encode, decode, Options, Message};
|
||||||
use super::{ethernet, ip};
|
use super::{ethernet, ip};
|
||||||
use super::Crypto;
|
use super::crypto::Crypto;
|
||||||
|
|
||||||
struct PeerList {
|
struct PeerList {
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
use sodiumoxide::crypto::stream::chacha20::{Key as CryptoKey, Nonce, stream_xor_inplace, gen_nonce,
|
|
||||||
KEYBYTES};
|
|
||||||
use sodiumoxide::crypto::auth::hmacsha512256::{Key as AuthKey, Tag, authenticate, verify};
|
|
||||||
use sodiumoxide::crypto::pwhash::{derive_key, SALTBYTES, Salt, HASHEDPASSWORDBYTES,
|
|
||||||
OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE};
|
|
||||||
|
|
||||||
use super::types::Error;
|
|
||||||
|
|
||||||
pub enum Crypto {
|
|
||||||
None,
|
|
||||||
ChaCha20HmacSha512256{key: Vec<u8>, nonce: Vec<u8>}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inc_nonce(nonce: &mut [u8]) {
|
|
||||||
let len = nonce.len();
|
|
||||||
for i in 1..len+1 {
|
|
||||||
let mut val = nonce[len-i];
|
|
||||||
val = val.wrapping_add(1);
|
|
||||||
nonce[len-i] = val;
|
|
||||||
if val != 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Crypto {
|
|
||||||
pub fn is_secure(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
&Crypto::None => false,
|
|
||||||
_ => true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_shared_key(password: &str) -> Self {
|
|
||||||
let salt = "vpncloudVPNCLOUDvpncl0udVpnCloud";
|
|
||||||
assert_eq!(salt.len(), SALTBYTES);
|
|
||||||
let mut key = [0; HASHEDPASSWORDBYTES];
|
|
||||||
derive_key(&mut key, password.as_bytes(), &Salt::from_slice(salt.as_bytes()).unwrap(),
|
|
||||||
OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE).unwrap();
|
|
||||||
let key = key[..KEYBYTES].iter().map(|b| *b).collect();
|
|
||||||
let nonce = gen_nonce().0.iter().map(|b| *b).collect();
|
|
||||||
Crypto::ChaCha20HmacSha512256{key: key, nonce: nonce}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decrypt(&self, mut buf: &mut [u8], nonce: &[u8], hash: &[u8]) -> Result<(), Error> {
|
|
||||||
match self {
|
|
||||||
&Crypto::None => Ok(()),
|
|
||||||
&Crypto::ChaCha20HmacSha512256{ref key, nonce: _} => {
|
|
||||||
let crypto_key = CryptoKey::from_slice(key).unwrap();
|
|
||||||
let nonce = Nonce::from_slice(nonce).unwrap();
|
|
||||||
let auth_key = AuthKey::from_slice(key).unwrap();
|
|
||||||
let hash = Tag::from_slice(hash).unwrap();
|
|
||||||
stream_xor_inplace(&mut buf, &nonce, &crypto_key);
|
|
||||||
match verify(&hash, &buf, &auth_key) {
|
|
||||||
true => Ok(()),
|
|
||||||
false => Err(Error::CryptoError("Decryption failed"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn encrypt(&mut self, mut buf: &mut [u8]) -> (Vec<u8>, Vec<u8>) {
|
|
||||||
match self {
|
|
||||||
&mut Crypto::None => (Vec::new(), Vec::new()),
|
|
||||||
&mut Crypto::ChaCha20HmacSha512256{ref key, ref mut nonce} => {
|
|
||||||
let crypto_key = CryptoKey::from_slice(key).unwrap();
|
|
||||||
let auth_key = AuthKey::from_slice(key).unwrap();
|
|
||||||
inc_nonce(nonce);
|
|
||||||
let hash = authenticate(&buf, &auth_key);
|
|
||||||
stream_xor_inplace(&mut buf, &Nonce::from_slice(&nonce).unwrap(), &crypto_key);
|
|
||||||
(nonce.clone(), hash.0.iter().map(|v| *v).collect())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn encrypt_decrypt() {
|
|
||||||
let mut sender = Crypto::from_shared_key("test");
|
|
||||||
let receiver = Crypto::from_shared_key("test");
|
|
||||||
let msg = "HelloWorld0123456789";
|
|
||||||
let mut buffer: Vec<u8> = msg.bytes().collect();
|
|
||||||
let (nonce1, hash1) = sender.encrypt(&mut buffer);
|
|
||||||
assert!(msg.as_bytes() != &buffer as &[u8]);
|
|
||||||
receiver.decrypt(&mut buffer, &nonce1, &hash1).unwrap();
|
|
||||||
assert_eq!(msg.as_bytes(), &buffer as &[u8]);
|
|
||||||
let (nonce2, hash2) = sender.encrypt(&mut buffer);
|
|
||||||
assert!(nonce1 != nonce2);
|
|
||||||
assert!(hash1 == hash2);
|
|
||||||
receiver.decrypt(&mut buffer, &nonce2, &hash2).unwrap();
|
|
||||||
assert_eq!(msg.as_bytes(), &buffer as &[u8]);
|
|
||||||
}
|
|
|
@ -1,12 +1,20 @@
|
||||||
use super::types::Error;
|
use super::super::types::Error;
|
||||||
|
|
||||||
pub enum Crypto {
|
pub enum Crypto {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Crypto {
|
impl Crypto {
|
||||||
pub fn is_secure(&self) -> bool {
|
pub fn method(&self) -> u8 {
|
||||||
false
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nonce_bytes(&self) -> usize {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn auth_bytes(&self) -> usize {
|
||||||
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_shared_key(_password: &str) -> Self {
|
pub fn from_shared_key(_password: &str) -> Self {
|
||||||
|
@ -14,10 +22,10 @@ impl Crypto {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decrypt(&self, mut _buf: &mut [u8], _nonce: &[u8], _hash: &[u8]) -> Result<(), Error> {
|
pub fn decrypt(&self, mut _buf: &mut [u8], _nonce: &[u8], _hash: &[u8]) -> Result<(), Error> {
|
||||||
Ok(())
|
unreachable!("This should never be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypt(&mut self, mut _buf: &mut [u8]) -> (Vec<u8>, Vec<u8>) {
|
pub fn encrypt(&mut self, mut _buf: &mut [u8]) -> (Vec<u8>, Vec<u8>) {
|
||||||
(Vec::new(), Vec::new())
|
unreachable!("This should never be called")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#[cfg(feature = "crypto")] mod sodium;
|
||||||
|
#[cfg(not(feature = "crypto"))] mod dummy;
|
||||||
|
|
||||||
|
#[cfg(feature = "crypto")] pub use self::sodium::Crypto;
|
||||||
|
#[cfg(not(feature = "crypto"))] pub use self::dummy::Crypto;
|
|
@ -0,0 +1,106 @@
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
use sodiumoxide::crypto::stream::chacha20::{Key as CryptoKey, Nonce, stream_xor_inplace, gen_nonce,
|
||||||
|
KEYBYTES, NONCEBYTES};
|
||||||
|
use sodiumoxide::crypto::auth::hmacsha512256::{Key as AuthKey, Tag, authenticate, verify, TAGBYTES};
|
||||||
|
use sodiumoxide::crypto::pwhash::{derive_key, SALTBYTES, Salt, HASHEDPASSWORDBYTES,
|
||||||
|
OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE};
|
||||||
|
|
||||||
|
use super::super::types::Error;
|
||||||
|
|
||||||
|
pub enum Crypto {
|
||||||
|
None,
|
||||||
|
ChaCha20HmacSha512256{crypto_key: CryptoKey, auth_key: AuthKey, nonce: Nonce}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inc_nonce(nonce: Nonce) -> Nonce {
|
||||||
|
unsafe {
|
||||||
|
let mut num: u64 = mem::transmute(nonce);
|
||||||
|
num = num.wrapping_add(1);
|
||||||
|
mem::transmute(num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Crypto {
|
||||||
|
pub fn method(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
&Crypto::None => 0,
|
||||||
|
&Crypto::ChaCha20HmacSha512256{crypto_key: _, auth_key: _, nonce: _} => 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nonce_bytes(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
&Crypto::None => 0,
|
||||||
|
&Crypto::ChaCha20HmacSha512256{crypto_key: _, auth_key: _, nonce: _} => NONCEBYTES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn auth_bytes(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
&Crypto::None => 0,
|
||||||
|
&Crypto::ChaCha20HmacSha512256{crypto_key: _, auth_key: _, nonce: _} => TAGBYTES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_shared_key(password: &str) -> Self {
|
||||||
|
let salt = "vpncloudVPNCLOUDvpncl0udVpnCloud";
|
||||||
|
assert_eq!(salt.len(), SALTBYTES);
|
||||||
|
let mut key = [0; HASHEDPASSWORDBYTES];
|
||||||
|
derive_key(&mut key, password.as_bytes(), &Salt::from_slice(salt.as_bytes()).unwrap(),
|
||||||
|
OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE).unwrap();
|
||||||
|
let mut crypto_key = CryptoKey([0; KEYBYTES]);
|
||||||
|
let mut auth_key = AuthKey([0; KEYBYTES]);
|
||||||
|
for i in 0..KEYBYTES {
|
||||||
|
crypto_key.0[i] = key[i];
|
||||||
|
}
|
||||||
|
for i in 0..KEYBYTES {
|
||||||
|
auth_key.0[i] = key[KEYBYTES+i];
|
||||||
|
}
|
||||||
|
Crypto::ChaCha20HmacSha512256{crypto_key: crypto_key, auth_key: auth_key, nonce: gen_nonce()}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decrypt(&self, mut buf: &mut [u8], nonce: &[u8], hash: &[u8]) -> Result<(), Error> {
|
||||||
|
match self {
|
||||||
|
&Crypto::None => unreachable!("This should never be called"),
|
||||||
|
&Crypto::ChaCha20HmacSha512256{ref crypto_key, ref auth_key, nonce: _} => {
|
||||||
|
let nonce = Nonce::from_slice(nonce).unwrap();
|
||||||
|
let hash = Tag::from_slice(hash).unwrap();
|
||||||
|
stream_xor_inplace(&mut buf, &nonce, crypto_key);
|
||||||
|
match verify(&hash, &buf, auth_key) {
|
||||||
|
true => Ok(()),
|
||||||
|
false => Err(Error::CryptoError("Decryption failed"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encrypt(&mut self, mut buf: &mut [u8]) -> (Vec<u8>, Vec<u8>) {
|
||||||
|
match self {
|
||||||
|
&mut Crypto::None => unreachable!("This should never be called"),
|
||||||
|
&mut Crypto::ChaCha20HmacSha512256{ref crypto_key, ref auth_key, ref mut nonce} => {
|
||||||
|
*nonce = inc_nonce(*nonce);
|
||||||
|
let hash = authenticate(&buf, auth_key);
|
||||||
|
stream_xor_inplace(&mut buf, nonce, crypto_key);
|
||||||
|
(nonce.0.iter().map(|v| *v).collect(), hash.0.iter().map(|v| *v).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn encrypt_decrypt() {
|
||||||
|
let mut sender = Crypto::from_shared_key("test");
|
||||||
|
let receiver = Crypto::from_shared_key("test");
|
||||||
|
let msg = "HelloWorld0123456789";
|
||||||
|
let mut buffer: Vec<u8> = msg.bytes().collect();
|
||||||
|
let (nonce1, hash1) = sender.encrypt(&mut buffer);
|
||||||
|
assert!(msg.as_bytes() != &buffer as &[u8]);
|
||||||
|
receiver.decrypt(&mut buffer, &nonce1, &hash1).unwrap();
|
||||||
|
assert_eq!(msg.as_bytes(), &buffer as &[u8]);
|
||||||
|
let (nonce2, hash2) = sender.encrypt(&mut buffer);
|
||||||
|
assert!(nonce1 != nonce2);
|
||||||
|
assert!(hash1 == hash2);
|
||||||
|
receiver.decrypt(&mut buffer, &nonce2, &hash2).unwrap();
|
||||||
|
assert_eq!(msg.as_bytes(), &buffer as &[u8]);
|
||||||
|
}
|
10
src/main.rs
10
src/main.rs
|
@ -7,8 +7,7 @@ extern crate epoll;
|
||||||
|
|
||||||
mod util;
|
mod util;
|
||||||
mod types;
|
mod types;
|
||||||
#[cfg(feature = "crypto")] mod crypto;
|
mod crypto;
|
||||||
#[cfg(not(feature = "crypto"))] mod no_crypto;
|
|
||||||
mod udpmessage;
|
mod udpmessage;
|
||||||
mod ethernet;
|
mod ethernet;
|
||||||
mod ip;
|
mod ip;
|
||||||
|
@ -28,12 +27,13 @@ use ip::RoutingTable;
|
||||||
use types::{Error, Mode, Type, Range, Table};
|
use types::{Error, Mode, Type, Range, Table};
|
||||||
use cloud::{TapCloud, TunCloud};
|
use cloud::{TapCloud, TunCloud};
|
||||||
use udpmessage::VERSION;
|
use udpmessage::VERSION;
|
||||||
#[cfg(feature = "crypto")] pub use crypto::Crypto;
|
use crypto::Crypto;
|
||||||
#[cfg(not(feature = "crypto"))] pub use no_crypto::Crypto;
|
|
||||||
|
|
||||||
//TODO: Implement IPv6
|
//TODO: Implement IPv6
|
||||||
//TODO: Call close
|
//TODO: Call close
|
||||||
|
//FIXME: The crypto method should be signaled as part of the protocol
|
||||||
|
//FIXME: The HMAC should also include the header
|
||||||
|
//FIXME: Encryption should also include all following additional headers
|
||||||
|
|
||||||
struct SimpleLogger;
|
struct SimpleLogger;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::u16;
|
||||||
|
|
||||||
use super::types::{Error, NetworkId, Range, Address};
|
use super::types::{Error, NetworkId, Range, Address};
|
||||||
use super::util::{as_obj, as_bytes, to_vec};
|
use super::util::{as_obj, as_bytes, to_vec};
|
||||||
use super::Crypto;
|
use super::crypto::Crypto;
|
||||||
|
|
||||||
const MAGIC: [u8; 3] = [0x76, 0x70, 0x6e];
|
const MAGIC: [u8; 3] = [0x76, 0x70, 0x6e];
|
||||||
pub const VERSION: u8 = 1;
|
pub const VERSION: u8 = 1;
|
||||||
|
@ -13,14 +13,15 @@ pub const VERSION: u8 = 1;
|
||||||
struct TopHeader {
|
struct TopHeader {
|
||||||
magic: [u8; 3],
|
magic: [u8; 3],
|
||||||
version: u8,
|
version: u8,
|
||||||
_reserved: [u8; 2],
|
crypto_method : u8,
|
||||||
|
_reserved: u8,
|
||||||
flags: u8,
|
flags: u8,
|
||||||
msgtype: u8
|
msgtype: u8
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TopHeader {
|
impl Default for TopHeader {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
TopHeader{magic: MAGIC, version: VERSION, _reserved: [0; 2], flags: 0, msgtype: 0}
|
TopHeader{magic: MAGIC, version: VERSION, crypto_method: 0, _reserved: 0, flags: 0, msgtype: 0}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +74,21 @@ pub fn decode<'a>(data: &'a mut [u8], crypto: &mut Crypto) -> Result<(Options, M
|
||||||
if header.version != VERSION {
|
if header.version != VERSION {
|
||||||
return Err(Error::ParseError("Wrong version"));
|
return Err(Error::ParseError("Wrong version"));
|
||||||
}
|
}
|
||||||
|
if header.crypto_method != crypto.method() {
|
||||||
|
return Err(Error::CryptoError("Wrong crypto method"));
|
||||||
|
}
|
||||||
|
if crypto.method() > 0 {
|
||||||
|
if data.len() < pos + crypto.nonce_bytes() + crypto.auth_bytes() {
|
||||||
|
return Err(Error::ParseError("Truncated crypto header"));
|
||||||
|
}
|
||||||
|
let nonce = &data[pos..pos+crypto.nonce_bytes()];
|
||||||
|
pos += crypto.nonce_bytes();
|
||||||
|
let hash = &data[pos..pos+crypto.auth_bytes()];
|
||||||
|
pos += crypto.auth_bytes();
|
||||||
|
// Cheat data mutable to make the borrow checker happy
|
||||||
|
let data = unsafe { slice::from_raw_parts_mut(mem::transmute(data[pos..].as_ptr()), data.len()-pos) };
|
||||||
|
try!(crypto.decrypt(data, nonce, hash));
|
||||||
|
}
|
||||||
let mut options = Options::default();
|
let mut options = Options::default();
|
||||||
if header.flags & 0x01 > 0 {
|
if header.flags & 0x01 > 0 {
|
||||||
if data.len() < pos + 8 {
|
if data.len() < pos + 8 {
|
||||||
|
@ -82,23 +98,6 @@ pub fn decode<'a>(data: &'a mut [u8], crypto: &mut Crypto) -> Result<(Options, M
|
||||||
options.network_id = Some(id);
|
options.network_id = Some(id);
|
||||||
pos += 8;
|
pos += 8;
|
||||||
}
|
}
|
||||||
if header.flags & 0x02 > 0 {
|
|
||||||
if data.len() < pos + 40 {
|
|
||||||
return Err(Error::ParseError("Truncated options"));
|
|
||||||
}
|
|
||||||
if !crypto.is_secure() {
|
|
||||||
return Err(Error::CryptoError("Unexpected encrypted data"));
|
|
||||||
}
|
|
||||||
let nonce = &data[pos..pos+8];
|
|
||||||
pos += 8;
|
|
||||||
let hash = &data[pos..pos+32];
|
|
||||||
pos += 32;
|
|
||||||
debug!("{:?}", nonce);
|
|
||||||
debug!("{:?}", hash);
|
|
||||||
// Cheat data mutable to make the borrow checker happy
|
|
||||||
let data = unsafe { slice::from_raw_parts_mut(mem::transmute(data[pos..].as_ptr()), data.len()-pos) };
|
|
||||||
try!(crypto.decrypt(data, nonce, hash));
|
|
||||||
}
|
|
||||||
let msg = match header.msgtype {
|
let msg = match header.msgtype {
|
||||||
0 => Message::Data(&data[pos..]),
|
0 => Message::Data(&data[pos..]),
|
||||||
1 => {
|
1 => {
|
||||||
|
@ -169,15 +168,18 @@ pub fn encode(options: &Options, msg: &Message, buf: &mut [u8], crypto: &mut Cry
|
||||||
&Message::Init(_) => 2,
|
&Message::Init(_) => 2,
|
||||||
&Message::Close => 3
|
&Message::Close => 3
|
||||||
};
|
};
|
||||||
|
header.crypto_method = crypto.method();
|
||||||
if options.network_id.is_some() {
|
if options.network_id.is_some() {
|
||||||
header.flags |= 0x01;
|
header.flags |= 0x01;
|
||||||
}
|
}
|
||||||
if crypto.is_secure() {
|
|
||||||
header.flags |= 0x02;
|
|
||||||
}
|
|
||||||
let header_dat = unsafe { as_bytes(&header) };
|
let header_dat = unsafe { as_bytes(&header) };
|
||||||
unsafe { ptr::copy_nonoverlapping(header_dat.as_ptr(), buf[pos..].as_mut_ptr(), header_dat.len()) };
|
unsafe { ptr::copy_nonoverlapping(header_dat.as_ptr(), buf[pos..].as_mut_ptr(), header_dat.len()) };
|
||||||
pos += header_dat.len();
|
pos += header_dat.len();
|
||||||
|
let nonce_pos = pos;
|
||||||
|
pos += crypto.nonce_bytes();
|
||||||
|
let hash_pos = pos;
|
||||||
|
pos += crypto.auth_bytes();
|
||||||
|
let crypto_pos = pos;
|
||||||
if let Some(id) = options.network_id {
|
if let Some(id) = options.network_id {
|
||||||
assert!(buf.len() >= pos + 8);
|
assert!(buf.len() >= pos + 8);
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -186,16 +188,6 @@ pub fn encode(options: &Options, msg: &Message, buf: &mut [u8], crypto: &mut Cry
|
||||||
}
|
}
|
||||||
pos += 8;
|
pos += 8;
|
||||||
}
|
}
|
||||||
let (nonce_pos, hash_pos) = if crypto.is_secure() {
|
|
||||||
let nonce_pos = pos;
|
|
||||||
pos += 8;
|
|
||||||
let hash_pos = pos;
|
|
||||||
pos += 32;
|
|
||||||
(nonce_pos, hash_pos)
|
|
||||||
} else {
|
|
||||||
(0, 0)
|
|
||||||
};
|
|
||||||
let crypto_pos = pos;
|
|
||||||
match msg {
|
match msg {
|
||||||
&Message::Data(ref data) => {
|
&Message::Data(ref data) => {
|
||||||
assert!(buf.len() >= pos + data.len());
|
assert!(buf.len() >= pos + data.len());
|
||||||
|
@ -249,13 +241,13 @@ pub fn encode(options: &Options, msg: &Message, buf: &mut [u8], crypto: &mut Cry
|
||||||
&Message::Close => {
|
&Message::Close => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if crypto.is_secure() {
|
if crypto.method() > 0 {
|
||||||
let (nonce, hash) = crypto.encrypt(&mut buf[crypto_pos..pos]);
|
let (nonce, hash) = crypto.encrypt(&mut buf[crypto_pos..pos]);
|
||||||
assert_eq!(nonce.len(), 8);
|
assert_eq!(nonce.len(), crypto.nonce_bytes());
|
||||||
assert_eq!(hash.len(), 32);
|
assert_eq!(hash.len(), crypto.auth_bytes());
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::copy_nonoverlapping(nonce.as_ptr(), buf[nonce_pos..].as_mut_ptr(), 8);
|
ptr::copy_nonoverlapping(nonce.as_ptr(), buf[nonce_pos..].as_mut_ptr(), crypto.nonce_bytes());
|
||||||
ptr::copy_nonoverlapping(hash.as_ptr(), buf[hash_pos..].as_mut_ptr(), 32);
|
ptr::copy_nonoverlapping(hash.as_ptr(), buf[hash_pos..].as_mut_ptr(), crypto.auth_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pos
|
pos
|
||||||
|
@ -287,7 +279,7 @@ fn encode_message_encrypted() {
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
let size = encode(&mut options, &msg, &mut buf[..], &mut crypto);
|
let size = encode(&mut options, &msg, &mut buf[..], &mut crypto);
|
||||||
assert_eq!(size, 53);
|
assert_eq!(size, 53);
|
||||||
assert_eq!(&buf[..8], &[118,112,110,1,0,0,2,0]);
|
assert_eq!(&buf[..8], &[118,112,110,1,1,0,0,0]);
|
||||||
let (options2, msg2) = decode(&mut buf[..size], &mut crypto).unwrap();
|
let (options2, msg2) = decode(&mut buf[..size], &mut crypto).unwrap();
|
||||||
assert_eq!(options, options2);
|
assert_eq!(options, options2);
|
||||||
assert_eq!(msg, msg2);
|
assert_eq!(msg, msg2);
|
||||||
|
|
Loading…
Reference in New Issue