Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Switch from base64 to data-encoding #1743

Merged
merged 4 commits into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion relay-auth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
43 changes: 17 additions & 26 deletions relay-auth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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::<Sha512>(&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
Expand Down Expand Up @@ -242,7 +243,7 @@ impl FromStr for SecretKey {
type Err = KeyParseError;

fn from_str(s: &str) -> Result<SecretKey, KeyParseError> {
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),
};
Expand All @@ -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())
)
}
}
Expand All @@ -292,17 +289,13 @@ impl PublicKey {
pub fn verify_meta(&self, data: &[u8], sig: &str) -> Option<SignatureHeader> {
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();
Expand Down Expand Up @@ -373,7 +366,7 @@ impl FromStr for PublicKey {
type Err = KeyParseError;

fn from_str(s: &str) -> Result<PublicKey, KeyParseError> {
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),
};
Expand All @@ -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()))
}
}

Expand Down Expand Up @@ -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}"))
}
Expand All @@ -475,14 +464,16 @@ impl SignedRegisterState {
max_age: Option<Duration>,
) -> Result<RegisterState, UnpackError> {
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::<RegisterState>(&json).map_err(UnpackError::BadPayload)?;
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion relay-profiling/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 2 additions & 1 deletion relay-profiling/src/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::{HashMap, HashSet};

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;
Expand Down Expand Up @@ -90,7 +91,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),
};
Expand Down
12 changes: 2 additions & 10 deletions relay-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,17 @@ 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 }
anyhow = "1.0.66"
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
Expand Down
6 changes: 4 additions & 2 deletions relay-server/src/body/store_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -71,8 +72,9 @@ fn decode_bytes<B: Into<Bytes> + AsRef<[u8]>>(body: B) -> Result<Bytes, PayloadE

// TODO: Switch to a streaming decoder
// see https://github.com/alicemaz/rust-base64/pull/56
let binary_body =
base64::decode(&body).map_err(|e| io::Error::new(ErrorKind::InvalidInput, e))?;
let binary_body = BASE64
.decode(body.as_ref())
.map_err(|e| io::Error::new(ErrorKind::InvalidInput, e))?;
if binary_body.starts_with(b"{") {
return Ok(binary_body.into());
}
Expand Down