diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7a55a0986..6544b851f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -30,6 +30,10 @@ jobs: features: "unsend-futures" steps: - uses: actions/checkout@v3 + - name: Install protobuf + run: | + sudo apt-get update + sudo apt-get install -y libprotobuf-dev libprotobuf-c-dev protobuf-compiler protobuf-c-compiler - uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -65,10 +69,14 @@ jobs: toolchain: "nightly" include: - project: "libsignal-service-actix" - toolchain: "1.70" + toolchain: "1.75" coverage: false steps: - uses: actions/checkout@v3 + - name: Install protobuf + run: | + sudo apt-get update + sudo apt-get install -y libprotobuf-dev libprotobuf-c-dev protobuf-compiler protobuf-c-compiler - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.toolchain }} diff --git a/README.md b/README.md index a2938cd51..c0d44693b 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,9 @@ If you're using a Cargo workspace, you should add the `[patch.crates.io]` sectio ### Note on supported Rust versions -`libsignal-service-rs` is the at the core of [Whisperfish][whisperfish], a SailfishOS application. The SailfishOS Rust compiler updates seldomly, and therefore the MSRV maps on the compiler for that operating system. At moment of writing, this is **Rust 1.72**. +`libsignal-service-rs` is the at the core of [Whisperfish][whisperfish], a SailfishOS application. The SailfishOS Rust compiler updates seldomly, and therefore the MSRV maps on the compiler for that operating system. At moment of writing, this is **Rust 1.75**. -For other platforms, we don't mandate MSRV. In practice, however, it is **Rust 1.70**. +For other platforms, we don't mandate MSRV. In practice, however, it is **Rust 1.75**. ## Contributing diff --git a/libsignal-service-actix/Cargo.toml b/libsignal-service-actix/Cargo.toml index 315b36536..71429a25c 100644 --- a/libsignal-service-actix/Cargo.toml +++ b/libsignal-service-actix/Cargo.toml @@ -29,7 +29,6 @@ rand = "0.8" thiserror = "1.0" async-trait = "0.1" -base64 = "0.13" phonenumber = "0.3" diff --git a/libsignal-service-hyper/Cargo.toml b/libsignal-service-hyper/Cargo.toml index d874aac8d..54ad2cb65 100644 --- a/libsignal-service-hyper/Cargo.toml +++ b/libsignal-service-hyper/Cargo.toml @@ -20,18 +20,20 @@ serde_json = "1.0" thiserror = "1.0" url = "2.1" +# hyper rustls 0.25 is not compatible with hyper 1 yet +# https://github.com/rustls/hyper-rustls/issues/234 hyper = { version = "0.14", features = ["client", "stream"] } -hyper-rustls = "0.24" +hyper-rustls = { version = "0.25", features=["http1", "http2"] } hyper-timeout = "0.4" headers = "0.3" # for websocket support -async-tungstenite = { version = "0.23", features = ["tokio-rustls-native-certs"] } +async-tungstenite = { version = "0.24", features = ["tokio-rustls-native-certs"] } tokio = { version = "1.0", features = ["macros"] } -tokio-rustls = "0.24" +tokio-rustls = "0.25" -rustls-pemfile = "0.3" +rustls-pemfile = "2.0" [dev-dependencies] rand = "0.8" diff --git a/libsignal-service-hyper/src/push_service.rs b/libsignal-service-hyper/src/push_service.rs index 940c56726..fc1374848 100644 --- a/libsignal-service-hyper/src/push_service.rs +++ b/libsignal-service-hyper/src/push_service.rs @@ -43,9 +43,11 @@ impl HyperPushService { let cfg = cfg.into(); let tls_config = Self::tls_config(&cfg); - let mut http = HttpConnector::new(); - http.enforce_http(false); - let https = HttpsConnector::from((http, tls_config)); + let https = hyper_rustls::HttpsConnectorBuilder::new() + .with_tls_config(tls_config) + .https_only() + .enable_http1() + .build(); // as in Signal-Android let mut timeout_connector = TimeoutConnector::new(https); @@ -66,21 +68,16 @@ impl HyperPushService { fn tls_config(cfg: &ServiceConfiguration) -> rustls::ClientConfig { let mut cert_bytes = std::io::Cursor::new(&cfg.certificate_authority); - let roots = rustls_pemfile::certs(&mut cert_bytes) - .expect("parseable PEM files"); - let roots = roots.iter().map(|v| rustls::Certificate(v.clone())); + let roots = rustls_pemfile::certs(&mut cert_bytes); let mut root_certs = rustls::RootCertStore::empty(); - for root in roots { - root_certs.add(&root).unwrap(); - } + root_certs.add_parsable_certificates( + roots.map(|c| c.expect("parsable PEM files")), + ); - let mut tls_config = rustls::ClientConfig::builder() - .with_safe_defaults() + rustls::ClientConfig::builder() .with_root_certificates(root_certs) - .with_no_client_auth(); - tls_config.alpn_protocols = vec![b"http/1.1".to_vec()]; - tls_config + .with_no_client_auth() } #[tracing::instrument(skip(self, path, body), fields(path = %path.as_ref()))] diff --git a/libsignal-service-hyper/src/websocket.rs b/libsignal-service-hyper/src/websocket.rs index 34624c0b3..8ec8777e6 100644 --- a/libsignal-service-hyper/src/websocket.rs +++ b/libsignal-service-hyper/src/websocket.rs @@ -3,13 +3,13 @@ use std::sync::Arc; use async_tungstenite::{ tokio::connect_async_with_tls_connector, tungstenite::{ - client::IntoClientRequest, http::HeaderName, Error as TungsteniteError, - Message, + client::IntoClientRequest, + http::{HeaderName, StatusCode}, + Error as TungsteniteError, Message, }, }; use bytes::Bytes; use futures::{channel::mpsc::*, prelude::*}; -use hyper::StatusCode; use tokio::time::Instant; use tokio_rustls::rustls; use url::Url; diff --git a/libsignal-service/Cargo.toml b/libsignal-service/Cargo.toml index f45f9009c..fa594c7ea 100644 --- a/libsignal-service/Cargo.toml +++ b/libsignal-service/Cargo.toml @@ -15,7 +15,7 @@ aes-gcm = "0.10" cbc = "0.1" ctr = "0.9" async-trait = "0.1" -base64 = "0.13" +base64 = "0.21" bincode = "1.3" bytes = "1" chrono = { version = "0.4", features = ["serde", "clock"], default-features = false } @@ -25,7 +25,7 @@ hex = "0.4" hkdf = "0.12" hmac = "0.12" phonenumber = "0.3" -prost = "0.10" +prost = "> 0.10, <= 0.12" rand = "0.8" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" @@ -38,13 +38,13 @@ tracing = { version = "0.1", features = ["log"] } tracing-futures = "0.2" [build-dependencies] -prost-build = "0.10" +prost-build = "> 0.10, <= 0.12" [dev-dependencies] anyhow = "1.0" tokio = { version = "1.0", features = ["macros", "rt"] } -rustls = "0.21" +rustls = "0.22" [features] unsend-futures = [] diff --git a/libsignal-service/src/account_manager.rs b/libsignal-service/src/account_manager.rs index 7d0da2bf1..0a0674cfd 100644 --- a/libsignal-service/src/account_manager.rs +++ b/libsignal-service/src/account_manager.rs @@ -1,3 +1,4 @@ +use base64::prelude::*; use std::collections::HashMap; use std::convert::{TryFrom, TryInto}; use std::time::SystemTime; @@ -296,7 +297,7 @@ impl AccountManager { &[], HttpAuthOverride::NoOverride, &ProvisioningMessage { - body: base64::encode(body), + body: BASE64_STANDARD.encode(body), }, ) .await @@ -326,7 +327,8 @@ impl AccountManager { let ephemeral_id = query.get("uuid").ok_or(LinkError::InvalidUuid)?; let pub_key = query.get("pub_key").ok_or(LinkError::InvalidPublicKey)?; - let pub_key = base64::decode(&**pub_key) + let pub_key = BASE64_STANDARD + .decode(&**pub_key) .map_err(|_e| LinkError::InvalidPublicKey)?; let pub_key = PublicKey::deserialize(&pub_key) .map_err(|_e| LinkError::InvalidPublicKey)?; @@ -640,6 +642,7 @@ pub fn decrypt_device_name( #[cfg(test)] mod tests { + use base64::prelude::*; use libsignal_protocol::{KeyPair, PrivateKey, PublicKey}; use super::DeviceName; @@ -666,19 +669,24 @@ mod tests { #[test] fn decrypt_device_name() -> anyhow::Result<()> { - let ephemeral_private_key = PrivateKey::deserialize(&base64::decode( - "0CgxHjwwblXjvX8sD5wZDWdYToMRf+CZSlgaUrxCGVo=", - )?)?; - let ephemeral_public_key = PublicKey::deserialize(&base64::decode( - "BcZS+Lt6yAKbEpXnRX+I5wHqesuvu93Q2V+fjidwW8R6", - )?)?; + let ephemeral_private_key = PrivateKey::deserialize( + &BASE64_STANDARD + .decode("0CgxHjwwblXjvX8sD5wZDWdYToMRf+CZSlgaUrxCGVo=")?, + )?; + let ephemeral_public_key = PublicKey::deserialize( + &BASE64_STANDARD + .decode("BcZS+Lt6yAKbEpXnRX+I5wHqesuvu93Q2V+fjidwW8R6")?, + )?; let device_name = DeviceName { ephemeral_public: Some(ephemeral_public_key.serialize().to_vec()), - synthetic_iv: Some(base64::decode("86gekHGmltnnZ9QARhiFcg==")?), - ciphertext: Some(base64::decode( - "MtJ9/9KBWLBVAxfZJD4pLKzP4q+iodRJeCc+/A==", - )?), + synthetic_iv: Some( + BASE64_STANDARD.decode("86gekHGmltnnZ9QARhiFcg==")?, + ), + ciphertext: Some( + BASE64_STANDARD + .decode("MtJ9/9KBWLBVAxfZJD4pLKzP4q+iodRJeCc+/A==")?, + ), }; let decrypted_device_name = diff --git a/libsignal-service/src/cipher.rs b/libsignal-service/src/cipher.rs index 6af9f11db..6f5fa188b 100644 --- a/libsignal-service/src/cipher.rs +++ b/libsignal-service/src/cipher.rs @@ -1,6 +1,7 @@ use std::{convert::TryFrom, fmt, time::SystemTime}; use aes::cipher::block_padding::{Iso7816, RawPadding}; +use base64::prelude::*; use libsignal_protocol::{ group_decrypt, message_decrypt_prekey, message_decrypt_signal, message_encrypt, process_sender_key_distribution_message, @@ -364,7 +365,7 @@ where r#type: Type::UnidentifiedSender as u32, destination_device_id: address.device_id().into(), destination_registration_id, - content: base64::encode(message), + content: BASE64_STANDARD.encode(message), }) } else { let message = message_encrypt( @@ -379,7 +380,7 @@ where let destination_registration_id = session_record.remote_registration_id()?; - let body = base64::encode(message.serialize()); + let body = BASE64_STANDARD.encode(message.serialize()); use crate::proto::envelope::Type; let message_type = match message.message_type() { diff --git a/libsignal-service/src/configuration.rs b/libsignal-service/src/configuration.rs index ac3d2e3fd..a5074e95e 100644 --- a/libsignal-service/src/configuration.rs +++ b/libsignal-service/src/configuration.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, str::FromStr}; +use base64::prelude::*; use libsignal_protocol::PublicKey; use serde::{Deserialize, Serialize}; use url::Url; @@ -129,8 +130,8 @@ impl From<&SignalServers> for ServiceConfiguration { "https://api-staging.directory.signal.org".parse().unwrap(), certificate_authority: include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/certs/staging-root-ca.pem")).to_string(), unidentified_sender_trust_root: - PublicKey::deserialize(&base64::decode("BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx").unwrap()).unwrap(), - zkgroup_server_public_params: bincode::deserialize(&base64::decode("ABSY21VckQcbSXVNCGRYJcfWHiAMZmpTtTELcDmxgdFbtp/bWsSxZdMKzfCp8rvIs8ocCU3B37fT3r4Mi5qAemeGeR2X+/YmOGR5ofui7tD5mDQfstAI9i+4WpMtIe8KC3wU5w3Inq3uNWVmoGtpKndsNfwJrCg0Hd9zmObhypUnSkfYn2ooMOOnBpfdanRtrvetZUayDMSC5iSRcXKpdlukrpzzsCIvEwjwQlJYVPOQPj4V0F4UXXBdHSLK05uoPBCQG8G9rYIGedYsClJXnbrgGYG3eMTG5hnx4X4ntARBgELuMWWUEEfSK0mjXg+/2lPmWcTZWR9nkqgQQP0tbzuiPm74H2wMO4u1Wafe+UwyIlIT9L7KLS19Aw8r4sPrXZSSsOZ6s7M1+rTJN0bI5CKY2PX29y5Ok3jSWufIKcgKOnWoP67d5b2du2ZVJjpjfibNIHbT/cegy/sBLoFwtHogVYUewANUAXIaMPyCLRArsKhfJ5wBtTminG/PAvuBdJ70Z/bXVPf8TVsR292zQ65xwvWTejROW6AZX6aqucUj").unwrap()).unwrap(), + PublicKey::deserialize(&BASE64_STANDARD.decode("BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx").unwrap()).unwrap(), + zkgroup_server_public_params: bincode::deserialize(&BASE64_STANDARD.decode("ABSY21VckQcbSXVNCGRYJcfWHiAMZmpTtTELcDmxgdFbtp/bWsSxZdMKzfCp8rvIs8ocCU3B37fT3r4Mi5qAemeGeR2X+/YmOGR5ofui7tD5mDQfstAI9i+4WpMtIe8KC3wU5w3Inq3uNWVmoGtpKndsNfwJrCg0Hd9zmObhypUnSkfYn2ooMOOnBpfdanRtrvetZUayDMSC5iSRcXKpdlukrpzzsCIvEwjwQlJYVPOQPj4V0F4UXXBdHSLK05uoPBCQG8G9rYIGedYsClJXnbrgGYG3eMTG5hnx4X4ntARBgELuMWWUEEfSK0mjXg+/2lPmWcTZWR9nkqgQQP0tbzuiPm74H2wMO4u1Wafe+UwyIlIT9L7KLS19Aw8r4sPrXZSSsOZ6s7M1+rTJN0bI5CKY2PX29y5Ok3jSWufIKcgKOnWoP67d5b2du2ZVJjpjfibNIHbT/cegy/sBLoFwtHogVYUewANUAXIaMPyCLRArsKhfJ5wBtTminG/PAvuBdJ70Z/bXVPf8TVsR292zQ65xwvWTejROW6AZX6aqucUj").unwrap()).unwrap(), }, // configuration with the Signal API production endpoints // https://github.com/signalapp/Signal-Desktop/blob/master/config/production.json @@ -147,9 +148,9 @@ impl From<&SignalServers> for ServiceConfiguration { contact_discovery_url: "https://api.directory.signal.org".parse().unwrap(), certificate_authority: include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/certs/production-root-ca.pem")).to_string(), unidentified_sender_trust_root: - PublicKey::deserialize(&base64::decode("BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF").unwrap()).unwrap(), + PublicKey::deserialize(&BASE64_STANDARD.decode("BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF").unwrap()).unwrap(), zkgroup_server_public_params: bincode::deserialize( - &base64::decode("AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X36nOoGPs54XsEGzPdEV+itQNGUFEjY6X9Uv+Acuks7NpyGvCoKxGwgKgE5XyJ+nNKlyHHOLb6N1NuHyBrZrgtY/JYJHRooo5CEqYKBqdFnmbTVGEkCvJKxLnjwKWf+fEPoWeQFj5ObDjcKMZf2Jm2Ae69x+ikU5gBXsRmoF94GXTLfN0/vLt98KDPnxwAQL9j5V1jGOY8jQl6MLxEs56cwXN0dqCnImzVH3TZT1cJ8SW1BRX6qIVxEzjsSGx3yxF3suAilPMqGRp4ffyopjMD1JXiKR2RwLKzizUe5e8XyGOy9fplzhw3jVzTRyUZTRSZKkMLWcQ/gv0E4aONNqs4P").unwrap()).unwrap(), + &BASE64_STANDARD.decode("AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X36nOoGPs54XsEGzPdEV+itQNGUFEjY6X9Uv+Acuks7NpyGvCoKxGwgKgE5XyJ+nNKlyHHOLb6N1NuHyBrZrgtY/JYJHRooo5CEqYKBqdFnmbTVGEkCvJKxLnjwKWf+fEPoWeQFj5ObDjcKMZf2Jm2Ae69x+ikU5gBXsRmoF94GXTLfN0/vLt98KDPnxwAQL9j5V1jGOY8jQl6MLxEs56cwXN0dqCnImzVH3TZT1cJ8SW1BRX6qIVxEzjsSGx3yxF3suAilPMqGRp4ffyopjMD1JXiKR2RwLKzizUe5e8XyGOy9fplzhw3jVzTRyUZTRSZKkMLWcQ/gv0E4aONNqs4P").unwrap()).unwrap(), }, } } diff --git a/libsignal-service/src/groups_v2/manager.rs b/libsignal-service/src/groups_v2/manager.rs index c132483e9..24102af34 100644 --- a/libsignal-service/src/groups_v2/manager.rs +++ b/libsignal-service/src/groups_v2/manager.rs @@ -9,6 +9,7 @@ use crate::{ push_service::{HttpAuth, HttpAuthOverride, ServiceIds}, }; +use base64::prelude::*; use bytes::Bytes; use chrono::{Days, NaiveDate, NaiveTime, Utc}; use futures::AsyncReadExt; @@ -40,7 +41,7 @@ impl CredentialResponse { self.credentials .into_iter() .map(|c| { - let bytes = base64::decode(c.credential)?; + let bytes = BASE64_STANDARD.decode(c.credential)?; let data = bincode::deserialize(&bytes)?; Ok((c.redemption_time, data)) }) diff --git a/libsignal-service/src/groups_v2/model.rs b/libsignal-service/src/groups_v2/model.rs index 6c8e9de0b..3fa3e6417 100644 --- a/libsignal-service/src/groups_v2/model.rs +++ b/libsignal-service/src/groups_v2/model.rs @@ -143,11 +143,11 @@ impl TryFrom for Role { fn try_from(value: i32) -> Result { use crate::proto::member::Role::*; - match crate::proto::member::Role::from_i32(value) { - Some(Unknown) => Ok(Role::Unknown), - Some(Default) => Ok(Role::Default), - Some(Administrator) => Ok(Role::Administrator), - None => Err(GroupDecodingError::WrongEnumValue), + match crate::proto::member::Role::try_from(value) { + Ok(Unknown) => Ok(Role::Unknown), + Ok(Default) => Ok(Role::Default), + Ok(Administrator) => Ok(Role::Administrator), + Err(_e) => Err(GroupDecodingError::WrongEnumValue), } } } @@ -169,13 +169,13 @@ impl TryFrom for AccessRequired { fn try_from(value: i32) -> Result { use crate::proto::access_control::AccessRequired::*; - match crate::proto::access_control::AccessRequired::from_i32(value) { - Some(Unknown) => Ok(AccessRequired::Unknown), - Some(Any) => Ok(AccessRequired::Any), - Some(Member) => Ok(AccessRequired::Member), - Some(Administrator) => Ok(AccessRequired::Administrator), - Some(Unsatisfiable) => Ok(AccessRequired::Unsatisfiable), - None => Err(GroupDecodingError::WrongEnumValue), + match crate::proto::access_control::AccessRequired::try_from(value) { + Ok(Unknown) => Ok(AccessRequired::Unknown), + Ok(Any) => Ok(AccessRequired::Any), + Ok(Member) => Ok(AccessRequired::Member), + Ok(Administrator) => Ok(AccessRequired::Administrator), + Ok(Unsatisfiable) => Ok(AccessRequired::Unsatisfiable), + Err(_e) => Err(GroupDecodingError::WrongEnumValue), } } } diff --git a/libsignal-service/src/groups_v2/operations.rs b/libsignal-service/src/groups_v2/operations.rs index a78e986f6..322eb99a1 100644 --- a/libsignal-service/src/groups_v2/operations.rs +++ b/libsignal-service/src/groups_v2/operations.rs @@ -1,5 +1,6 @@ use std::convert::TryInto; +use base64::prelude::*; use bytes::Bytes; use libsignal_protocol::{Aci, ServiceId}; use prost::Message; @@ -402,9 +403,9 @@ impl GroupOperations { let modify_invite_link_password = actions.modify_invite_link_password.into_iter().map(|m| { - Ok(GroupChange::InviteLinkPassword(base64::encode( - m.invite_link_password, - ))) + Ok(GroupChange::InviteLinkPassword( + BASE64_STANDARD.encode(m.invite_link_password), + )) }); let modify_announcements_only = actions diff --git a/libsignal-service/src/provisioning/mod.rs b/libsignal-service/src/provisioning/mod.rs index aba0bf200..5774d43b4 100644 --- a/libsignal-service/src/provisioning/mod.rs +++ b/libsignal-service/src/provisioning/mod.rs @@ -6,6 +6,7 @@ use std::{array::TryFromSliceError, borrow::Cow}; pub use cipher::ProvisioningCipher; +use base64::prelude::*; use derivative::Derivative; use futures::StreamExt; use futures::{channel::mpsc::Sender, pin_mut, SinkExt}; @@ -222,7 +223,7 @@ pub async fn link_device< let pni_signed_pre_key = generate_signed_pre_key(pni_store, csprng, &pni_key_pair).await?; - let encrypted_device_name = base64::encode( + let encrypted_device_name = BASE64_STANDARD.encode( encrypt_device_name(csprng, device_name, &aci_public_key)? .encode_to_vec(), ); diff --git a/libsignal-service/src/provisioning/pipe.rs b/libsignal-service/src/provisioning/pipe.rs index 147468ff1..ee6ba42c5 100644 --- a/libsignal-service/src/provisioning/pipe.rs +++ b/libsignal-service/src/provisioning/pipe.rs @@ -1,3 +1,4 @@ +use base64::prelude::*; use bytes::Bytes; use futures::{ channel::{ @@ -97,7 +98,7 @@ impl ProvisioningPipe { .append_pair("uuid", &uuid.uuid.unwrap()) .append_pair( "pub_key", - &base64::encode( + &BASE64_STANDARD.encode( self.provisioning_cipher.public_key().serialize(), ), ); diff --git a/libsignal-service/src/utils.rs b/libsignal-service/src/utils.rs index a911dbda9..cd5e194e4 100644 --- a/libsignal-service/src/utils.rs +++ b/libsignal-service/src/utils.rs @@ -1,4 +1,5 @@ pub mod serde_base64 { + use base64::prelude::*; use serde::{Deserialize, Deserializer, Serializer}; pub fn serialize(bytes: &T, serializer: S) -> Result @@ -6,7 +7,7 @@ pub mod serde_base64 { T: AsRef<[u8]>, S: Serializer, { - serializer.serialize_str(&base64::encode(bytes.as_ref())) + serializer.serialize_str(&BASE64_STANDARD.encode(bytes.as_ref())) } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> @@ -15,12 +16,15 @@ pub mod serde_base64 { { use serde::de::Error; String::deserialize(deserializer).and_then(|string| { - base64::decode(string).map_err(|err| Error::custom(err.to_string())) + BASE64_STANDARD + .decode(string) + .map_err(|err| Error::custom(err.to_string())) }) } } pub mod serde_optional_base64 { + use base64::prelude::*; use serde::{Deserialize, Deserializer, Serializer}; use super::serde_base64; @@ -47,7 +51,8 @@ pub mod serde_optional_base64 { { use serde::de::Error; match Option::::deserialize(deserializer)? { - Some(s) => base64::decode(s) + Some(s) => BASE64_STANDARD + .decode(s) .map_err(|err| Error::custom(err.to_string())) .map(Some), None => Ok(None), @@ -56,6 +61,7 @@ pub mod serde_optional_base64 { } pub mod serde_public_key { + use base64::prelude::*; use libsignal_protocol::PublicKey; use serde::{Deserialize, Deserializer, Serializer}; @@ -67,7 +73,7 @@ pub mod serde_public_key { S: Serializer, { let public_key = public_key.serialize(); - serializer.serialize_str(&base64::encode(&public_key)) + serializer.serialize_str(&BASE64_STANDARD.encode(&public_key)) } pub fn deserialize<'de, D>(deserializer: D) -> Result @@ -75,7 +81,8 @@ pub mod serde_public_key { D: Deserializer<'de>, { PublicKey::deserialize( - &base64::decode(String::deserialize(deserializer)?) + &BASE64_STANDARD + .decode(String::deserialize(deserializer)?) .map_err(serde::de::Error::custom)?, ) .map_err(serde::de::Error::custom) @@ -83,6 +90,7 @@ pub mod serde_public_key { } pub mod serde_optional_public_key { + use base64::prelude::*; use libsignal_protocol::PublicKey; use serde::{Deserialize, Deserializer, Serializer}; @@ -112,7 +120,8 @@ pub mod serde_optional_public_key { match Option::::deserialize(deserializer)? { Some(public_key) => Ok(Some( PublicKey::deserialize( - &base64::decode(public_key) + &BASE64_STANDARD + .decode(public_key) .map_err(serde::de::Error::custom)?, ) .map_err(serde::de::Error::custom)?, @@ -123,6 +132,7 @@ pub mod serde_optional_public_key { } pub mod serde_private_key { + use base64::prelude::*; use libsignal_protocol::PrivateKey; use serde::{Deserialize, Deserializer, Serializer}; @@ -134,7 +144,7 @@ pub mod serde_private_key { S: Serializer, { let public_key = public_key.serialize(); - serializer.serialize_str(&base64::encode(public_key)) + serializer.serialize_str(&BASE64_STANDARD.encode(public_key)) } pub fn deserialize<'de, D>(deserializer: D) -> Result @@ -142,7 +152,8 @@ pub mod serde_private_key { D: Deserializer<'de>, { PrivateKey::deserialize( - &base64::decode(String::deserialize(deserializer)?) + &BASE64_STANDARD + .decode(String::deserialize(deserializer)?) .map_err(serde::de::Error::custom)?, ) .map_err(serde::de::Error::custom) @@ -150,6 +161,7 @@ pub mod serde_private_key { } pub mod serde_optional_private_key { + use base64::prelude::*; use libsignal_protocol::PrivateKey; use serde::{Deserialize, Deserializer, Serializer}; @@ -179,7 +191,8 @@ pub mod serde_optional_private_key { match Option::::deserialize(deserializer)? { Some(private_key) => Ok(Some( PrivateKey::deserialize( - &base64::decode(private_key) + &BASE64_STANDARD + .decode(private_key) .map_err(serde::de::Error::custom)?, ) .map_err(serde::de::Error::custom)?, @@ -193,6 +206,7 @@ pub mod serde_signaling_key { use std::convert::TryInto; use crate::configuration::SignalingKey; + use base64::prelude::*; use serde::{Deserialize, Deserializer, Serializer}; pub fn serialize( @@ -202,7 +216,7 @@ pub mod serde_signaling_key { where S: Serializer, { - serializer.serialize_str(&base64::encode(signaling_key)) + serializer.serialize_str(&BASE64_STANDARD.encode(signaling_key)) } pub fn deserialize<'de, D>( @@ -211,7 +225,8 @@ pub mod serde_signaling_key { where D: Deserializer<'de>, { - base64::decode(String::deserialize(deserializer)?) + BASE64_STANDARD + .decode(String::deserialize(deserializer)?) .map_err(serde::de::Error::custom)? .try_into() .map_err(|buf: Vec| { diff --git a/libsignal-service/src/websocket/sender.rs b/libsignal-service/src/websocket/sender.rs index 4c94a0b4f..cecc7e1c9 100644 --- a/libsignal-service/src/websocket/sender.rs +++ b/libsignal-service/src/websocket/sender.rs @@ -2,6 +2,7 @@ use crate::{ sender::{OutgoingPushMessages, SendMessageResponse}, unidentified_access::UnidentifiedAccess, }; +use base64::prelude::*; use super::*; @@ -20,8 +21,10 @@ impl SignalWebSocket { access: &UnidentifiedAccess, ) -> Result { let path = format!("/v1/messages/{}", messages.recipient.uuid); - let header = - format!("Unidentified-Access-Key:{}", base64::encode(&access.key)); + let header = format!( + "Unidentified-Access-Key:{}", + BASE64_STANDARD.encode(&access.key) + ); self.put_json_with_headers(&path, messages, vec![header]) .await }