From da6c7bc1b84071fd99269d1706ec8848b722e230 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 12 Jan 2023 18:34:15 +0100 Subject: [PATCH] feat: Switch from base64 to data-encoding --- Cargo.lock | 9 +++--- relay-auth/Cargo.toml | 2 +- relay-auth/src/lib.rs | 43 ++++++++++++----------------- relay-profiling/Cargo.toml | 2 +- relay-profiling/src/android.rs | 3 +- relay-server/Cargo.toml | 12 ++------ relay-server/src/body/store_body.rs | 6 ++-- 7 files changed, 32 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88766db9b3f..020d5a03fdb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -891,9 +891,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" [[package]] name = "debugid" @@ -3163,8 +3163,8 @@ dependencies = [ name = "relay-auth" version = "22.11.0" dependencies = [ - "base64 0.10.1", "chrono", + "data-encoding", "ed25519-dalek", "hmac", "rand 0.6.5", @@ -3393,6 +3393,7 @@ dependencies = [ "base64 0.10.1", "bytes 0.4.12", "chrono", + "data-encoding", "relay-general", "serde", "serde_json", @@ -3466,11 +3467,11 @@ version = "22.11.0" dependencies = [ "actix", "actix-web", - "base64 0.10.1", "brotli2", "bytes 0.4.12", "chrono", "clap", + "data-encoding", "failure", "flate2", "fragile", diff --git a/relay-auth/Cargo.toml b/relay-auth/Cargo.toml index 9f01dfb1dbd..3486697e066 100644 --- a/relay-auth/Cargo.toml +++ b/relay-auth/Cargo.toml @@ -11,7 +11,6 @@ publish = false build = "build.rs" [dependencies] -base64 = "0.10.1" chrono = "0.4.11" ed25519-dalek = "0.9.1" thiserror = "1.0.24" @@ -21,3 +20,4 @@ relay-common = { path = "../relay-common" } serde = { version = "1.0.114", features = ["derive"] } serde_json = "1.0.55" sha2 = "0.8.1" +data-encoding = "2.3.3" diff --git a/relay-auth/src/lib.rs b/relay-auth/src/lib.rs index 18c72db7e33..274922f3cb5 100644 --- a/relay-auth/src/lib.rs +++ b/relay-auth/src/lib.rs @@ -7,6 +7,7 @@ use std::fmt; use std::str::FromStr; use chrono::{DateTime, Duration, TimeZone, Utc}; +use data_encoding::BASE64URL_NOPAD; use hmac::{Hmac, Mac}; use rand::{rngs::OsRng, thread_rng, RngCore}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -201,11 +202,11 @@ impl SecretKey { pub fn sign_with_header(&self, data: &[u8], header: &SignatureHeader) -> String { let mut header = serde_json::to_vec(&header).expect("attempted to pack non json safe header"); - let header_encoded = base64::encode_config(&header[..], base64::URL_SAFE_NO_PAD); + let header_encoded = BASE64URL_NOPAD.encode(&header); header.push(b'\x00'); header.extend_from_slice(data); let sig = self.inner.sign::(&header); - let mut sig_encoded = base64::encode_config(&sig.to_bytes()[..], base64::URL_SAFE_NO_PAD); + let mut sig_encoded = BASE64URL_NOPAD.encode(&sig.to_bytes()); sig_encoded.push('.'); sig_encoded.push_str(&header_encoded); sig_encoded @@ -242,7 +243,7 @@ impl FromStr for SecretKey { type Err = KeyParseError; fn from_str(s: &str) -> Result { - let bytes = match base64::decode_config(s, base64::URL_SAFE_NO_PAD) { + let bytes = match BASE64URL_NOPAD.decode(s.as_bytes()) { Ok(bytes) => bytes, _ => return Err(KeyParseError::BadEncoding), }; @@ -263,16 +264,12 @@ impl FromStr for SecretKey { impl fmt::Display for SecretKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { - write!( - f, - "{}", - base64::encode_config(&self.inner.to_bytes()[..], base64::URL_SAFE_NO_PAD) - ) + write!(f, "{}", BASE64URL_NOPAD.encode(&self.inner.to_bytes())) } else { write!( f, "{}", - base64::encode_config(&self.inner.secret.to_bytes()[..], base64::URL_SAFE_NO_PAD) + BASE64URL_NOPAD.encode(&self.inner.secret.to_bytes()) ) } } @@ -292,17 +289,13 @@ impl PublicKey { pub fn verify_meta(&self, data: &[u8], sig: &str) -> Option { let mut iter = sig.splitn(2, '.'); let sig_bytes = match iter.next() { - Some(sig_encoded) => { - base64::decode_config(sig_encoded, base64::URL_SAFE_NO_PAD).ok()? - } + Some(sig_encoded) => BASE64URL_NOPAD.decode(sig_encoded.as_bytes()).ok()?, None => return None, }; let sig = ed25519_dalek::Signature::from_bytes(&sig_bytes).ok()?; let header = match iter.next() { - Some(header_encoded) => { - base64::decode_config(header_encoded, base64::URL_SAFE_NO_PAD).ok()? - } + Some(header_encoded) => BASE64URL_NOPAD.decode(header_encoded.as_bytes()).ok()?, None => return None, }; let mut to_verify = header.clone(); @@ -373,7 +366,7 @@ impl FromStr for PublicKey { type Err = KeyParseError; fn from_str(s: &str) -> Result { - let bytes = match base64::decode_config(s, base64::URL_SAFE_NO_PAD) { + let bytes = match BASE64URL_NOPAD.decode(s.as_bytes()) { Ok(bytes) => bytes, _ => return Err(KeyParseError::BadEncoding), }; @@ -386,11 +379,7 @@ impl FromStr for PublicKey { impl fmt::Display for PublicKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{}", - base64::encode_config(&self.inner.to_bytes()[..], base64::URL_SAFE_NO_PAD) - ) + write!(f, "{}", BASE64URL_NOPAD.encode(&self.inner.to_bytes())) } } @@ -445,11 +434,11 @@ impl SignedRegisterState { /// Signs the given `RegisterState` and serializes it into a single string. fn sign(state: RegisterState, secret: &[u8]) -> Self { let json = serde_json::to_string(&state).expect("relay register state serializes to JSON"); - let token = base64::encode_config(&json, base64::URL_SAFE_NO_PAD); + let token = BASE64URL_NOPAD.encode(json.as_bytes()); let mut mac = Self::mac(secret); mac.input(token.as_bytes()); - let signature = base64::encode_config(&mac.result().code(), base64::URL_SAFE_NO_PAD); + let signature = BASE64URL_NOPAD.encode(&mac.result().code()); Self(format!("{}:{}", token, signature)) } @@ -475,14 +464,16 @@ impl SignedRegisterState { max_age: Option, ) -> Result { let (token, signature) = self.split(); - let code = base64::decode_config(signature, base64::URL_SAFE_NO_PAD) + let code = BASE64URL_NOPAD + .decode(signature.as_bytes()) .map_err(|_| UnpackError::BadEncoding)?; let mut mac = Self::mac(secret); mac.input(token.as_bytes()); mac.verify(&code).map_err(|_| UnpackError::BadSignature)?; - let json = base64::decode_config(token, base64::URL_SAFE_NO_PAD) + let json = BASE64URL_NOPAD + .decode(token.as_bytes()) .map_err(|_| UnpackError::BadEncoding)?; let state = serde_json::from_slice::(&json).map_err(UnpackError::BadPayload)?; @@ -539,7 +530,7 @@ fn nonce() -> String { let mut rng = thread_rng(); let mut bytes = vec![0u8; 64]; rng.fill_bytes(&mut bytes); - base64::encode_config(&bytes, base64::URL_SAFE_NO_PAD) + BASE64URL_NOPAD.encode(&bytes) } /// Represents a request for registration with the upstream. diff --git a/relay-profiling/Cargo.toml b/relay-profiling/Cargo.toml index 66372615b48..e9dd091ccd4 100644 --- a/relay-profiling/Cargo.toml +++ b/relay-profiling/Cargo.toml @@ -11,9 +11,9 @@ publish = false [dependencies] android_trace_log = { version = "0.2.0", features = ["serde"] } -base64 = "0.10.1" bytes = { version = "0.4.12", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] } +data-encoding = "2.3.3" relay-general = { path = "../relay-general" } serde = { version = "1.0.114", features = ["derive"] } serde_json = "1.0.55" diff --git a/relay-profiling/src/android.rs b/relay-profiling/src/android.rs index b1f3dce5126..0d2892241b1 100644 --- a/relay-profiling/src/android.rs +++ b/relay-profiling/src/android.rs @@ -3,6 +3,7 @@ use std::time::Duration; use android_trace_log::chrono::{DateTime, Utc}; use android_trace_log::{AndroidTraceLog, Clock, Time, Vm}; +use data_encoding::BASE64; use serde::{Deserialize, Serialize}; use relay_general::protocol::EventId; @@ -83,7 +84,7 @@ impl AndroidProfile { } fn parse(&mut self) -> Result<(), ProfileError> { - let profile_bytes = match base64::decode(&self.sampled_profile) { + let profile_bytes = match BASE64.decode(self.sampled_profile.as_bytes()) { Ok(profile) => profile, Err(_) => return Err(ProfileError::InvalidBase64Value), }; diff --git a/relay-server/Cargo.toml b/relay-server/Cargo.toml index c66a0d745ac..6e25c53413e 100644 --- a/relay-server/Cargo.toml +++ b/relay-server/Cargo.toml @@ -13,24 +13,16 @@ publish = false [features] default = [] ssl = ["native-tls", "actix-web/tls"] -processing = [ - "minidump", - "relay-config/processing", - "relay-kafka/producer", - "relay-quotas/redis", - "relay-redis/impl", - "symbolic-unreal", - "symbolic-common", -] +processing = ["minidump", "relay-config/processing", "relay-kafka/producer", "relay-quotas/redis", "relay-redis/impl", "symbolic-unreal", "symbolic-common"] [dependencies] actix = "0.7.9" actix-web = { version = "0.7.19", default-features = false } -base64 = "0.10.1" brotli2 = "0.3.2" bytes = { version = "0.4.12", features = ["serde"] } chrono = { version = "0.4.11", features = ["serde"] } clap = "2.33.1" +data-encoding = "2.3.3" failure = "0.1.8" flate2 = "1.0.19" fragile = { version = "2.0.0", features = ["slab"] } # used for vendoring sentry-actix diff --git a/relay-server/src/body/store_body.rs b/relay-server/src/body/store_body.rs index 4bfd2ed3032..f6c856e014b 100644 --- a/relay-server/src/body/store_body.rs +++ b/relay-server/src/body/store_body.rs @@ -3,6 +3,7 @@ use std::io::{self, ErrorKind, Read}; use actix_web::{error::PayloadError, HttpRequest}; use bytes::Bytes; +use data_encoding::BASE64; use flate2::read::ZlibDecoder; use futures01::prelude::*; use url::form_urlencoded; @@ -71,8 +72,9 @@ fn decode_bytes + AsRef<[u8]>>(body: B) -> Result