diff --git a/Cargo.lock b/Cargo.lock index ff76bfd..d10e9e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -508,7 +508,7 @@ dependencies = [ [[package]] name = "card-cli" -version = "1.12.3" +version = "1.12.4" dependencies = [ "aes-gcm-stream", "authenticator 0.3.1", diff --git a/Cargo.toml b/Cargo.toml index f03299a..fd58452 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "card-cli" -version = "1.12.3" +version = "1.12.4" authors = ["Hatter Jiang "] edition = "2018" diff --git a/src/hmacutil.rs b/src/hmacutil.rs index 3ba5606..76be399 100644 --- a/src/hmacutil.rs +++ b/src/hmacutil.rs @@ -10,7 +10,7 @@ use yubico_manager::sec::hmac_sha1; use yubico_manager::Yubico; use crate::digestutil::{copy_sha256, sha256_bytes}; use crate::util; -use crate::util::{base64_decode, base64_encode}; +use crate::util::{base64_decode, base64_encode, base64_encode_url_safe_no_pad, base64_uri_decode}; const HMAC_ENC_PREFIX: &str = "hmac_enc:"; @@ -34,8 +34,8 @@ pub fn hmac_encrypt(plaintext: &[u8]) -> XResult { Ok(format!("{}{}:{}:{}", HMAC_ENC_PREFIX, - hex::encode(hmac_nonce), - hex::encode(aes_gcm_nonce), + base64_encode_url_safe_no_pad(hmac_nonce), + base64_encode_url_safe_no_pad(aes_gcm_nonce), base64_encode(&ciphertext) )) } @@ -62,8 +62,8 @@ pub fn hmac_decrypt(ciphertext: &str) -> XResult> { return simple_error!("Invalid ciphertext: {}", ciphertext); } let parts = ciphertext.split(":").collect::>(); - let hmac_nonce = hex::decode(parts[1])?; - let aes_gcm_nonce = hex::decode(parts[2])?; + let hmac_nonce = try_decode_hmac_val(parts[1])?; + let aes_gcm_nonce = try_decode_hmac_val(parts[2])?; let ciphertext = base64_decode(parts[3])?; let hmac_key = compute_yubikey_hmac(&hmac_nonce)?; @@ -77,6 +77,16 @@ pub fn hmac_decrypt(ciphertext: &str) -> XResult> { Ok(plaintext) } +fn try_decode_hmac_val(s: &str) -> XResult> { + match hex::decode(s) { + Ok(v) => Ok(v), + Err(e) => match base64_uri_decode(s) { + Ok(v) => Ok(v), + Err(_) => simple_error!("Try decode failed: {}", e) + } + } +} + pub fn compute_yubikey_hmac(challenge_bytes: &[u8]) -> XResult> { let mut yubi = Yubico::new(); let device = match yubi.find_yubikey() {