mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-03 19:13:43 +02:00
Build and test fixes.
This commit is contained in:
parent
9c64f262a3
commit
7318a188b2
18 changed files with 73 additions and 65 deletions
|
@ -4,8 +4,8 @@ version = "0.1.0"
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
rand_core = "^0"
|
||||
rand_core = "0.5"
|
||||
aes-gmac-siv = { path = "../aes-gmac-siv" }
|
||||
gcrypt = "^0"
|
||||
x25519-dalek = { version = "^1", features = ["u64_backend"] }
|
||||
ed25519-dalek = { version = "^1", features = ["u64_backend"] }
|
||||
gcrypt = "0.7.0"
|
||||
x25519-dalek = { version = "1.2.0", features = ["u64_backend"] }
|
||||
ed25519-dalek = { version = "1.0.1", features = ["u64_backend"] }
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use crate::hash::{SHA384, SHA512};
|
||||
|
@ -24,7 +23,7 @@ fn hash_int_le(sha: &mut SHA512, i: u64) {
|
|||
/// Compute balloon memory-hard hash using SHA-512 and SHA-384 for the final.
|
||||
/// SPACE_COST must be a multiple of 64. This is checked with an assertion.
|
||||
/// DELTA is usually 3.
|
||||
pub fn hash<const SPACE_COST: usize, const TIME_COST: usize, const DELTA: usize>(password: &[u8], salt: &[u8]) -> [u8; crate::crypto::hash::SHA384_HASH_SIZE] {
|
||||
pub fn hash<const SPACE_COST: usize, const TIME_COST: usize, const DELTA: usize>(password: &[u8], salt: &[u8]) -> [u8; crate::hash::SHA384_HASH_SIZE] {
|
||||
debug_assert_ne!(SPACE_COST, 0);
|
||||
debug_assert_ne!(TIME_COST, 0);
|
||||
debug_assert_ne!(DELTA, 0);
|
||||
|
@ -129,7 +128,7 @@ mod tests {
|
|||
let start = std::time::SystemTime::now();
|
||||
let mut tmp = 0_u8;
|
||||
for _ in 0..100 {
|
||||
let foo = crate::crypto::balloon::hash::<16384, 3, 3>(&[1_u8], &[2_u8]);
|
||||
let foo = crate::balloon::hash::<16384, 3, 3>(&[1_u8], &[2_u8]);
|
||||
tmp = tmp.wrapping_add(foo[0]);
|
||||
}
|
||||
let duration = std::time::SystemTime::now().duration_since(start).unwrap();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
pub(crate) const HEX_CHARS: [u8; 16] = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd', b'e', b'f'];
|
||||
pub const HEX_CHARS: [u8; 16] = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd', b'e', b'f'];
|
||||
|
||||
/// Encode a byte slice to a hexadecimal string.
|
||||
pub fn to_string(b: &[u8]) -> String {
|
|
@ -15,6 +15,7 @@ pub mod balloon;
|
|||
pub mod kbkdf;
|
||||
pub mod random;
|
||||
pub mod secret;
|
||||
pub mod hex;
|
||||
|
||||
pub use aes_gmac_siv;
|
||||
pub use rand_core;
|
||||
|
|
|
@ -27,7 +27,7 @@ fn dump_sexp(exp: &SExpression) {
|
|||
} else {
|
||||
let b = exp.get_bytes(0);
|
||||
if b.is_some() {
|
||||
print!("#{}#", crate::util::hex::to_string(b.unwrap()));
|
||||
print!("#{}#", crate::hex::to_string(b.unwrap()));
|
||||
} else {
|
||||
print!("()");
|
||||
}
|
||||
|
@ -51,14 +51,14 @@ fn dump_sexp(exp: &SExpression) {
|
|||
|
||||
#[inline(always)]
|
||||
fn hash_to_data_sexp(msg: &[u8]) -> [u8; 155] {
|
||||
let h = crate::crypto::hash::SHA512::hash(msg);
|
||||
let h = crate::hash::SHA512::hash(msg);
|
||||
let mut d = [0_u8; 155];
|
||||
d[0..24].copy_from_slice(b"(data(flags raw)(value #");
|
||||
let mut j = 24;
|
||||
for i in 0..64 {
|
||||
let b = h[i] as usize;
|
||||
d[j] = crate::util::hex::HEX_CHARS[b >> 4];
|
||||
d[j + 1] = crate::util::hex::HEX_CHARS[b & 0xf];
|
||||
d[j] = crate::hex::HEX_CHARS[b >> 4];
|
||||
d[j + 1] = crate::hex::HEX_CHARS[b & 0xf];
|
||||
j += 2;
|
||||
}
|
||||
d[152..155].copy_from_slice(b"#))");
|
||||
|
@ -107,8 +107,8 @@ impl P521KeyPair {
|
|||
public_key: pk_exp,
|
||||
public_key_bytes: [0_u8; P521_PUBLIC_KEY_SIZE],
|
||||
},
|
||||
secret_key_for_ecdsa: SExpression::from_str(format!("(private-key(ecc(curve nistp521)(q #{}#)(d #{}#)))", crate::util::hex::to_string(pk), crate::util::hex::to_string(sk)).as_str()).unwrap(),
|
||||
secret_key_for_ecdh: SExpression::from_str(format!("(data(flags raw)(value #{}#))", crate::util::hex::to_string(sk)).as_str()).unwrap(),
|
||||
secret_key_for_ecdsa: SExpression::from_str(format!("(private-key(ecc(curve nistp521)(q #{}#)(d #{}#)))", crate::hex::to_string(pk), crate::hex::to_string(sk)).as_str()).unwrap(),
|
||||
secret_key_for_ecdh: SExpression::from_str(format!("(data(flags raw)(value #{}#))", crate::hex::to_string(sk)).as_str()).unwrap(),
|
||||
secret_key_bytes: Secret::default(),
|
||||
};
|
||||
kp.public_key.public_key_bytes[((P521_PUBLIC_KEY_SIZE + 1) - pk.len())..P521_PUBLIC_KEY_SIZE].copy_from_slice(&pk[1..]);
|
||||
|
@ -132,8 +132,8 @@ impl P521KeyPair {
|
|||
}
|
||||
Some(P521KeyPair {
|
||||
public_key: public_key.unwrap(),
|
||||
secret_key_for_ecdsa: SExpression::from_str(format!("(private-key(ecc(curve nistp521)(q #04{}#)(d #{}#)))", crate::util::hex::to_string(public_bytes), crate::util::hex::to_string(secret_bytes)).as_str()).unwrap(),
|
||||
secret_key_for_ecdh: SExpression::from_str(format!("(data(flags raw)(value #{}#))", crate::util::hex::to_string(secret_bytes)).as_str()).unwrap(),
|
||||
secret_key_for_ecdsa: SExpression::from_str(format!("(private-key(ecc(curve nistp521)(q #04{}#)(d #{}#)))", crate::hex::to_string(public_bytes), crate::hex::to_string(secret_bytes)).as_str()).unwrap(),
|
||||
secret_key_for_ecdh: SExpression::from_str(format!("(data(flags raw)(value #{}#))", crate::hex::to_string(secret_bytes)).as_str()).unwrap(),
|
||||
secret_key_bytes: Secret::from_bytes(secret_bytes),
|
||||
})
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ impl P521PublicKey {
|
|||
pub fn from_bytes(b: &[u8]) -> Option<P521PublicKey> {
|
||||
if b.len() == P521_PUBLIC_KEY_SIZE {
|
||||
Some(P521PublicKey {
|
||||
public_key: SExpression::from_str(format!("(public-key(ecc(curve nistp521)(q #04{}#)))", crate::util::hex::to_string(b)).as_str()).unwrap(),
|
||||
public_key: SExpression::from_str(format!("(public-key(ecc(curve nistp521)(q #04{}#)))", crate::hex::to_string(b)).as_str()).unwrap(),
|
||||
public_key_bytes: b.try_into().unwrap(),
|
||||
})
|
||||
} else {
|
||||
|
@ -201,7 +201,7 @@ impl P521PublicKey {
|
|||
pub fn verify(&self, msg: &[u8], signature: &[u8]) -> bool {
|
||||
if signature.len() == P521_ECDSA_SIGNATURE_SIZE {
|
||||
let data = SExpression::from_str(unsafe { std::str::from_utf8_unchecked(&hash_to_data_sexp(msg)) }).unwrap();
|
||||
let sig = SExpression::from_str(format!("(sig-val(ecdsa(r #{}#)(s #{}#)))", crate::util::hex::to_string(&signature[0..66]), crate::util::hex::to_string(&signature[66..132])).as_str()).unwrap();
|
||||
let sig = SExpression::from_str(format!("(sig-val(ecdsa(r #{}#)(s #{}#)))", crate::hex::to_string(&signature[0..66]), crate::hex::to_string(&signature[66..132])).as_str()).unwrap();
|
||||
gcrypt::pkey::verify(&self.public_key, &data, &sig).is_ok()
|
||||
} else {
|
||||
false
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
* https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
use rand_core::{RngCore, Error};
|
||||
use rand_core::CryptoRng;
|
||||
use gcrypt::rand::{Level, randomize};
|
||||
|
||||
/// Secure random source based on the desired third party library (gcrypt).
|
||||
|
@ -18,7 +16,7 @@ impl SecureRandom {
|
|||
pub fn get() -> Self { Self }
|
||||
}
|
||||
|
||||
impl RngCore for SecureRandom {
|
||||
impl rand_core::RngCore for SecureRandom {
|
||||
#[inline(always)]
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
let mut tmp = 0_u32;
|
||||
|
@ -37,13 +35,13 @@ impl RngCore for SecureRandom {
|
|||
fn fill_bytes(&mut self, dest: &mut [u8]) { randomize(Level::Strong, dest); }
|
||||
|
||||
#[inline(always)]
|
||||
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
|
||||
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
|
||||
randomize(Level::Strong, dest);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl CryptoRng for SecureRandom {}
|
||||
impl rand_core::CryptoRng for SecureRandom {}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn next_u32_secure() -> u32 {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::mem::size_of;
|
||||
use std::ptr::write_volatile;
|
||||
|
||||
/// Container for secrets that clears them on drop.
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
* https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
pub mod hex;
|
||||
pub mod pool;
|
||||
pub mod gate;
|
||||
pub mod varint;
|
||||
|
||||
pub use zerotier_core_crypto::hex;
|
||||
|
||||
pub(crate) const ZEROES: [u8; 64] = [0_u8; 64];
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
use std::mem::size_of;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
|
|
|
@ -7,55 +7,59 @@
|
|||
*/
|
||||
|
||||
use std::io::{Read, Write};
|
||||
use crate::vl1::buffer::Buffer;
|
||||
|
||||
/// Write a variable length integer, which can consume up to 10 bytes.
|
||||
pub fn write<W: Write>(w: &mut W, mut v: u64) -> std::io::Result<()> {
|
||||
let mut b = [0_u8; 10];
|
||||
let mut i = 10;
|
||||
let mut i = 0;
|
||||
loop {
|
||||
if v > 0x7f {
|
||||
i -= 1;
|
||||
b[i] = (v as u8) & 0x7f;
|
||||
v >>= 7;
|
||||
i += 1;
|
||||
v = v.wrapping_shr(7);
|
||||
} else {
|
||||
i -= 1;
|
||||
b[i] = (v as u8) | 0x80;
|
||||
i += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
w.write_all(&b[i..])
|
||||
w.write_all(&b[0..i])
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(r: &mut R) -> std::io::Result<u64> {
|
||||
/// Read a variable length integer, returning the value and the number of bytes written.
|
||||
pub fn read<R: Read>(r: &mut R) -> std::io::Result<(u64, usize)> {
|
||||
let mut v = 0_u64;
|
||||
let mut buf = [0_u8; 1];
|
||||
let mut pos = 0;
|
||||
let mut i = 0_usize;
|
||||
loop {
|
||||
v <<= 7;
|
||||
let _ = r.read_exact(&mut buf)?;
|
||||
let b = buf[0];
|
||||
i += 1;
|
||||
if b <= 0x7f {
|
||||
v |= b as u64;
|
||||
v |= (b as u64).wrapping_shl(pos);
|
||||
pos += 7;
|
||||
} else {
|
||||
v |= (b & 0x7f) as u64;
|
||||
return Ok(v);
|
||||
v |= ((b & 0x7f) as u64).wrapping_shl(pos);
|
||||
return Ok((v, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn read_from_bytes(r: &[u8], cursor: &mut usize) -> std::io::Result<u64> {
|
||||
let mut v = 0_u64;
|
||||
let mut c = *cursor;
|
||||
while c < r.len() {
|
||||
v <<= 7;
|
||||
let b = unsafe { *r.get_unchecked(c) };
|
||||
c += 1;
|
||||
if b <= 0x7f {
|
||||
v |= b as u64;
|
||||
} else {
|
||||
v |= (b & 0x7f) as u64;
|
||||
*cursor = c;
|
||||
return Ok(v);
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::util::varint::*;
|
||||
|
||||
#[test]
|
||||
fn varint() {
|
||||
let mut t: Vec<u8> = Vec::new();
|
||||
for i in 0..131072 {
|
||||
t.clear();
|
||||
let ii = (u64::MAX / 131072) * i;
|
||||
assert!(write(&mut t, ii).is_ok());
|
||||
let mut t2 = t.as_slice();
|
||||
assert_eq!(read(&mut t2).unwrap().0, ii);
|
||||
}
|
||||
}
|
||||
*cursor = c;
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "incomplete varint"));
|
||||
}
|
||||
|
|
|
@ -106,6 +106,9 @@ impl<const L: usize> Buffer<L> {
|
|||
#[inline(always)]
|
||||
pub unsafe fn set_size_unchecked(&mut self, s: usize) { self.0 = s; }
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn get_unchecked(&self, i: usize) -> u8 { *self.1.get_unchecked(i) }
|
||||
|
||||
/// Append a packed structure and call a function to initialize it in place.
|
||||
/// Anything not initialized will be zero.
|
||||
#[inline(always)]
|
||||
|
@ -327,7 +330,11 @@ impl<const L: usize> Buffer<L> {
|
|||
/// Get the next variable length integer and advance the cursor by its length in bytes.
|
||||
#[inline(always)]
|
||||
pub fn read_varint(&self, cursor: &mut usize) -> std::io::Result<u64> {
|
||||
crate::util::varint::read_from_bytes(&(self.1[self.0..]), cursor)
|
||||
let mut a = &self.1[*cursor..];
|
||||
crate::util::varint::read(&mut a).map(|r| {
|
||||
*cursor += r.1;
|
||||
r.0
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the next u8 and advance the cursor.
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::util::hex::HEX_CHARS;
|
|||
/// It also supports binary keys and values which will be minimally escaped but render the result not
|
||||
/// entirely human readable. Keys are serialized in natural sort order so the result can be consistently
|
||||
/// checksummed or hashed.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Dictionary(BTreeMap<String, Vec<u8>>);
|
||||
|
||||
fn write_escaped<W: Write>(b: &[u8], w: &mut W) -> std::io::Result<()> {
|
||||
|
|
|
@ -306,9 +306,9 @@ impl Identity {
|
|||
/// Verify a signature.
|
||||
pub fn verify(&self, msg: &[u8], signature: &[u8]) -> bool {
|
||||
self.v1.as_ref().map_or_else(|| {
|
||||
crate::crypto::c25519::ed25519_verify(&self.ed25519, signature, msg)
|
||||
zerotier_core_crypto::c25519::ed25519_verify(&self.ed25519, signature, msg)
|
||||
}, |p521| {
|
||||
signature.len() == IDENTITY_TYPE_1_SIGNATURE_SIZE && (*p521).1.verify(msg, &signature[0..P521_ECDSA_SIGNATURE_SIZE]) && crate::crypto::c25519::ed25519_verify(&self.ed25519, &signature[P521_ECDSA_SIGNATURE_SIZE..], msg)
|
||||
signature.len() == IDENTITY_TYPE_1_SIGNATURE_SIZE && (*p521).1.verify(msg, &signature[0..P521_ECDSA_SIGNATURE_SIZE]) && zerotier_core_crypto::c25519::ed25519_verify(&self.ed25519, &signature[P521_ECDSA_SIGNATURE_SIZE..], msg)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -92,11 +92,13 @@ impl Locator {
|
|||
self.subject.marshal(buf)?;
|
||||
self.signer.marshal(buf)?;
|
||||
buf.append_varint(self.timestamp as u64)?;
|
||||
self.metadata.map_or_else(|| buf.append_varint(0), |d| {
|
||||
let db = d.to_bytes();
|
||||
if self.metadata.is_none() {
|
||||
buf.append_varint(0)?;
|
||||
} else {
|
||||
let db = self.metadata.as_ref().unwrap().to_bytes();
|
||||
buf.append_varint(db.len() as u64)?;
|
||||
buf.append_bytes(db.as_slice())
|
||||
})?;
|
||||
buf.append_bytes(db.as_slice())?;
|
||||
}
|
||||
buf.append_varint(self.endpoints.len() as u64)?;
|
||||
for e in self.endpoints.iter() {
|
||||
e.marshal(buf)?;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicI64, AtomicU64, AtomicU8, Ordering};
|
||||
|
@ -449,7 +448,7 @@ impl Peer {
|
|||
|
||||
let aes_ctr_iv_position = packet.len();
|
||||
debug_assert!(packet.append_and_init_bytes_fixed(|iv: &mut [u8; 18]| {
|
||||
crate::crypto::random::fill_bytes_secure(&mut iv[0..16]);
|
||||
zerotier_core_crypto::random::fill_bytes_secure(&mut iv[0..16]);
|
||||
iv[12] &= 0x7f; // mask off MSB of counter in iv to play nice with some AES-CTR implementations
|
||||
|
||||
// LEGACY: create a 16-bit encrypted field that specifies zero moons. This is ignored by v2
|
||||
|
|
|
@ -177,7 +177,7 @@ pub fn compress_packet(src: &[u8], dest: &mut Buffer<{ PACKET_SIZE_MAX }>) -> bo
|
|||
let d = dest.as_bytes_mut();
|
||||
d[0..PACKET_VERB_INDEX].copy_from_slice(&src[0..PACKET_VERB_INDEX]);
|
||||
d[PACKET_VERB_INDEX] = src[PACKET_VERB_INDEX] | VERB_FLAG_COMPRESSED;
|
||||
lz4_flex::block::compress_into(&src[PACKET_VERB_INDEX + 1..], d, PACKET_VERB_INDEX + 1)
|
||||
lz4_flex::block::compress_into(&src[PACKET_VERB_INDEX + 1..], &mut d[PACKET_VERB_INDEX + 1..])
|
||||
};
|
||||
if cs.is_ok() {
|
||||
let cs = cs.unwrap();
|
||||
|
@ -193,7 +193,7 @@ pub fn compress_packet(src: &[u8], dest: &mut Buffer<{ PACKET_SIZE_MAX }>) -> bo
|
|||
/// Add HMAC-SHA384 to the end of a packet and set verb flag.
|
||||
#[inline(always)]
|
||||
pub fn add_extended_auth(pkt: &mut Buffer<{ PACKET_SIZE_MAX }>, hmac_secret_key: &[u8]) -> std::io::Result<()> {
|
||||
pkt.append_bytes_fixed(&ztcrypto::hash::SHA384::hmac(hmac_secret_key, pkt.as_bytes_starting_at(PACKET_VERB_INDEX + 1)?))?;
|
||||
pkt.append_bytes_fixed(&zerotier_core_crypto::hash::SHA384::hmac(hmac_secret_key, pkt.as_bytes_starting_at(PACKET_VERB_INDEX + 1)?))?;
|
||||
pkt.as_bytes_mut()[PACKET_VERB_INDEX] |= VERB_FLAG_EXTENDED_AUTHENTICATION;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ use zerotier_core_crypto::hash::SHA384;
|
|||
use zerotier_core_crypto::p521::*;
|
||||
use zerotier_core_crypto::secret::Secret;
|
||||
|
||||
use crate::error::InvalidFormatError;
|
||||
use crate::vl1::{Endpoint, Identity};
|
||||
use crate::vl1::buffer::Buffer;
|
||||
use crate::vl1::protocol::PACKET_SIZE_MAX;
|
||||
|
|
2
zerotier-system-service/Cargo.lock
generated
2
zerotier-system-service/Cargo.lock
generated
|
@ -1298,7 +1298,7 @@ dependencies = [
|
|||
"aes-gmac-siv",
|
||||
"ed25519-dalek",
|
||||
"gcrypt",
|
||||
"rand_core 0.6.3",
|
||||
"rand_core 0.5.1",
|
||||
"x25519-dalek",
|
||||
]
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue