diff --git a/Cargo.lock b/Cargo.lock index f03bb23..e125552 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,12 +262,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.2" @@ -2427,7 +2421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "async-compression", - "base64 0.21.2", + "base64", "bytes", "cookie 0.16.2", "cookie_store", @@ -2567,7 +2561,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64", ] [[package]] @@ -3009,7 +3003,7 @@ name = "steamguard" version = "0.10.1" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "cookie 0.14.4", "hmac", "lazy_static 1.4.0", @@ -3043,7 +3037,7 @@ dependencies = [ "aes 0.8.3", "anyhow", "argon2", - "base64 0.13.1", + "base64", "cbc", "clap", "clap_complete", diff --git a/Cargo.toml b/Cargo.toml index f8a436f..c3ffe5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ path = "src/main.rs" [dependencies] anyhow = "^1.0" -base64 = "0.13.0" +base64 = "0.21.2" text_io = "0.1.8" rpassword = "5.0" reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "cookies", "gzip", "rustls-tls"] } diff --git a/src/encryption/argon2id_aes.rs b/src/encryption/argon2id_aes.rs index 71ad45e..4183666 100644 --- a/src/encryption/argon2id_aes.rs +++ b/src/encryption/argon2id_aes.rs @@ -1,7 +1,9 @@ use aes::cipher::block_padding::Pkcs7; use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit}; use aes::Aes256; +use anyhow::Context; use argon2::Argon2; +use base64::Engine; use log::*; use super::*; @@ -19,7 +21,7 @@ impl Argon2idAes256 { fn get_encryption_key(passkey: &str, salt: &str) -> anyhow::Result<[u8; Self::KEY_SIZE_BYTES]> { let password_bytes = passkey.as_bytes(); - let salt_bytes = base64::decode(salt)?; + let salt_bytes = base64::engine::general_purpose::STANDARD.decode(salt)?; let mut full_key: [u8; Self::KEY_SIZE_BYTES] = [0u8; Self::KEY_SIZE_BYTES]; let deriver = Argon2::new( argon2::Algorithm::Argon2id, @@ -40,6 +42,14 @@ impl Argon2idAes256 { ) .expect("Unable to create Argon2 config.") } + + fn decode_iv(&self) -> anyhow::Result<[u8; Self::IV_LENGTH]> { + let mut iv = [0u8; Self::IV_LENGTH]; + base64::engine::general_purpose::STANDARD + .decode_slice_unchecked(&self.iv, &mut iv) + .context("decoding iv")?; + Ok(iv) + } } impl EntryEncryptor for Argon2idAes256 { @@ -50,8 +60,8 @@ impl EntryEncryptor for Argon2idAes256 { rng.fill(&mut salt); rng.fill(&mut iv); Argon2idAes256 { - iv: base64::encode(iv), - salt: base64::encode(salt), + iv: base64::engine::general_purpose::STANDARD.encode(iv), + salt: base64::engine::general_purpose::STANDARD.encode(salt), } } @@ -65,11 +75,11 @@ impl EntryEncryptor for Argon2idAes256 { debug!("key derivation took: {:?}", start.elapsed()); let start = std::time::Instant::now(); - let mut iv = [0u8; Self::IV_LENGTH]; - base64::decode_config_slice(&self.iv, base64::STANDARD, &mut iv)?; - let cipher = cbc::Encryptor::::new_from_slices(&key, &iv)?; + let iv = self.decode_iv()?; + let cipher = + cbc::Encryptor::::new_from_slices(&key, &iv).context("creating cipher")?; let ciphertext = cipher.encrypt_padded_vec_mut::(&plaintext); - let encoded = base64::encode(ciphertext); + let encoded = base64::engine::general_purpose::STANDARD.encode(ciphertext); debug!("encryption took: {:?}", start.elapsed()); Ok(encoded.as_bytes().to_vec()) } @@ -84,10 +94,10 @@ impl EntryEncryptor for Argon2idAes256 { debug!("key derivation took: {:?}", start.elapsed()); let start = std::time::Instant::now(); - let mut iv = [0u8; Self::IV_LENGTH]; - base64::decode_config_slice(&self.iv, base64::STANDARD, &mut iv)?; - let cipher = cbc::Decryptor::::new_from_slices(&key, &iv)?; - let decoded = base64::decode(ciphertext)?; + let iv = self.decode_iv()?; + let cipher = + cbc::Decryptor::::new_from_slices(&key, &iv).context("creating cipher")?; + let decoded = base64::engine::general_purpose::STANDARD.decode(ciphertext)?; let size: usize = decoded.len() / 16 + (if decoded.len() % 16 == 0 { 0 } else { 1 }); let mut buffer = vec![0xffu8; 16 * size]; buffer[..decoded.len()].copy_from_slice(&decoded); @@ -104,7 +114,7 @@ mod tests { #[test] fn test_encryption_key() { assert_eq!( - base64::encode( + base64::engine::general_purpose::STANDARD.encode( Argon2idAes256::get_encryption_key("password", "GMhL0N2hqXg=") .unwrap() .as_slice() @@ -116,7 +126,7 @@ mod tests { #[test] fn test_encryption_key2() { assert_eq!( - base64::encode( + base64::engine::general_purpose::STANDARD.encode( Argon2idAes256::get_encryption_key("password", "wTzTE9A6aN8=") .unwrap() .as_slice() diff --git a/src/encryption/legacy.rs b/src/encryption/legacy.rs index 42da0af..eb1e4b0 100644 --- a/src/encryption/legacy.rs +++ b/src/encryption/legacy.rs @@ -1,6 +1,8 @@ use aes::cipher::block_padding::Pkcs7; use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit}; use aes::Aes256; +use anyhow::Context; +use base64::Engine; use log::*; use sha1::Sha1; @@ -21,7 +23,7 @@ impl LegacySdaCompatible { fn get_encryption_key(passkey: &str, salt: &str) -> anyhow::Result<[u8; Self::KEY_SIZE_BYTES]> { let password_bytes = passkey.as_bytes(); - let salt_bytes = base64::decode(salt)?; + let salt_bytes = base64::engine::general_purpose::STANDARD.decode(salt)?; let mut full_key: [u8; Self::KEY_SIZE_BYTES] = [0u8; Self::KEY_SIZE_BYTES]; pbkdf2::pbkdf2_hmac::( password_bytes, @@ -31,6 +33,14 @@ impl LegacySdaCompatible { ); Ok(full_key) } + + fn decode_iv(&self) -> anyhow::Result<[u8; Self::IV_LENGTH]> { + let mut iv = [0u8; Self::IV_LENGTH]; + base64::engine::general_purpose::STANDARD + .decode_slice_unchecked(&self.iv, &mut iv) + .context("decoding iv")?; + Ok(iv) + } } impl EntryEncryptor for LegacySdaCompatible { @@ -41,8 +51,8 @@ impl EntryEncryptor for LegacySdaCompatible { rng.fill(&mut salt); rng.fill(&mut iv); LegacySdaCompatible { - iv: base64::encode(iv), - salt: base64::encode(salt), + iv: base64::engine::general_purpose::STANDARD.encode(iv), + salt: base64::engine::general_purpose::STANDARD.encode(salt), } } @@ -56,11 +66,11 @@ impl EntryEncryptor for LegacySdaCompatible { debug!("key derivation took: {:?}", start.elapsed()); let start = std::time::Instant::now(); - let mut iv = [0u8; Self::IV_LENGTH]; - base64::decode_config_slice(&self.iv, base64::STANDARD, &mut iv)?; - let cipher = cbc::Encryptor::::new_from_slices(&key, &iv)?; + let iv = self.decode_iv()?; + let cipher = + cbc::Encryptor::::new_from_slices(&key, &iv).context("creating cipher")?; let ciphertext = cipher.encrypt_padded_vec_mut::(&plaintext); - let encoded = base64::encode(ciphertext); + let encoded = base64::engine::general_purpose::STANDARD.encode(ciphertext); debug!("encryption took: {:?}", start.elapsed()); Ok(encoded.as_bytes().to_vec()) } @@ -75,10 +85,10 @@ impl EntryEncryptor for LegacySdaCompatible { debug!("key derivation took: {:?}", start.elapsed()); let start = std::time::Instant::now(); - let mut iv = [0u8; Self::IV_LENGTH]; - base64::decode_config_slice(&self.iv, base64::STANDARD, &mut iv)?; - let cipher = cbc::Decryptor::::new_from_slices(&key, &iv)?; - let decoded = base64::decode(ciphertext)?; + let iv = self.decode_iv()?; + let cipher = + cbc::Decryptor::::new_from_slices(&key, &iv).context("creating cipher")?; + let decoded = base64::engine::general_purpose::STANDARD.decode(ciphertext)?; let size: usize = decoded.len() / 16 + (if decoded.len() % 16 == 0 { 0 } else { 1 }); let mut buffer = vec![0xffu8; 16 * size]; buffer[..decoded.len()].copy_from_slice(&decoded); @@ -100,7 +110,8 @@ mod tests { LegacySdaCompatible::get_encryption_key("password", "GMhL0N2hqXg=") .unwrap() .as_slice(), - base64::decode("KtiRa4/OxW83MlB6URf+Z8rAGj7CBY+pDlwD/NuVo6Y=") + base64::engine::general_purpose::STANDARD + .decode("KtiRa4/OxW83MlB6URf+Z8rAGj7CBY+pDlwD/NuVo6Y=") .unwrap() .as_slice() ); @@ -109,7 +120,8 @@ mod tests { LegacySdaCompatible::get_encryption_key("password", "wTzTE9A6aN8=") .unwrap() .as_slice(), - base64::decode("Dqpej/3DqEat0roJaHmu3luYgDzRCUmzX94n4fqvWj8=") + base64::engine::general_purpose::STANDARD + .decode("Dqpej/3DqEat0roJaHmu3luYgDzRCUmzX94n4fqvWj8=") .unwrap() .as_slice() ); @@ -140,8 +152,8 @@ mod tests { /// An insecure but reproducible strategy for generating encryption params. fn encryption_params()(salt in any::<[u8; LegacySdaCompatible::SALT_LENGTH]>(), iv in any::<[u8; LegacySdaCompatible::IV_LENGTH]>()) -> LegacySdaCompatible { LegacySdaCompatible { - salt: base64::encode(salt), - iv: base64::encode(iv), + salt: base64::engine::general_purpose::STANDARD.encode(salt), + iv: base64::engine::general_purpose::STANDARD.encode(iv), } } } diff --git a/steamguard/Cargo.toml b/steamguard/Cargo.toml index f3e846e..30b8b4c 100644 --- a/steamguard/Cargo.toml +++ b/steamguard/Cargo.toml @@ -13,7 +13,7 @@ license = "MIT OR Apache-2.0" [dependencies] anyhow = "^1.0" sha1 = "^0.10" -base64 = "0.13.0" +base64 = "^0.21" reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "cookies", "gzip", "rustls-tls", "multipart"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/steamguard/src/accountlinker.rs b/steamguard/src/accountlinker.rs index c10ade4..e09f26b 100644 --- a/steamguard/src/accountlinker.rs +++ b/steamguard/src/accountlinker.rs @@ -5,6 +5,7 @@ use crate::steamapi::twofactor::TwoFactorClient; use crate::token::TwoFactorSecret; use crate::transport::Transport; use crate::{steamapi::EResult, token::Tokens, SteamGuardAccount}; +use base64::Engine; use log::*; use thiserror::Error; @@ -64,9 +65,13 @@ where uri: resp.take_uri().into(), shared_secret: TwoFactorSecret::from_bytes(resp.take_shared_secret()), token_gid: resp.take_token_gid(), - identity_secret: base64::encode(resp.take_identity_secret()).into(), + identity_secret: base64::engine::general_purpose::STANDARD + .encode(resp.take_identity_secret()) + .into(), device_id: self.device_id.clone(), - secret_1: base64::encode(resp.take_secret_1()).into(), + secret_1: base64::engine::general_purpose::STANDARD + .encode(resp.take_secret_1()) + .into(), tokens: Some(self.tokens.clone()), }; let success = AccountLinkSuccess { diff --git a/steamguard/src/confirmation.rs b/steamguard/src/confirmation.rs index ef3acfd..1c10461 100644 --- a/steamguard/src/confirmation.rs +++ b/steamguard/src/confirmation.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; +use base64::Engine; use hmac::{Hmac, Mac}; use log::*; use reqwest::{ @@ -403,13 +404,15 @@ fn generate_confirmation_hash_for_time( tag: &str, identity_secret: impl AsRef<[u8]>, ) -> String { - let decode: &[u8] = &base64::decode(identity_secret).unwrap(); + let decode: &[u8] = &base64::engine::general_purpose::STANDARD + .decode(identity_secret) + .unwrap(); let mut mac = Hmac::::new_from_slice(decode).unwrap(); mac.update(&build_time_bytes(time)); mac.update(tag.as_bytes()); let result = mac.finalize(); let hash = result.into_bytes(); - base64::encode(hash) + base64::engine::general_purpose::STANDARD.encode(hash) } #[cfg(test)] diff --git a/steamguard/src/protobufs.rs b/steamguard/src/protobufs.rs index 3f53079..f445185 100644 --- a/steamguard/src/protobufs.rs +++ b/steamguard/src/protobufs.rs @@ -24,6 +24,7 @@ impl Zeroize for Ip_addr { #[cfg(test)] mod parse_tests { + use base64::Engine; use protobuf::Message; use super::steammessages_auth_steamclient::CAuthentication_GetPasswordRSAPublicKey_Request; @@ -34,7 +35,7 @@ mod parse_tests { req.set_account_name("hydrastar2".to_owned()); let bytes = req.write_to_bytes().unwrap(); - let s = base64::encode_config(bytes, base64::URL_SAFE); + let s = base64::engine::general_purpose::URL_SAFE.encode(bytes); assert_eq!(s, "CgpoeWRyYXN0YXIy"); } } diff --git a/steamguard/src/token.rs b/steamguard/src/token.rs index 9ecb030..73c5085 100644 --- a/steamguard/src/token.rs +++ b/steamguard/src/token.rs @@ -1,3 +1,4 @@ +use base64::Engine; use hmac::{Hmac, Mac}; use secrecy::{ExposeSecret, Secret, SecretString}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -25,7 +26,10 @@ impl TwoFactorSecret { pub fn parse_shared_secret(secret: String) -> anyhow::Result { ensure!(!secret.is_empty(), "unable to parse empty shared secret"); - let result: [u8; 20] = base64::decode(secret)?.try_into().unwrap(); + let result: [u8; 20] = base64::engine::general_purpose::STANDARD + .decode(secret)? + .try_into() + .unwrap(); Ok(Self(result.into())) } @@ -67,7 +71,11 @@ impl Serialize for TwoFactorSecret { where S: Serializer, { - serializer.serialize_str(base64::encode(self.0.expose_secret()).as_str()) + serializer.serialize_str( + base64::engine::general_purpose::STANDARD + .encode(self.0.expose_secret()) + .as_str(), + ) } } @@ -152,7 +160,7 @@ fn decode_jwt(jwt: impl AsRef) -> anyhow::Result { ensure!(parts.len() == 3, "Invalid JWT"); let data = parts[1]; - let bytes = base64::decode_config(data, base64::URL_SAFE)?; + let bytes = base64::engine::general_purpose::URL_SAFE.decode(data)?; let json = String::from_utf8(bytes)?; let jwt_data: SteamJwtData = serde_json::from_str(&json)?; Ok(jwt_data) diff --git a/steamguard/src/transport/webapi.rs b/steamguard/src/transport/webapi.rs index 22dab99..63725db 100644 --- a/steamguard/src/transport/webapi.rs +++ b/steamguard/src/transport/webapi.rs @@ -43,7 +43,10 @@ impl Transport for WebApiTransport { let mut req = self.client.request(Req::method(), &url); req = if Req::method() == reqwest::Method::GET { - let encoded = encode_msg(apireq.request_data(), base64::URL_SAFE)?; + let encoded = encode_msg( + apireq.request_data(), + base64::engine::general_purpose::URL_SAFE, + )?; let mut params = vec![("input_protobuf_encoded", encoded.as_str())]; if let Some(access_token) = apireq.access_token() { params.push(("access_token", access_token.expose_secret())); @@ -53,7 +56,10 @@ impl Transport for WebApiTransport { if let Some(access_token) = apireq.access_token() { req = req.query(&[("access_token", access_token)]); } - let encoded = encode_msg(apireq.request_data(), base64::STANDARD)?; + let encoded = encode_msg( + apireq.request_data(), + base64::engine::general_purpose::STANDARD, + )?; let form = Form::new().text("input_protobuf_encoded", encoded); req.multipart(form) }; @@ -119,9 +125,9 @@ impl Transport for WebApiTransport { } } -fn encode_msg(msg: &T, config: base64::Config) -> anyhow::Result { +fn encode_msg(msg: &T, engine: impl base64::Engine) -> anyhow::Result { let bytes = msg.write_to_bytes()?; - let b64 = base64::encode_config(bytes, config); + let b64 = engine.encode(bytes); Ok(b64) } @@ -138,12 +144,13 @@ mod tests { }; use super::*; + use base64::{engine::general_purpose::STANDARD, Engine}; #[test] fn test_parse_poll_response() { let sample = b"GuUDZXlBaWRIbHdJam9nSWtwWFZDSXNJQ0poYkdjaU9pQWlSV1JFVTBFaUlIMC5leUFpYVhOeklqb2dJbk4wWldGdElpd2dJbk4xWWlJNklDSTNOalUyTVRFNU9URTFOVGN3TmpnNU1pSXNJQ0poZFdRaU9pQmJJQ0ozWldJaUxDQWljbVZ1WlhjaUxDQWlaR1Z5YVhabElpQmRMQ0FpWlhod0lqb2dNVGN3TlRBeE1UazFOU3dnSW01aVppSTZJREUyTnpnME5qUTRNemNzSUNKcFlYUWlPaUF4TmpnM01UQTBPRE0zTENBaWFuUnBJam9nSWpFNFF6VmZNakpDTTBZME16RmZRMFJHTmtFaUxDQWliMkYwSWpvZ01UWTROekV3TkRnek55d2dJbkJsY2lJNklERXNJQ0pwY0Y5emRXSnFaV04wSWpvZ0lqWTVMakV5TUM0eE16WXVNVEkwSWl3Z0ltbHdYMk52Ym1acGNtMWxjaUk2SUNJMk9TNHhNakF1TVRNMkxqRXlOQ0lnZlEuR3A1VFBqOXBHUWJ4SXpXREROQ1NQOU9rS1lTZXduV0JFOEUtY1ZxalFxcVQ1M0FzRTRya213OER5TThoVXJ4T0VQQ1dDWHdyYkRVcmgxOTlSempQRHci/gNleUFpZEhsd0lqb2dJa3BYVkNJc0lDSmhiR2NpT2lBaVJXUkVVMEVpSUgwLmV5QWlhWE56SWpvZ0luSTZNVGhETlY4eU1rSXpSalF6TVY5RFJFWTJRU0lzSUNKemRXSWlPaUFpTnpZMU5qRXhPVGt4TlRVM01EWTRPVElpTENBaVlYVmtJam9nV3lBaWQyVmlJaUJkTENBaVpYaHdJam9nTVRZNE56RTVNamM0T0N3Z0ltNWlaaUk2SURFMk56ZzBOalE0TXpjc0lDSnBZWFFpT2lBeE5qZzNNVEEwT0RNM0xDQWlhblJwSWpvZ0lqRXlSREZmTWpKQ00wVTROekZmT1RaRk5EQWlMQ0FpYjJGMElqb2dNVFk0TnpFd05EZ3pOeXdnSW5KMFgyVjRjQ0k2SURFM01EVXdNVEU1TlRVc0lDSndaWElpT2lBd0xDQWlhWEJmYzNWaWFtVmpkQ0k2SUNJMk9TNHhNakF1TVRNMkxqRXlOQ0lzSUNKcGNGOWpiMjVtYVhKdFpYSWlPaUFpTmprdU1USXdMakV6Tmk0eE1qUWlJSDAuMVNnUEotSVZuWEp6Nk9nSW1udUdOQ0hMbEJTcGdvc0Z0UkxoOV9iVVBHQ1RaMmFtRWY2ZTZVYkJzVWZ3bnlYbEdFdG5LSHhPemhibTdLNzBwVFhEQ0EoADIKaHlkcmFzdGFyMg=="; - let bytes = base64::decode_config(sample, base64::STANDARD).unwrap(); + let bytes = STANDARD.decode(sample).unwrap(); let resp: CAuthentication_PollAuthSessionStatus_Response = decode_msg(&bytes).unwrap(); @@ -154,7 +161,7 @@ mod tests { fn parse_get_public_rsa_response() { let sample = b"CoAEYjYyMGI1ZWNhMWIxMjgyYjkxYzZkZmZkYWFhOWI0ODI0YjlhNmRiYmEyZDVmYjc0ODcxNDczZDc1MDYxNGEzNWM4ODQ3NDYzZTEyNjAwNTJmNzZlNTYxMDM5ODdlN2U3NGJkMWZjZGRjYWJhMDVmZGM5OTBjMWIyNmQ2ZDg5MGM2MTEzZmRkNTZmMmQ1YmZjNzU4ODhlMzZhNTM2NjM3N2IzZTE3ZTJiZWM5MjhlNGY4MmE1YzY0NGYxZTZlMTk3NzZkNjIzMDIxYjhmYTA0MGRjNWE5YjY0M2I0N2I5YmVhMjM2YmEyZjM4ODVjM2ZlNWVhNjMzZThlNjJjNGE1YTY4NjNmMzNiMzdlMTQ4M2MwZTUzZTg4ODIzMGFkNTVjNzg5ZmU4Y2NkMjVjNzdiMTkxOTg0ZThjN2JmNWYzNzY2MjI0OGI1NWVmOWM1OGY3NDM5YjA4ZjNhNWJiNzljNTc5ZDE5M2I3NzhmMzFiY2IwYTA3MmVhZWYxOGEyYjljZDY2M2VmYmY2YmRiZDU3MGEyMTNiOTIxNTc4ODk0MjJkMDY3ODFiNTVkY2VjYjQ4NjA4MjUyMmUzZWQyOWM4MjExYzQ5N2Q1YjNhYTk2OGM2MDY1YWFhZTNhNGVmYzZiMGJjNDYyMzMxNmVmYTUxN2JjNzRiZDYzODcxMWU4ZWYSBjAxMDAwMRiQn6Ly3wk="; - let bytes = base64::decode_config(sample, base64::STANDARD).unwrap(); + let bytes = STANDARD.decode(sample).unwrap(); let resp: CAuthentication_GetPasswordRSAPublicKey_Response = decode_msg(&bytes).unwrap(); @@ -165,11 +172,11 @@ mod tests { fn test_decode_encode_roundtrip() { let sample = b"EgpoeWRyYXN0YXIyGtgCRUxaNTBXdHM2Z0kxWlZaVjl6bzRJNFBEcEhTMGRZR3RSNzJPbytqZkR5QmRBUitrbnBUcUVGcGF4NDd1UVdqdUQ1R2hpRC9JanA2cEtGQzlrdUZDdzBFT0RMSFpINERZUG5hci9IMktOZGoxSFNjWEhyemZjNmk1OWpsRE5OTTI0RVllNUEyUjVSdzBoa2lodU14Z1A4NDJESFUxMkgwNWFyYmdRUWp3NFJmVHh6cDBQQlRjdTk4VUViUjJnak1RajlVK3RsYStPdTN6WTQ5K1BKc0szTkpMTVdxWm4vaFZ1dTR3NFprZGhXNVBqNWphb2Flb3J6MG8zbWIvUXo2M0NlNFdwWmUra1lFYUlSa29oUXBaZkliaW4rTWdQcVpNelg4cW4vNDcyNFp5N05mblpETlVBV3RoTkowTkUxSDVESXZ4N0IwRFJHZVBwdk5FbVdqWEJ3PT0g4MCW2tYBOAFCBk1vYmlsZUocCgpHYWxheHkgUzIyEAMYjPz/////////ASCQBA=="; - let bytes = base64::decode_config(sample, base64::STANDARD).unwrap(); + let bytes = STANDARD.decode(sample).unwrap(); let decoded: CAuthentication_BeginAuthSessionViaCredentials_Request = decode_msg(&bytes).expect("Failed to decode"); - let encoded = encode_msg(&decoded, base64::STANDARD).expect("Failed to encode"); + let encoded = encode_msg(&decoded, STANDARD).expect("Failed to encode"); assert_eq!(encoded, String::from_utf8(sample.to_vec()).unwrap()); } diff --git a/steamguard/src/userlogin.rs b/steamguard/src/userlogin.rs index 7e6bc21..9f24b47 100644 --- a/steamguard/src/userlogin.rs +++ b/steamguard/src/userlogin.rs @@ -17,6 +17,7 @@ use crate::steamapi::authentication::AuthenticationClient; use crate::steamapi::EResult; use crate::token::Tokens; use crate::transport::Transport; +use base64::Engine; use log::*; use rsa::{Pkcs1v15Encrypt, RsaPublicKey}; use std::time::Duration; @@ -275,7 +276,7 @@ fn encrypt_password( let mut rng = tests::MockStepRng(rand::rngs::mock::StepRng::new(2, 1)); #[cfg(not(test))] let mut rng = rand::rngs::OsRng; - base64::encode( + base64::engine::general_purpose::STANDARD.encode( public_key .encrypt(&mut rng, Pkcs1v15Encrypt, password.as_ref()) .unwrap(),