diff --git a/CMakeLists.txt b/CMakeLists.txt index 6419641d7..735677d42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,16 +20,6 @@ project(zerotier if(NOT PACKAGE_STATIC) - #find_program( - # GO go - # HINTS "/usr/local/go/bin" "/usr/bin" "/usr/local/bin" "C:/go/bin" - #) - #if(NOT GO) - # message(FATAL_ERROR "Golang not found") - #else(NOT GO) - # message(STATUS "Found Golang at ${GO}") - #endif(NOT GO) - set(default_build_type "Release") if(WIN32) @@ -111,11 +101,6 @@ if(NOT PACKAGE_STATIC) else(WIN32) - #set(GOFLAGS - # -trimpath - # -buildmode=pie - #) - if(APPLE) message("++ Setting MacOS Compiler Flags ${CMAKE_BUILD_TYPE}") @@ -144,12 +129,6 @@ if(NOT PACKAGE_STATIC) $<$:-flto> ) - #set(GOFLAGS - # ${GOFLAGS} - # -a - # -ldflags '-w -extldflags \"-Wl,-undefined -Wl,dynamic_lookup\"' - #) - else(APPLE) message("++ Setting Linux/BSD/Posix Compiler Flags (${CMAKE_BUILD_TYPE})") @@ -172,18 +151,11 @@ if(NOT PACKAGE_STATIC) option(BUILD_32BIT "Force building as 32-bit binary" OFF) option(BUILD_STATIC "Build statically linked executable" OFF) - option(BUILD_ARM_V5 "Build ARMv5" OFF) - option(BUILD_ARM_V6 "Build ARMv6" OFF) - - if(BUILD_ARM_V5 AND BUILD_ARM_V6) - message(FATAL_ERROR "BUILD_ARM_V5 and BUILD_ARM_V6 are mutually exclusive!") - endif(BUILD_ARM_V5 AND BUILD_ARM_V6) if(BUILD_32BIT) set(CMAKE_SYSTEM_PROCESSOR "x86" CACHE STRING "system processor") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32" CACHE STRING "c++ flags") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32" CACHE STRING "c flags") - set(GOARCH "GOARCH=386" CACHE STRING "go architecture") add_compile_options( -m32 ) @@ -194,28 +166,8 @@ if(NOT PACKAGE_STATIC) -static ) set(CMAKE_EXE_LINKER_FLAGS "-static ${CMAKE_EXE_LINKER_FLAGS}") - #set(GOFLAGS - # ${GOFLAGS} - # -a - # -tags osusergo,netgo - # -ldflags '-w -extldflags \"-static -Wl,-unresolved-symbols=ignore-all\"' - #) - else(BUILD_STATIC) - #set(GOFLAGS - # ${GOFLAGS} - # -a - # -ldflags '-w -extldflags \"-Wl,-unresolved-symbols=ignore-all\"' - #) endif(BUILD_STATIC) - if(BUILD_ARM_V5) - set(GOARM "GOARM=5") - endif(BUILD_ARM_V5) - - if(BUILD_ARM_V6) - set(GOARM "GOARM=6") - endif(BUILD_ARM_V6) - endif(APPLE) endif(WIN32) @@ -229,11 +181,8 @@ if(NOT PACKAGE_STATIC) add_compile_options(-march=armv8-a+aes+crypto -mtune=generic -mstrict-align) endif() - set(GO_BUILD_TAGS) - if(BUILD_CENTRAL_CONTROLLER) add_definitions(-DZT_CONTROLLER_USE_LIBPQ=1) - set(GO_BUILD_TAGS -tags central) endif(BUILD_CENTRAL_CONTROLLER) add_subdirectory(core) diff --git a/core/AES.hpp b/core/AES.hpp index 47ca19bbd..9a91f80a5 100644 --- a/core/AES.hpp +++ b/core/AES.hpp @@ -47,15 +47,20 @@ class AES { */ static ZT_INLINE bool accelerated() { -#ifdef ZT_AES_NO_ACCEL - return false; -#else +#ifndef ZT_AES_NO_ACCEL #ifdef ZT_AES_AESNI +#define ZT_HAVE_HW_AES_IMPL 1 return Utils::CPUID.aes; #endif #ifdef ZT_AES_NEON +#define ZT_HAVE_HW_AES_IMPL 1 return Utils::ARMCAP.aes; #endif +#ifndef ZT_HAVE_HW_AES_IMPL + return false; +#endif +#else + return false; #endif } diff --git a/core/ECC384.cpp b/core/ECC384.cpp index 257b8a9d3..8d569e2e7 100644 --- a/core/ECC384.cpp +++ b/core/ECC384.cpp @@ -65,15 +65,12 @@ ZT_INLINE unsigned int vli_numBits(const uint64_t *const p_vli) ZT_INLINE int vli_cmp(const uint64_t *const p_left, const uint64_t *const p_right) { + int comp = 0; for (int i = ECC_CURVE_DIGITS - 1; i >= 0; --i) { - if (p_left[i] > p_right[i]) { - return 1; - } - else if (p_left[i] < p_right[i]) { - return -1; - } + comp += (int)((p_left[i] > p_right[i])&&(comp == 0)); // should be constant time + comp -= (int)((p_left[i] < p_right[i])&&(comp == 0)); } - return 0; + return comp; } ZT_INLINE uint64_t vli_lshift(uint64_t *const p_result, const uint64_t *const p_in, const unsigned int p_shift) @@ -150,8 +147,8 @@ ZT_INLINE void vli_square(uint64_t *const p_result, const uint64_t *const p_left for (int k = 0; k < ECC_CURVE_DIGITS * 2 - 1; ++k) { for (int i = (k < ECC_CURVE_DIGITS ? 0 : (k + 1) - ECC_CURVE_DIGITS); i <= k && i <= k - i; ++i) { uint128_t l_product = (uint128_t)p_left[i] * p_left[k - i]; - if (i < k - i) { - r2 += l_product >> 127U; + if (i < (k - i)) { + r2 += (uint64_t)(l_product >> 127U); l_product *= 2; } r01 += l_product; diff --git a/core/InetAddress.cpp b/core/InetAddress.cpp index ab829b7f4..9ce94bc9a 100644 --- a/core/InetAddress.cpp +++ b/core/InetAddress.cpp @@ -25,10 +25,10 @@ static_assert( "ZT_SOCKADDR_STORAGE_SIZE is incorrect on this platform, must be size of sockaddr_storage"); static_assert( ZT_SOCKADDR_STORAGE_SIZE == sizeof(InetAddress), - "ZT_SOCKADDR_STORAGE_SIZE should equal InetAddress, which should equal size of sockaddr_storage"); + "ZT_SOCKADDR_STORAGE_SIZE should equal InetAddress, which must equal size of sockaddr_storage"); static_assert( ZT_SOCKADDR_STORAGE_SIZE == sizeof(ZT_InetAddress), - "ZT_SOCKADDR_STORAGE_SIZE should equal ZT_InetAddress, which should equal size of sockaddr_storage"); + "ZT_SOCKADDR_STORAGE_SIZE should equal ZT_InetAddress, which must equal size of sockaddr_storage"); const InetAddress InetAddress::LO4((const void *)("\x7f\x00\x00\x01"), 4, 0); const InetAddress diff --git a/core/MIMC52.cpp b/core/MIMC52.cpp index 16269b2af..c28a80541 100644 --- a/core/MIMC52.cpp +++ b/core/MIMC52.cpp @@ -163,10 +163,7 @@ static uint64_t mulmod64(uint64_t a, uint64_t b, const uint64_t m) * performs fairly equally across CPUs. */ ZT_INLINE uint64_t mulmod52(uint64_t a, const uint64_t b, const uint64_t m, const double mf) { - a = ((a * b) - (((uint64_t)(((double)a * (double)b) / mf) - 1) * m)); - // a -= m * (uint64_t)(a > m); // faster on some systems, but slower on newer cores - a %= m; - return a; + return ((a * b) - (((uint64_t)(((double)a * (double)b) / mf) - 1ULL) * m)) % m; } #endif diff --git a/core/OS.hpp b/core/OS.hpp index 28ed3d72f..f5a8b237d 100644 --- a/core/OS.hpp +++ b/core/OS.hpp @@ -87,12 +87,6 @@ #define ZT_ARCH_X86 1 #endif -#if !defined(ZT_ARCH_X86) -#ifndef ZT_NO_UNALIGNED_ACCESS -#define ZT_NO_UNALIGNED_ACCESS 1 -#endif -#endif - #if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(ZT_ARCH_ARM_HAS_NEON) #if (defined(__APPLE__) && !defined(__LP64__)) || (defined(__ANDROID__) && defined(__arm__)) #ifdef ZT_ARCH_ARM_HAS_NEON @@ -107,6 +101,12 @@ /*#include */ #endif +#if !defined(ZT_ARCH_X86) && !defined(__aarch64__) +#ifndef ZT_NO_UNALIGNED_ACCESS +#define ZT_NO_UNALIGNED_ACCESS 1 +#endif +#endif + #ifdef __APPLE__ #include #include diff --git a/core/zerotier.h b/core/zerotier.h index 61223a7ee..7f1eda5ed 100644 --- a/core/zerotier.h +++ b/core/zerotier.h @@ -272,6 +272,13 @@ typedef void ZT_Identity; */ typedef void ZT_Locator; +/** + * Size of sockaddr_storage. + * + * This is defined here to avoid having to import system header files + * unnecessarily. It's checked during compile with a static_assert to ensure + * that it is correct for the target. Checks are in InetAddress.cpp. + */ #define ZT_SOCKADDR_STORAGE_SIZE 128 /** diff --git a/rust-zerotier-core/Cargo.toml b/rust-zerotier-core/Cargo.toml index d866557fe..224e4e038 100644 --- a/rust-zerotier-core/Cargo.toml +++ b/rust-zerotier-core/Cargo.toml @@ -5,6 +5,12 @@ authors = ["Adam Ierymenko "] edition = "2018" build = "build.rs" +[profile.release] +opt-level = 'z' +lto = true +codegen-units = 1 +panic = 'abort' + [dependencies] num-traits = "0.2" num-derive = "0.3" diff --git a/rust-zerotier-core/src/certificate.rs b/rust-zerotier-core/src/certificate.rs index 9a59fc263..35d57c17b 100644 --- a/rust-zerotier-core/src/certificate.rs +++ b/rust-zerotier-core/src/certificate.rs @@ -31,6 +31,7 @@ pub const CERTIFICATE_MAX_STRING_LENGTH: isize = ztcore::ZT_CERTIFICATE_MAX_STRI /// Certificate local trust bit field flag: this certificate self-signs a root CA. pub const CERTIFICATE_LOCAL_TRUST_FLAG_ROOT_CA: u32 = ztcore::ZT_CERTIFICATE_LOCAL_TRUST_FLAG_ROOT_CA; +pub const CERTIFICATE_LOCAL_TRUST_FLAG_CONFIG: u32 = ztcore::ZT_CERTIFICATE_LOCAL_TRUST_FLAG_CONFIG; pub const CERTIFICATE_USAGE_DIGITAL_SIGNATURE: u64 = ztcore::ZT_CERTIFICATE_USAGE_DIGITAL_SIGNATURE as u64; pub const CERTIFICATE_USAGE_NON_REPUDIATION: u64 = ztcore::ZT_CERTIFICATE_USAGE_NON_REPUDIATION as u64; @@ -41,6 +42,7 @@ pub const CERTIFICATE_USAGE_CERTIFICATE_SIGNING: u64 = ztcore::ZT_CERTIFICATE_US pub const CERTIFICATE_USAGE_CRL_SIGNING: u64 = ztcore::ZT_CERTIFICATE_USAGE_CRL_SIGNING as u64; pub const CERTIFICATE_USAGE_EXECUTABLE_SIGNATURE: u64 = ztcore::ZT_CERTIFICATE_USAGE_EXECUTABLE_SIGNATURE as u64; pub const CERTIFICATE_USAGE_TIMESTAMPING: u64 = ztcore::ZT_CERTIFICATE_USAGE_TIMESTAMPING as u64; +pub const CERTIFICATE_USAGE_ZEROTIER_ROOT_SET: u64 = ztcore::ZT_CERTIFICATE_USAGE_ZEROTIER_ROOT_SET as u64; #[inline(always)] fn vec_to_array(v: &Vec) -> [u8; L] { @@ -54,8 +56,6 @@ fn vec_to_array(v: &Vec) -> [u8; L] { a } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq, Clone, Copy)] pub enum CertificatePublicKeyAlgorithm { None = ztcore::ZT_CertificatePublicKeyAlgorithm_ZT_CERTIFICATE_PUBLIC_KEY_ALGORITHM_NONE as isize, @@ -69,8 +69,6 @@ impl From for CertificatePublicKeyAlgorithm { } } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)] pub struct CertificateSerialNo(pub [u8; 48]); @@ -142,18 +140,19 @@ impl ToString for CertificateSerialNo { impl serde::Serialize for CertificateSerialNo { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) } } + struct CertificateSerialNoVisitor; + impl<'de> serde::de::Visitor<'de> for CertificateSerialNoVisitor { type Value = CertificateSerialNo; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("object") } - fn visit_str(self, s: &str) -> Result where E: serde::de::Error { Self::Value::new_from_string(s).map_or_else(|| { Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self)) },|serial| { Ok(serial as Self::Value) }) } + fn visit_str(self, s: &str) -> Result where E: serde::de::Error { Self::Value::new_from_string(s).map_or_else(|| { Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self)) }, |serial| { Ok(serial as Self::Value) }) } } + impl<'de> serde::Deserialize<'de> for CertificateSerialNo { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(CertificateSerialNoVisitor) } } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq, Clone, Copy)] pub enum CertificateError { None = ztcore::ZT_CertificateError_ZT_CERTIFICATE_ERROR_NONE as isize, @@ -212,18 +211,19 @@ impl> From for CertificateError { impl serde::Serialize for CertificateError { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) } } + struct CertificateErrorVisitor; + impl<'de> serde::de::Visitor<'de> for CertificateErrorVisitor { type Value = CertificateError; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("object") } fn visit_str(self, s: &str) -> Result where E: serde::de::Error { return Ok(CertificateError::from(s)); } } + impl<'de> serde::Deserialize<'de> for CertificateError { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(CertificateErrorVisitor) } } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct CertificateName { #[serde(rename = "serialNo")] @@ -310,8 +310,6 @@ impl CertificateName { } } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct CertificateNetwork { pub id: NetworkId, @@ -343,7 +341,7 @@ impl CertificateNetwork { controller: ztcore::ZT_Fingerprint { address: 0, hash: [0_u8; 48], - } + }, } }, |controller| { ztcore::ZT_Certificate_Network { @@ -357,8 +355,6 @@ impl CertificateNetwork { } } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct CertificateIdentity { pub identity: Identity, @@ -384,8 +380,6 @@ impl CertificateIdentity { } } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct CertificateSubject { pub timestamp: i64, @@ -559,8 +553,6 @@ impl CertificateSubject { } } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct Certificate { #[serde(rename = "serialNo")] @@ -740,8 +732,6 @@ impl Certificate { } } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #[cfg(test)] mod tests { use crate::*; @@ -760,11 +750,11 @@ mod tests { let (_, unique_id_private) = Certificate::new_key_pair(CertificatePublicKeyAlgorithm::ECDSANistP384).ok().unwrap(); let id0 = Identity::new_generate(IdentityType::Curve25519).ok().unwrap(); - let mut cert = Certificate{ + let mut cert = Certificate { serial_no: CertificateSerialNo::new(), usage_flags: 1, timestamp: 2, - validity: [ 1,10 ], + validity: [1, 10], subject: CertificateSubject::new(), issuer: CertificateSerialNo::new(), issuer_public_key: issuer_pubk, @@ -772,21 +762,21 @@ mod tests { subject_signature: Vec::new(), extended_attributes: Vec::new(), max_path_length: 123, - signature: Vec::new() + signature: Vec::new(), }; cert.serial_no.0[1] = 99; cert.issuer.0[1] = 199; cert.subject.timestamp = 5; - cert.subject.identities.push(CertificateIdentity{ + cert.subject.identities.push(CertificateIdentity { identity: id0.clone(), - locator: None + locator: None, }); - cert.subject.networks.push(CertificateNetwork{ + cert.subject.networks.push(CertificateNetwork { id: NetworkId(0xdeadbeef), - controller: Some(id0.fingerprint()) + controller: Some(id0.fingerprint()), }); cert.subject.update_urls.push(String::from("http://foo.bar")); - cert.subject.name = CertificateName{ + cert.subject.name = CertificateName { serial_no: String::from("12345"), common_name: String::from("foo"), country: String::from("bar"), @@ -798,7 +788,7 @@ mod tests { postal_code: String::from("postal code"), email: String::from("nobody@nowhere.org"), url: String::from("https://www.zerotier.com/"), - host: String::from("zerotier.com") + host: String::from("zerotier.com"), }; unsafe { diff --git a/service/Cargo.toml b/service/Cargo.toml index 680fd1613..114a34aa8 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -5,7 +5,11 @@ authors = ["Adam Ierymenko "] edition = "2018" build = "build.rs" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +opt-level = 'z' +lto = true +codegen-units = 1 +panic = 'abort' [dependencies] zerotier-core = { path = "../rust-zerotier-core" } diff --git a/service/src/commands/cert.rs b/service/src/commands/cert.rs index 5094dfd14..e23407eed 100644 --- a/service/src/commands/cert.rs +++ b/service/src/commands/cert.rs @@ -34,6 +34,7 @@ fn cert_usage_flags_to_string(flags: u64) -> String { (CERTIFICATE_USAGE_CRL_SIGNING, "r"), (CERTIFICATE_USAGE_EXECUTABLE_SIGNATURE, "x"), (CERTIFICATE_USAGE_TIMESTAMPING, "t"), + (CERTIFICATE_USAGE_ZEROTIER_ROOT_SET, "z"), ].iter() { if (flags & (*f).0) != 0 { if !flags_str.is_empty() { @@ -58,6 +59,7 @@ fn cert_string_to_usage_flags(flags_str: &str) -> u64 { 'r' => CERTIFICATE_USAGE_CRL_SIGNING, 'x' => CERTIFICATE_USAGE_EXECUTABLE_SIGNATURE, 't' => CERTIFICATE_USAGE_TIMESTAMPING, + 'z' => CERTIFICATE_USAGE_ZEROTIER_ROOT_SET, _ => 0, } } diff --git a/service/src/main.rs b/service/src/main.rs index 35e2252bf..b27e73413 100644 --- a/service/src/main.rs +++ b/service/src/main.rs @@ -135,6 +135,7 @@ Advanced Operations: r Usage: CRL signing (CA) x Usage: executable signing t Usage: timestamping + z Usage: ZeroTier root set -t Timestamp (default: current time) -s Start time (default: timestamp) -l <#y|d|h|m|s... (ex: 1y, 3d12h)> Time to live (default: forever)