mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-25 16:36:54 +02:00
cleanup
This commit is contained in:
parent
5006580c41
commit
23e73bbdd1
6 changed files with 250 additions and 222 deletions
|
@ -15,6 +15,215 @@ pub const P384_SECRET_KEY_SIZE: usize = 48;
|
|||
pub const P384_ECDSA_SIGNATURE_SIZE: usize = 96;
|
||||
pub const P384_ECDH_SHARED_SECRET_SIZE: usize = 48;
|
||||
|
||||
// Version using OpenSSL's ECC
|
||||
#[cfg(not(target_feature = "builtin_nist_ecc"))]
|
||||
mod openssl_based {
|
||||
use std::convert::TryInto;
|
||||
use std::os::raw::{c_int, c_ulong, c_void};
|
||||
use std::ptr::{null, write_volatile};
|
||||
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use lazy_static::lazy_static;
|
||||
use openssl::bn::{BigNum, BigNumContext};
|
||||
use openssl::ec::{EcKey, EcPoint, EcPointRef, PointConversionForm};
|
||||
use openssl::ecdsa::EcdsaSig;
|
||||
use openssl::nid::Nid;
|
||||
use openssl::pkey::{Private, Public};
|
||||
|
||||
use crate::hash::SHA384;
|
||||
use crate::secret::Secret;
|
||||
|
||||
use super::{P384_ECDH_SHARED_SECRET_SIZE, P384_ECDSA_SIGNATURE_SIZE, P384_PUBLIC_KEY_SIZE, P384_SECRET_KEY_SIZE};
|
||||
|
||||
//#[link(name="crypto")]
|
||||
extern "C" {
|
||||
fn ECDH_compute_key(out: *mut c_void, outlen: c_ulong, pub_key: *mut c_void, ecdh: *mut c_void, kdf: *const c_void) -> c_int;
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref GROUP_P384: openssl::ec::EcGroup = openssl::ec::EcGroup::from_curve_name(Nid::SECP384R1).unwrap();
|
||||
}
|
||||
|
||||
/// A NIST P-384 ECDH/ECDSA public key.
|
||||
#[derive(Clone)]
|
||||
pub struct P384PublicKey {
|
||||
key: EcKey<Public>,
|
||||
bytes: [u8; 49],
|
||||
}
|
||||
|
||||
impl P384PublicKey {
|
||||
fn new_from_point(key: &EcPointRef) -> Self {
|
||||
let mut bnc = BigNumContext::new().unwrap();
|
||||
let kb = key
|
||||
.to_bytes(GROUP_P384.as_ref(), PointConversionForm::COMPRESSED, &mut bnc)
|
||||
.unwrap();
|
||||
let mut bytes = [0_u8; 49];
|
||||
bytes[(49 - kb.len())..].copy_from_slice(kb.as_slice());
|
||||
Self {
|
||||
key: EcKey::from_public_key(GROUP_P384.as_ref(), key).unwrap(),
|
||||
bytes,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_bytes(b: &[u8]) -> Option<P384PublicKey> {
|
||||
if b.len() == 49 {
|
||||
let mut bnc = BigNumContext::new().unwrap();
|
||||
let key = EcPoint::from_bytes(GROUP_P384.as_ref(), b, &mut bnc);
|
||||
if key.is_ok() {
|
||||
let key = key.unwrap();
|
||||
if key.is_on_curve(GROUP_P384.as_ref(), &mut bnc).unwrap_or(false) {
|
||||
let key = EcKey::from_public_key(GROUP_P384.as_ref(), key.as_ref());
|
||||
if key.is_ok() {
|
||||
return Some(Self { key: key.unwrap(), bytes: b.try_into().unwrap() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
pub fn verify(&self, msg: &[u8], signature: &[u8]) -> bool {
|
||||
if signature.len() == 96 {
|
||||
let r = BigNum::from_slice(&signature[0..48]);
|
||||
let s = BigNum::from_slice(&signature[48..96]);
|
||||
if r.is_ok() && s.is_ok() {
|
||||
let r = r.unwrap();
|
||||
let s = s.unwrap();
|
||||
let z = BigNum::from_u32(0).unwrap();
|
||||
// Check that r and s are >=1 just in case the OpenSSL version or an OpenSSL API lookalike is
|
||||
// vulnerable to this, since a bunch of vulnerabilities involving zero r/s just made the rounds.
|
||||
if r.gt(&z) && s.gt(&z) {
|
||||
let sig = EcdsaSig::from_private_components(r, s);
|
||||
if sig.is_ok() {
|
||||
return sig.unwrap().verify(&SHA384::hash(msg), self.key.as_ref()).unwrap_or(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> &[u8; 49] {
|
||||
&self.bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for P384PublicKey {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.bytes == other.bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for P384PublicKey {}
|
||||
|
||||
unsafe impl Sync for P384PublicKey {}
|
||||
|
||||
/// A NIST P-384 ECDH/ECDSA public/private key pair.
|
||||
#[derive(Clone)]
|
||||
pub struct P384KeyPair {
|
||||
pair: EcKey<Private>,
|
||||
public: P384PublicKey,
|
||||
}
|
||||
|
||||
impl P384KeyPair {
|
||||
pub fn generate() -> P384KeyPair {
|
||||
let pair = EcKey::generate(GROUP_P384.as_ref()).unwrap(); // failure implies a serious problem
|
||||
assert!(pair.check_key().is_ok()); // also would imply a serious problem
|
||||
let public = P384PublicKey::new_from_point(pair.public_key());
|
||||
Self { pair, public }
|
||||
}
|
||||
|
||||
pub fn from_bytes(public_bytes: &[u8], secret_bytes: &[u8]) -> Option<P384KeyPair> {
|
||||
if public_bytes.len() == 49 && secret_bytes.len() == 48 {
|
||||
P384PublicKey::from_bytes(public_bytes).map_or(None, |public| {
|
||||
BigNum::from_slice(secret_bytes).map_or(None, |private| {
|
||||
let pair = EcKey::from_private_components(GROUP_P384.as_ref(), private.as_ref(), public.key.public_key());
|
||||
if pair.is_ok() {
|
||||
let pair = pair.unwrap();
|
||||
if pair.check_key().is_ok() {
|
||||
Some(Self { pair, public })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn public_key(&self) -> &P384PublicKey {
|
||||
&self.public
|
||||
}
|
||||
|
||||
pub fn public_key_bytes(&self) -> &[u8; P384_PUBLIC_KEY_SIZE] {
|
||||
&self.public.bytes
|
||||
}
|
||||
|
||||
pub fn secret_key_bytes(&self) -> Secret<P384_SECRET_KEY_SIZE> {
|
||||
let mut tmp: Secret<P384_SECRET_KEY_SIZE> = Secret::default();
|
||||
let mut k = self.pair.private_key().to_vec();
|
||||
tmp.0[(48 - k.len())..].copy_from_slice(k.as_slice());
|
||||
unsafe {
|
||||
// Force zero memory occupied by temporary vector before releasing.
|
||||
let kp = k.as_mut_ptr();
|
||||
for i in 0..k.len() {
|
||||
write_volatile(kp.add(i), 0);
|
||||
}
|
||||
}
|
||||
tmp
|
||||
}
|
||||
|
||||
/// Sign a message with ECDSA/SHA384.
|
||||
pub fn sign(&self, msg: &[u8]) -> [u8; P384_ECDSA_SIGNATURE_SIZE] {
|
||||
let sig = EcdsaSig::sign(&SHA384::hash(msg), self.pair.as_ref()).unwrap();
|
||||
let r = sig.r().to_vec();
|
||||
let s = sig.s().to_vec();
|
||||
assert!(!r.is_empty() && !s.is_empty() && r.len() <= 48 && s.len() <= 48);
|
||||
let mut b = [0_u8; P384_ECDSA_SIGNATURE_SIZE];
|
||||
b[(48 - r.len())..48].copy_from_slice(r.as_slice());
|
||||
b[(96 - s.len())..96].copy_from_slice(s.as_slice());
|
||||
b
|
||||
}
|
||||
|
||||
/// Perform ECDH key agreement, returning the raw (un-hashed!) ECDH secret.
|
||||
///
|
||||
/// This secret should not be used directly. It should be hashed and perhaps used in a KDF.
|
||||
pub fn agree(&self, other_public: &P384PublicKey) -> Option<Secret<P384_ECDH_SHARED_SECRET_SIZE>> {
|
||||
unsafe {
|
||||
let mut s: Secret<P384_ECDH_SHARED_SECRET_SIZE> = Secret::default();
|
||||
if ECDH_compute_key(
|
||||
s.0.as_mut_ptr().cast(),
|
||||
48,
|
||||
other_public.key.public_key().as_ptr().cast(),
|
||||
self.pair.as_ptr().cast(),
|
||||
null(),
|
||||
) == 48
|
||||
{
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for P384KeyPair {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.pair.private_key().eq(other.pair.private_key()) && self.public.bytes.eq(&other.public.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for P384KeyPair {}
|
||||
|
||||
unsafe impl Send for P384KeyPair {}
|
||||
|
||||
unsafe impl Sync for P384KeyPair {}
|
||||
}
|
||||
|
||||
// This is small and relatively fast but may not be constant time and hasn't been well audited, so we don't
|
||||
// use it by default. It's left here though in case it proves useful in the future on embedded systems.
|
||||
#[cfg(target_feature = "builtin_nist_ecc")]
|
||||
|
@ -1138,215 +1347,6 @@ mod builtin {
|
|||
impl P384KeyPair {}
|
||||
}
|
||||
|
||||
// Version using OpenSSL's ECC
|
||||
#[cfg(not(target_feature = "builtin_nist_ecc"))]
|
||||
mod openssl_based {
|
||||
use std::convert::TryInto;
|
||||
use std::os::raw::{c_int, c_ulong, c_void};
|
||||
use std::ptr::{null, write_volatile};
|
||||
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use lazy_static::lazy_static;
|
||||
use openssl::bn::{BigNum, BigNumContext};
|
||||
use openssl::ec::{EcKey, EcPoint, EcPointRef, PointConversionForm};
|
||||
use openssl::ecdsa::EcdsaSig;
|
||||
use openssl::nid::Nid;
|
||||
use openssl::pkey::{Private, Public};
|
||||
|
||||
use crate::hash::SHA384;
|
||||
use crate::secret::Secret;
|
||||
|
||||
use super::{P384_ECDH_SHARED_SECRET_SIZE, P384_ECDSA_SIGNATURE_SIZE, P384_PUBLIC_KEY_SIZE, P384_SECRET_KEY_SIZE};
|
||||
|
||||
//#[link(name="crypto")]
|
||||
extern "C" {
|
||||
fn ECDH_compute_key(out: *mut c_void, outlen: c_ulong, pub_key: *mut c_void, ecdh: *mut c_void, kdf: *const c_void) -> c_int;
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref GROUP_P384: openssl::ec::EcGroup = openssl::ec::EcGroup::from_curve_name(Nid::SECP384R1).unwrap();
|
||||
}
|
||||
|
||||
/// A NIST P-384 ECDH/ECDSA public key.
|
||||
#[derive(Clone)]
|
||||
pub struct P384PublicKey {
|
||||
key: EcKey<Public>,
|
||||
bytes: [u8; 49],
|
||||
}
|
||||
|
||||
impl P384PublicKey {
|
||||
fn new_from_point(key: &EcPointRef) -> Self {
|
||||
let mut bnc = BigNumContext::new().unwrap();
|
||||
let kb = key
|
||||
.to_bytes(GROUP_P384.as_ref(), PointConversionForm::COMPRESSED, &mut bnc)
|
||||
.unwrap();
|
||||
let mut bytes = [0_u8; 49];
|
||||
bytes[(49 - kb.len())..].copy_from_slice(kb.as_slice());
|
||||
Self {
|
||||
key: EcKey::from_public_key(GROUP_P384.as_ref(), key).unwrap(),
|
||||
bytes,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_bytes(b: &[u8]) -> Option<P384PublicKey> {
|
||||
if b.len() == 49 {
|
||||
let mut bnc = BigNumContext::new().unwrap();
|
||||
let key = EcPoint::from_bytes(GROUP_P384.as_ref(), b, &mut bnc);
|
||||
if key.is_ok() {
|
||||
let key = key.unwrap();
|
||||
if key.is_on_curve(GROUP_P384.as_ref(), &mut bnc).unwrap_or(false) {
|
||||
let key = EcKey::from_public_key(GROUP_P384.as_ref(), key.as_ref());
|
||||
if key.is_ok() {
|
||||
return Some(Self { key: key.unwrap(), bytes: b.try_into().unwrap() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
pub fn verify(&self, msg: &[u8], signature: &[u8]) -> bool {
|
||||
if signature.len() == 96 {
|
||||
let r = BigNum::from_slice(&signature[0..48]);
|
||||
let s = BigNum::from_slice(&signature[48..96]);
|
||||
if r.is_ok() && s.is_ok() {
|
||||
let r = r.unwrap();
|
||||
let s = s.unwrap();
|
||||
let z = BigNum::from_u32(0).unwrap();
|
||||
// Check that r and s are >=1 just in case the OpenSSL version or an OpenSSL API lookalike is
|
||||
// vulnerable to this, since a bunch of vulnerabilities involving zero r/s just made the rounds.
|
||||
if r.gt(&z) && s.gt(&z) {
|
||||
let sig = EcdsaSig::from_private_components(r, s);
|
||||
if sig.is_ok() {
|
||||
return sig.unwrap().verify(&SHA384::hash(msg), self.key.as_ref()).unwrap_or(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> &[u8; 49] {
|
||||
&self.bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for P384PublicKey {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.bytes == other.bytes
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for P384PublicKey {}
|
||||
|
||||
unsafe impl Sync for P384PublicKey {}
|
||||
|
||||
/// A NIST P-384 ECDH/ECDSA public/private key pair.
|
||||
#[derive(Clone)]
|
||||
pub struct P384KeyPair {
|
||||
pair: EcKey<Private>,
|
||||
public: P384PublicKey,
|
||||
}
|
||||
|
||||
impl P384KeyPair {
|
||||
pub fn generate() -> P384KeyPair {
|
||||
let pair = EcKey::generate(GROUP_P384.as_ref()).unwrap(); // failure implies a serious problem
|
||||
assert!(pair.check_key().is_ok()); // also would imply a serious problem
|
||||
let public = P384PublicKey::new_from_point(pair.public_key());
|
||||
Self { pair, public }
|
||||
}
|
||||
|
||||
pub fn from_bytes(public_bytes: &[u8], secret_bytes: &[u8]) -> Option<P384KeyPair> {
|
||||
if public_bytes.len() == 49 && secret_bytes.len() == 48 {
|
||||
P384PublicKey::from_bytes(public_bytes).map_or(None, |public| {
|
||||
BigNum::from_slice(secret_bytes).map_or(None, |private| {
|
||||
let pair = EcKey::from_private_components(GROUP_P384.as_ref(), private.as_ref(), public.key.public_key());
|
||||
if pair.is_ok() {
|
||||
let pair = pair.unwrap();
|
||||
if pair.check_key().is_ok() {
|
||||
Some(Self { pair, public })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn public_key(&self) -> &P384PublicKey {
|
||||
&self.public
|
||||
}
|
||||
|
||||
pub fn public_key_bytes(&self) -> &[u8; P384_PUBLIC_KEY_SIZE] {
|
||||
&self.public.bytes
|
||||
}
|
||||
|
||||
pub fn secret_key_bytes(&self) -> Secret<P384_SECRET_KEY_SIZE> {
|
||||
let mut tmp: Secret<P384_SECRET_KEY_SIZE> = Secret::default();
|
||||
let mut k = self.pair.private_key().to_vec();
|
||||
tmp.0[(48 - k.len())..].copy_from_slice(k.as_slice());
|
||||
unsafe {
|
||||
// Force zero memory occupied by temporary vector before releasing.
|
||||
let kp = k.as_mut_ptr();
|
||||
for i in 0..k.len() {
|
||||
write_volatile(kp.add(i), 0);
|
||||
}
|
||||
}
|
||||
tmp
|
||||
}
|
||||
|
||||
/// Sign a message with ECDSA/SHA384.
|
||||
pub fn sign(&self, msg: &[u8]) -> [u8; P384_ECDSA_SIGNATURE_SIZE] {
|
||||
let sig = EcdsaSig::sign(&SHA384::hash(msg), self.pair.as_ref()).unwrap();
|
||||
let r = sig.r().to_vec();
|
||||
let s = sig.s().to_vec();
|
||||
assert!(!r.is_empty() && !s.is_empty() && r.len() <= 48 && s.len() <= 48);
|
||||
let mut b = [0_u8; P384_ECDSA_SIGNATURE_SIZE];
|
||||
b[(48 - r.len())..48].copy_from_slice(r.as_slice());
|
||||
b[(96 - s.len())..96].copy_from_slice(s.as_slice());
|
||||
b
|
||||
}
|
||||
|
||||
/// Perform ECDH key agreement, returning the raw (un-hashed!) ECDH secret.
|
||||
///
|
||||
/// This secret should not be used directly. It should be hashed and perhaps used in a KDF.
|
||||
pub fn agree(&self, other_public: &P384PublicKey) -> Option<Secret<P384_ECDH_SHARED_SECRET_SIZE>> {
|
||||
unsafe {
|
||||
let mut s: Secret<P384_ECDH_SHARED_SECRET_SIZE> = Secret::default();
|
||||
if ECDH_compute_key(
|
||||
s.0.as_mut_ptr().cast(),
|
||||
48,
|
||||
other_public.key.public_key().as_ptr().cast(),
|
||||
self.pair.as_ptr().cast(),
|
||||
null(),
|
||||
) == 48
|
||||
{
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for P384KeyPair {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.pair.private_key().eq(other.pair.private_key()) && self.public.bytes.eq(&other.public.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for P384KeyPair {}
|
||||
|
||||
unsafe impl Send for P384KeyPair {}
|
||||
|
||||
unsafe impl Sync for P384KeyPair {}
|
||||
}
|
||||
|
||||
#[cfg(target_feature = "builtin_nist_ecc")]
|
||||
pub use builtin::*;
|
||||
|
||||
|
|
|
@ -831,7 +831,7 @@ impl<'de> serde::de::Visitor<'de> for IdentityVisitor {
|
|||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
todo!()
|
||||
Identity::from_bytes(v).map_err(|e| serde::de::Error::custom(e.to_string()))
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
|
|
|
@ -239,7 +239,7 @@ impl<HostSystemImpl: HostSystem + ?Sized> Peer<HostSystemImpl> {
|
|||
};
|
||||
|
||||
let mut chunk_size = (packet_size - pos).min(UDP_DEFAULT_MTU - v1::HEADER_SIZE);
|
||||
let mut tmp_buf: [u8; v1::SIZE_MAX] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
|
||||
let mut tmp_buf = [0u8; v1::SIZE_MAX];
|
||||
loop {
|
||||
header.total_and_fragment_no += 1;
|
||||
let next_pos = pos + chunk_size;
|
||||
|
|
|
@ -7,7 +7,6 @@ use crate::vl2::NetworkId;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use zerotier_utils::arrayvec::ArrayVec;
|
||||
use zerotier_utils::blob::Blob;
|
||||
use zerotier_utils::error::InvalidParameterError;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
|
@ -34,7 +33,6 @@ pub struct CertificateOfOwnership {
|
|||
pub timestamp: i64,
|
||||
pub things: HashSet<Thing>,
|
||||
pub issued_to: Address,
|
||||
pub issued_to_fingerprint: Blob<{ Identity::FINGERPRINT_SIZE }>,
|
||||
pub signature: ArrayVec<u8, { crate::vl1::identity::IDENTITY_MAX_SIGNATURE_SIZE }>,
|
||||
pub version: u8,
|
||||
}
|
||||
|
@ -47,7 +45,6 @@ impl CertificateOfOwnership {
|
|||
timestamp,
|
||||
things: HashSet::with_capacity(4),
|
||||
issued_to,
|
||||
issued_to_fingerprint: Blob::default(),
|
||||
signature: ArrayVec::new(),
|
||||
version: if legacy_v1 {
|
||||
1
|
||||
|
@ -165,7 +162,6 @@ impl CertificateOfOwnership {
|
|||
timestamp,
|
||||
things,
|
||||
issued_to: Address::from_bytes(&b[..5]).ok_or(InvalidParameterError("invalid address"))?,
|
||||
issued_to_fingerprint: Blob::default(),
|
||||
signature: {
|
||||
let mut s = ArrayVec::new();
|
||||
s.push_slice(&b[13..109]);
|
||||
|
|
|
@ -24,7 +24,11 @@ pub struct NetworkConfig {
|
|||
pub network_id: NetworkId,
|
||||
pub issued_to: Address,
|
||||
|
||||
#[serde(skip_serializing_if = "String::is_empty")]
|
||||
#[serde(default)]
|
||||
pub name: String,
|
||||
#[serde(skip_serializing_if = "String::is_empty")]
|
||||
#[serde(default)]
|
||||
pub motd: String,
|
||||
pub private: bool,
|
||||
|
||||
|
@ -34,19 +38,39 @@ pub struct NetworkConfig {
|
|||
|
||||
pub mtu: u16,
|
||||
pub multicast_limit: u32,
|
||||
#[serde(skip_serializing_if = "HashSet::is_empty")]
|
||||
#[serde(default)]
|
||||
pub routes: HashSet<IpRoute>,
|
||||
#[serde(skip_serializing_if = "HashSet::is_empty")]
|
||||
#[serde(default)]
|
||||
pub static_ips: HashSet<InetAddress>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
#[serde(default)]
|
||||
pub rules: Vec<Rule>,
|
||||
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
||||
#[serde(default)]
|
||||
pub dns: HashMap<String, HashSet<InetAddress>>,
|
||||
|
||||
pub certificate_of_membership: Option<CertificateOfMembership>, // considered invalid if None
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
#[serde(default)]
|
||||
pub certificates_of_ownership: Vec<CertificateOfOwnership>,
|
||||
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
||||
#[serde(default)]
|
||||
pub tags: HashMap<u32, Tag>,
|
||||
|
||||
pub banned: HashSet<Address>, // v2 only
|
||||
#[serde(skip_serializing_if = "HashSet::is_empty")]
|
||||
#[serde(default)]
|
||||
pub banned: HashSet<Address>, // v2 only
|
||||
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
||||
#[serde(default)]
|
||||
pub node_info: HashMap<Address, NodeInfo>, // v2 only
|
||||
|
||||
#[serde(skip_serializing_if = "String::is_empty")]
|
||||
#[serde(default)]
|
||||
pub central_url: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(default)]
|
||||
pub sso: Option<SSOAuthConfiguration>,
|
||||
}
|
||||
|
||||
|
@ -387,8 +411,14 @@ pub struct SSOAuthConfiguration {
|
|||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct NodeInfo {
|
||||
pub flags: u64,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(default)]
|
||||
pub ip: Option<InetAddress>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(default)]
|
||||
pub name: Option<String>,
|
||||
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
||||
#[serde(default)]
|
||||
pub services: HashMap<String, Option<String>>,
|
||||
}
|
||||
|
||||
|
@ -396,6 +426,8 @@ pub struct NodeInfo {
|
|||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
pub struct IpRoute {
|
||||
pub target: InetAddress,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(default)]
|
||||
pub via: Option<InetAddress>,
|
||||
pub flags: u16,
|
||||
pub metric: u16,
|
||||
|
|
|
@ -12,11 +12,11 @@ use zerotier_utils::error::InvalidParameterError;
|
|||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Tag {
|
||||
pub id: u32,
|
||||
pub value: u32,
|
||||
pub network_id: NetworkId,
|
||||
pub timestamp: i64,
|
||||
pub issued_to: Address,
|
||||
pub id: u32,
|
||||
pub value: u32,
|
||||
pub signature: ArrayVec<u8, { identity::IDENTITY_MAX_SIGNATURE_SIZE }>,
|
||||
pub version: u8,
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ impl Tag {
|
|||
legacy_v1: bool,
|
||||
) -> Option<Self> {
|
||||
let mut tag = Self {
|
||||
id,
|
||||
value,
|
||||
network_id,
|
||||
timestamp,
|
||||
issued_to: issued_to.address,
|
||||
id,
|
||||
value,
|
||||
signature: ArrayVec::new(),
|
||||
version: if legacy_v1 {
|
||||
1
|
||||
|
@ -107,11 +107,11 @@ impl Tag {
|
|||
}
|
||||
Ok((
|
||||
Self {
|
||||
id: u32::from_be_bytes(b[16..20].try_into().unwrap()),
|
||||
value: u32::from_be_bytes(b[20..24].try_into().unwrap()),
|
||||
network_id: NetworkId::from_bytes(&b[0..8]).ok_or(InvalidParameterError("invalid network ID"))?,
|
||||
timestamp: i64::from_be_bytes(b[8..16].try_into().unwrap()),
|
||||
issued_to: Address::from_bytes(&b[24..29]).ok_or(InvalidParameterError("invalid address"))?,
|
||||
id: u32::from_be_bytes(b[16..20].try_into().unwrap()),
|
||||
value: u32::from_be_bytes(b[20..24].try_into().unwrap()),
|
||||
signature: {
|
||||
let mut s = ArrayVec::new();
|
||||
s.push_slice(&b[37..133]);
|
||||
|
|
Loading…
Add table
Reference in a new issue