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/Cargo.toml b/libsignal-service/Cargo.toml index f45f9009c..136a2b6ad 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 } diff --git a/libsignal-service/src/account_manager.rs b/libsignal-service/src/account_manager.rs index cc2e2d1a2..cf96ac458 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; @@ -293,7 +294,7 @@ impl AccountManager { &[], HttpAuthOverride::NoOverride, &ProvisioningMessage { - body: base64::encode(body), + body: BASE64_STANDARD.encode(body), }, ) .await @@ -322,7 +323,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)?; @@ -653,19 +655,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 0922253de..4e487227f 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, @@ -357,7 +358,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( @@ -372,7 +373,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 de58b09e7..a0fc66ce2 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; @@ -128,8 +129,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 @@ -146,9 +147,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/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 3fe28684e..904c9e879 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}; @@ -221,7 +222,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 6b9c9422a..cf0c32cba 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::{ @@ -99,7 +100,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 }