From 1698e2d9f809dcd07fffa2f9bc32319a88a272a2 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 26 Aug 2023 12:02:45 +0800 Subject: [PATCH] feat: update base64 version --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cmd_pgpcarddecrypt.rs | 12 +++++++----- src/cmd_pgpcardsign.rs | 7 ++++--- src/cmd_pivecsign.rs | 5 +++-- src/cmd_pivrsasign.rs | 10 ++++++---- src/cmd_u2fregister.rs | 3 ++- src/cmd_u2fsign.rs | 5 +++-- src/fido.rs | 10 ++++++---- src/main.rs | 1 + src/sshutil.rs | 4 +++- src/util.rs | 10 ++++++++++ 12 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 src/util.rs diff --git a/Cargo.lock b/Cargo.lock index b73d899..6b417ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,7 +323,7 @@ name = "card-cli" version = "1.6.0" dependencies = [ "authenticator", - "base64 0.13.1", + "base64 0.21.2", "chrono", "clap", "digest 0.10.7", diff --git a/Cargo.toml b/Cargo.toml index 7b6aa1a..731cc31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ digest = "0.10" sha1 = "0.10" sha2 = "0.10" rand = "0.8" -base64 = "0.13" +base64 = "0.21" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" hex = "0.4" diff --git a/src/cmd_pgpcarddecrypt.rs b/src/cmd_pgpcarddecrypt.rs index 9ce26a9..0e7fc05 100644 --- a/src/cmd_pgpcarddecrypt.rs +++ b/src/cmd_pgpcarddecrypt.rs @@ -1,11 +1,13 @@ use std::collections::BTreeMap; use clap::{App, Arg, ArgMatches, SubCommand}; -use openpgp_card::OpenPgp; use openpgp_card::crypto_data::Cryptogram; +use openpgp_card::OpenPgp; use rust_util::util_clap::{Command, CommandError}; use rust_util::util_msg; +use crate::util::{base64_decode, base64_encode}; + pub struct CommandImpl; impl Command for CommandImpl { @@ -34,7 +36,7 @@ impl Command for CommandImpl { let cipher_bytes = if let Some(cipher) = cipher { opt_result!(hex::decode(cipher), "Decode cipher failed: {}") } else if let Some(cipher_base64) = cipher_base64 { - opt_result!(base64::decode(cipher_base64), "Decode cipher-base64 failed: {}") + opt_result!(base64_decode(cipher_base64), "Decode cipher-base64 failed: {}") } else { return simple_error!("cipher or cipher-base64 must assign one"); }; @@ -48,15 +50,15 @@ impl Command for CommandImpl { let text = trans.decipher(Cryptogram::RSA(&cipher_bytes))?; success!("Clear text HEX: {}", hex::encode(&text)); - success!("Clear text base64: {}", base64::encode(&text)); + success!("Clear text base64: {}", base64_encode(&text)); success!("Clear text UTF-8: {}", String::from_utf8_lossy(&text)); if json_output { let mut json = BTreeMap::<&'_ str, String>::new(); json.insert("cipher_hex", hex::encode(&cipher_bytes)); - json.insert("cipher_base64", base64::encode(&cipher_bytes)); + json.insert("cipher_base64", base64_encode(&cipher_bytes)); json.insert("text_hex", hex::encode(&text)); - json.insert("text_base64", base64::encode(&text)); + json.insert("text_base64", base64_encode(&text)); json.insert("text_utf8", String::from_utf8_lossy(&text).to_string()); println!("{}", serde_json::to_string_pretty(&json).unwrap()); diff --git a/src/cmd_pgpcardsign.rs b/src/cmd_pgpcardsign.rs index 1864051..87c9bcb 100644 --- a/src/cmd_pgpcardsign.rs +++ b/src/cmd_pgpcardsign.rs @@ -9,6 +9,7 @@ use openpgp_card::OpenPgp; use rust_util::util_clap::{Command, CommandError}; use rust_util::{util_msg, XResult}; use sha2::{Sha256, Sha384, Sha512}; +use crate::util::base64_encode; const BUFF_SIZE: usize = 512 * 1024; @@ -89,7 +90,7 @@ impl Command for CommandImpl { success!("User sign pin verify success!"); let sig = trans.signature_for_hash(Hash::SHA256(sha256_hex))?; success!("SHA256 signature HEX: {}", hex::encode(&sig)); - success!("SHA256 signature base64: {}", base64::encode(&sig)); + success!("SHA256 signature base64: {}", base64_encode(&sig)); if json_output { let mut entry = BTreeMap::new(); entry.insert("digest", hex::encode(&sha256_hex)); @@ -104,7 +105,7 @@ impl Command for CommandImpl { success!("User sign pin verify success!"); let sig = trans.signature_for_hash(Hash::SHA384(sha384_hex))?; success!("SHA384 signature HEX: {}", hex::encode(&sig)); - success!("SHA384 signature base64: {}", base64::encode(&sig)); + success!("SHA384 signature base64: {}", base64_encode(&sig)); if json_output { let mut entry = BTreeMap::new(); entry.insert("digest", hex::encode(&sha384_hex)); @@ -119,7 +120,7 @@ impl Command for CommandImpl { success!("User sign pin verify success!"); let sig = trans.signature_for_hash(Hash::SHA512(sha512_hex))?; success!("SHA512 signature HEX: {}", hex::encode(&sig)); - success!("SHA512 signature base64: {}", base64::encode(&sig)); + success!("SHA512 signature base64: {}", base64_encode(&sig)); if json_output { let mut entry = BTreeMap::new(); entry.insert("digest", hex::encode(&sha512_hex)); diff --git a/src/cmd_pivecsign.rs b/src/cmd_pivecsign.rs index 7d239b6..c9420d5 100644 --- a/src/cmd_pivecsign.rs +++ b/src/cmd_pivecsign.rs @@ -9,6 +9,7 @@ use yubikey::YubiKey; use crate::digest::sha256; use crate::pivutil; +use crate::util::base64_encode; pub struct CommandImpl; @@ -77,12 +78,12 @@ impl Command for CommandImpl { json.insert("algorithm", algorithm_str.to_string()); json.insert("hash_hex", hex::encode(&hash_bytes)); json.insert("signed_data_hex", hex::encode(&signed_data.as_bytes())); - json.insert("signed_data_base64", base64::encode(&signed_data.as_bytes())); + json.insert("signed_data_base64", base64_encode(&signed_data.as_bytes())); } else { information!("Slot: {:?}", slot_id); information!("Algorithm: {}", algorithm_str); information!("Hash hex: {}", hex::encode(&hash_bytes)); - information!("Signed data base64: {}", base64::encode(&signed_data.as_bytes())); + information!("Signed data base64: {}", base64_encode(&signed_data.as_bytes())); information!("Signed data hex: {}", hex::encode(&signed_data.as_bytes())); } diff --git a/src/cmd_pivrsasign.rs b/src/cmd_pivrsasign.rs index ec5fe2c..f05bfe3 100644 --- a/src/cmd_pivrsasign.rs +++ b/src/cmd_pivrsasign.rs @@ -1,11 +1,13 @@ use std::collections::BTreeMap; use clap::{App, Arg, ArgMatches, SubCommand}; +use rust_util::{util_msg, XResult}; use rust_util::util_clap::{Command, CommandError}; use rust_util::util_msg::MessageType; -use rust_util::{util_msg, XResult}; -use yubikey::piv::{AlgorithmId, SlotId}; use yubikey::{piv, YubiKey}; +use yubikey::piv::{AlgorithmId, SlotId}; + +use crate::util::base64_encode; pub struct CommandImpl; @@ -61,11 +63,11 @@ impl Command for CommandImpl { let mut json = BTreeMap::<&'_ str, String>::new(); json.insert("hash_hex", hex::encode(&hash)); json.insert("sign_hex", hex::encode(&sign_bytes)); - json.insert("sign_base64", base64::encode(&sign_bytes)); + json.insert("sign_base64", base64_encode(&sign_bytes)); println!("{}", serde_json::to_string_pretty(&json).unwrap()); } else { success!("Signature HEX: {}", hex::encode(sign_bytes)); - success!("Signature base64: {}", base64::encode(sign_bytes)); + success!("Signature base64: {}", base64_encode(sign_bytes)); } } Ok(None) diff --git a/src/cmd_u2fregister.rs b/src/cmd_u2fregister.rs index 710e5f4..4713658 100644 --- a/src/cmd_u2fregister.rs +++ b/src/cmd_u2fregister.rs @@ -16,6 +16,7 @@ use x509_parser::prelude::FromDer; use crate::digest; use crate::fido; use crate::fido::{U2fRegistrationData, U2fV2Challenge}; +use crate::util::base64_encode; pub struct CommandImpl; @@ -119,7 +120,7 @@ impl Command for CommandImpl { } else { success!("Device info: {}", u2f_registration_data.device_info); information!("Register challenge: {}", u2fv2_challenge_str); - information!("Register challenge base64: {}", base64::encode(&u2fv2_challenge_str)); + information!("Register challenge base64: {}", base64_encode(&u2fv2_challenge_str)); if let Some(cert) = u2f_registration_data.attestation_cert_pem { information!("Attestation certificate: {}", cert); } diff --git a/src/cmd_u2fsign.rs b/src/cmd_u2fsign.rs index 7f783b0..04a7723 100644 --- a/src/cmd_u2fsign.rs +++ b/src/cmd_u2fsign.rs @@ -16,6 +16,7 @@ use rust_util::util_clap::{Command, CommandError}; use crate::digest; use crate::fido; use crate::fido::U2fV2Challenge; +use crate::util::base64_encode; pub struct CommandImpl; @@ -123,8 +124,8 @@ impl Command for CommandImpl { json.insert("counter", format!("{}", counter_u32)); } else { information!("Sign challenge: {}", u2fv2_challenge_str); - information!("Sign challenge base64: {}", base64::encode(&u2fv2_challenge_str)); - information!("Sign result : {}", base64::encode(&sign_data)); + information!("Sign challenge base64: {}", base64_encode(&u2fv2_challenge_str)); + information!("Sign result : {}", base64_encode(&sign_data)); information!("- presence : {}", user_presence_flag); information!("- counter : {}", counter_u32); information!("- signature: {}", hex::encode(&signature)); diff --git a/src/fido.rs b/src/fido.rs index 6111c14..c46ee97 100644 --- a/src/fido.rs +++ b/src/fido.rs @@ -4,12 +4,14 @@ use std::thread; use std::time::SystemTime; use authenticator::{RegisterResult, StatusUpdate}; -use base64::URL_SAFE_NO_PAD; +use base64::Engine; +use base64::engine::general_purpose::URL_SAFE_NO_PAD; use rand::Rng; use rust_util::XResult; use serde::{Deserialize, Serialize}; use crate::pkiutil::bytes_to_pem; +use crate::util::base64_encode; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct U2FDeviceInfo { @@ -76,7 +78,7 @@ impl U2fRegistrationData { device_info: U2FDeviceInfo::from(register_result), device_name: registration.device_name, client_data: client_data.into(), - registration_data: base64::encode(®ister_result.0), + registration_data: base64_encode(®ister_result.0), attestation_cert: registration.attestation_cert.clone(), attestation_cert_pem: registration.attestation_cert.map(|cert| { bytes_to_pem("CERTIFICATE", cert) @@ -101,7 +103,7 @@ impl U2fV2Challenge { None => U2fV2Challenge::new_random(app_id, with_time_stamp_prefix), Some(challenge_hex) => { let challenge_bytes = opt_result!(hex::decode(challenge_hex), "Decode challenge hex failed: {}"); - let challenge = base64::encode_config(&challenge_bytes, base64::URL_SAFE_NO_PAD); + let challenge = URL_SAFE_NO_PAD.encode(&challenge_bytes); U2fV2Challenge::new(challenge, app_id) } }) @@ -120,7 +122,7 @@ impl U2fV2Challenge { rand_bytes[..8].clone_from_slice(×tamp_be_bytes[..8]); } - let challenge = base64::encode_config(&rand_bytes, URL_SAFE_NO_PAD); + let challenge = URL_SAFE_NO_PAD.encode(&rand_bytes); Self::new(challenge, app_id) } diff --git a/src/main.rs b/src/main.rs index 40d0b9c..1235432 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ extern crate rust_util; use clap::{App, AppSettings, ArgMatches}; use rust_util::util_clap::{Command, CommandError}; +mod util; mod sshutil; mod fido; mod digest; diff --git a/src/sshutil.rs b/src/sshutil.rs index 5e6d7bc..947b997 100644 --- a/src/sshutil.rs +++ b/src/sshutil.rs @@ -1,3 +1,5 @@ +use crate::util::base64_encode; + pub fn with_sign(mut vec: Vec) -> Vec { if vec.len() > 0 && vec[0] >= 128 { vec.insert(0, 0x00); @@ -10,7 +12,7 @@ pub fn generate_ssh_string(e: &[u8], n: &[u8], comment: &str) -> String { append_slice_with_len(&mut ssh_key, "ssh-rsa".as_bytes()); append_slice_with_len(&mut ssh_key, &with_sign(e.to_vec())); append_slice_with_len(&mut ssh_key, &with_sign(n.to_vec())); - format!("ssh-rsa {} {}", base64::encode(&ssh_key), comment) + format!("ssh-rsa {} {}", base64_encode(&ssh_key), comment) } pub fn append_slice_with_len(v: &mut Vec, s: &[u8]) { diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..c841974 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,10 @@ +use base64::{DecodeError, Engine}; +use base64::engine::general_purpose::STANDARD; + +pub fn base64_encode>(input: T) -> String { + STANDARD.encode(input) +} + +pub fn base64_decode>(input: T) -> Result, DecodeError> { + STANDARD.decode(input) +}