From d0d34e75fd6e97e93a9adec00f4e751fb0ae976d Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 12 Dec 2022 13:37:36 -0500 Subject: [PATCH] Build fix due to base64 crate API changes. --- network-hypervisor/src/vl1/endpoint.rs | 16 +++++++--------- network-hypervisor/src/vl1/identity.rs | 10 +++++----- utils/Cargo.toml | 1 + utils/src/lib.rs | 13 +++++++++++++ 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/network-hypervisor/src/vl1/endpoint.rs b/network-hypervisor/src/vl1/endpoint.rs index 09fe2d8bd..ed43805f8 100644 --- a/network-hypervisor/src/vl1/endpoint.rs +++ b/network-hypervisor/src/vl1/endpoint.rs @@ -13,6 +13,7 @@ use crate::vl1::{Address, MAC}; use zerotier_utils::buffer::Buffer; use zerotier_utils::error::InvalidFormatError; use zerotier_utils::marshalable::{Marshalable, UnmarshalError}; +use zerotier_utils::{base64_decode_url_nopad, base64_encode_url_nopad}; pub const TYPE_NIL: u8 = 0; pub const TYPE_ZEROTIER: u8 = 1; @@ -323,7 +324,7 @@ impl ToString for Endpoint { fn to_string(&self) -> String { match self { Endpoint::Nil => format!("nil"), - Endpoint::ZeroTier(a, ah) => format!("zt:{}-{}", a.to_string(), base64::encode_config(ah, base64::URL_SAFE_NO_PAD)), + Endpoint::ZeroTier(a, ah) => format!("zt:{}-{}", a.to_string(), base64_encode_url_nopad(ah)), Endpoint::Ethernet(m) => format!("eth:{}", m.to_string()), Endpoint::WifiDirect(m) => format!("wifip2p:{}", m.to_string()), Endpoint::Bluetooth(m) => format!("bt:{}", m.to_string()), @@ -331,8 +332,8 @@ impl ToString for Endpoint { Endpoint::IpUdp(ip) => format!("udp:{}", ip.to_string()), Endpoint::IpTcp(ip) => format!("tcp:{}", ip.to_string()), Endpoint::Http(url) => format!("url:{}", url.clone()), // http or https - Endpoint::WebRTC(offer) => format!("webrtc:{}", base64::encode_config(offer.as_slice(), base64::URL_SAFE_NO_PAD)), - Endpoint::ZeroTierEncap(a, ah) => format!("zte:{}-{}", a.to_string(), base64::encode_config(ah, base64::URL_SAFE_NO_PAD)), + Endpoint::WebRTC(offer) => format!("webrtc:{}", base64_encode_url_nopad(offer.as_slice())), + Endpoint::ZeroTierEncap(a, ah) => format!("zte:{}-{}", a.to_string(), base64_encode_url_nopad(ah)), } } } @@ -355,9 +356,7 @@ impl FromStr for Endpoint { let address_and_hash = endpoint_data.split_once("-"); if address_and_hash.is_some() { let (address, hash) = address_and_hash.unwrap(); - let hash = base64::decode_config(hash, base64::URL_SAFE_NO_PAD); - if hash.is_ok() { - let hash = hash.unwrap(); + if let Some(hash) = base64_decode_url_nopad(hash) { if hash.len() == IDENTITY_FINGERPRINT_SIZE { if endpoint_type == "zt" { return Ok(Endpoint::ZeroTier(Address::from_str(address)?, hash.as_slice().try_into().unwrap())); @@ -379,9 +378,8 @@ impl FromStr for Endpoint { "tcp" => return Ok(Endpoint::IpTcp(InetAddress::from_str(endpoint_data)?)), "url" => return Ok(Endpoint::Http(endpoint_data.into())), "webrtc" => { - let offer = base64::decode_config(endpoint_data, base64::URL_SAFE_NO_PAD); - if offer.is_ok() { - return Ok(Endpoint::WebRTC(offer.unwrap())); + if let Some(offer) = base64_decode_url_nopad(endpoint_data) { + return Ok(Endpoint::WebRTC(offer)); } } _ => {} diff --git a/network-hypervisor/src/vl1/identity.rs b/network-hypervisor/src/vl1/identity.rs index ebce5fd70..0a7d5fdea 100644 --- a/network-hypervisor/src/vl1/identity.rs +++ b/network-hypervisor/src/vl1/identity.rs @@ -18,8 +18,8 @@ use zerotier_crypto::x25519::*; use zerotier_utils::arrayvec::ArrayVec; use zerotier_utils::buffer::Buffer; use zerotier_utils::error::{InvalidFormatError, InvalidParameterError}; -use zerotier_utils::hex; use zerotier_utils::marshalable::{Marshalable, UnmarshalError}; +use zerotier_utils::{base64_decode_url_nopad, base64_encode_url_nopad, hex}; use crate::protocol::{ADDRESS_SIZE, ADDRESS_SIZE_STRING, IDENTITY_POW_THRESHOLD}; use crate::vl1::Address; @@ -500,7 +500,7 @@ impl Identity { &p384.ecdsa_self_signature, &p384.ed25519_self_signature, ); - s.push_str(base64::encode_config(p384_joined, base64::URL_SAFE_NO_PAD).as_str()); + s.push_str(base64_encode_url_nopad(&p384_joined).as_str()); if self.secret.is_some() && include_private { let secret = self.secret.as_ref().unwrap(); if secret.p384.is_some() { @@ -510,7 +510,7 @@ impl Identity { p384_secret.ecdsa.secret_key_bytes().as_bytes(), ); s.push(':'); - s.push_str(base64::encode_config(p384_secret_joined, base64::URL_SAFE_NO_PAD).as_str()); + s.push_str(base64_encode_url_nopad(&p384_secret_joined).as_str()); } } } @@ -594,8 +594,8 @@ impl FromStr for Identity { let keys = [ hex::from_string(keys[0].unwrap_or("")), hex::from_string(keys[1].unwrap_or("")), - base64::decode_config(keys[2].unwrap_or(""), base64::URL_SAFE_NO_PAD).unwrap_or_else(|_| Vec::new()), - base64::decode_config(keys[3].unwrap_or(""), base64::URL_SAFE_NO_PAD).unwrap_or_else(|_| Vec::new()), + base64_decode_url_nopad(keys[2].unwrap_or("")).unwrap_or_else(|| Vec::new()), + base64_decode_url_nopad(keys[3].unwrap_or("")).unwrap_or_else(|| Vec::new()), ]; if keys[0].len() != C25519_PUBLIC_KEY_SIZE + ED25519_PUBLIC_KEY_SIZE { return Err(InvalidFormatError); diff --git a/utils/Cargo.toml b/utils/Cargo.toml index fed728f4d..1a792ed08 100644 --- a/utils/Cargo.toml +++ b/utils/Cargo.toml @@ -14,6 +14,7 @@ serde = { version = "^1", features = ["derive"], default-features = false } serde_json = { version = "^1", features = ["std"], default-features = false } tokio = { version = "^1", default-features = false, features = ["fs", "io-util", "io-std", "net", "process", "rt", "rt-multi-thread", "signal", "sync", "time"], optional = true } futures-util = { version = "^0", optional = true } +base64 = "0.20.0" [target."cfg(windows)".dependencies] winapi = { version = "^0", features = ["handleapi", "ws2ipdef", "ws2tcpip"] } diff --git a/utils/src/lib.rs b/utils/src/lib.rs index 690a8cf14..b3651a513 100644 --- a/utils/src/lib.rs +++ b/utils/src/lib.rs @@ -33,6 +33,19 @@ pub use futures_util; /// Initial value that should be used for monotonic tick time variables. pub const NEVER_HAPPENED_TICKS: i64 = 0; +const BASE64_URL_SAFE_NO_PAD_ENGINE: base64::engine::fast_portable::FastPortable = + base64::engine::fast_portable::FastPortable::from(&base64::alphabet::URL_SAFE, base64::engine::fast_portable::NO_PAD); + +/// Encode base64 using URL-safe alphabet and no padding. +pub fn base64_encode_url_nopad(bytes: &[u8]) -> String { + base64::encode_engine(bytes, &BASE64_URL_SAFE_NO_PAD_ENGINE) +} + +/// Decode base64 using URL-safe alphabet and no padding, or None on error. +pub fn base64_decode_url_nopad(b64: &str) -> Option> { + base64::decode_engine(b64, &BASE64_URL_SAFE_NO_PAD_ENGINE).ok() +} + /// Get milliseconds since unix epoch. #[inline] pub fn ms_since_epoch() -> i64 {