mirror of
https://github.com/LordGrimmauld/yubi-oath-rs.git
synced 2025-03-04 05:44:40 +01:00
more cleanup
This commit is contained in:
parent
76073ac87f
commit
c407fb0e31
3 changed files with 25 additions and 47 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -23,12 +23,6 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5ab921a56bbe68325ba6d3711ee2c681239fe4c9c295c6a1c2fe6992e27f86"
|
checksum = "3c5ab921a56bbe68325ba6d3711ee2c681239fe4c9c295c6a1c2fe6992e27f86"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base32"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.22.1"
|
version = "0.22.1"
|
||||||
|
@ -137,7 +131,6 @@ name = "oath-rs-experiments"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"apdu-core",
|
"apdu-core",
|
||||||
"base32",
|
|
||||||
"base64",
|
"base64",
|
||||||
"hmac",
|
"hmac",
|
||||||
"iso7816-tlv",
|
"iso7816-tlv",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
[dependencies]
|
[dependencies]
|
||||||
apdu-core = "0.4.0"
|
apdu-core = "0.4.0"
|
||||||
base32 = "0.5.1"
|
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
hmac = "0.12.1"
|
hmac = "0.12.1"
|
||||||
iso7816-tlv = "0.4.4"
|
iso7816-tlv = "0.4.4"
|
||||||
|
|
|
@ -4,9 +4,8 @@ mod transaction;
|
||||||
use transaction::*;
|
use transaction::*;
|
||||||
/// Utilities for interacting with YubiKey OATH/TOTP functionality
|
/// Utilities for interacting with YubiKey OATH/TOTP functionality
|
||||||
extern crate pcsc;
|
extern crate pcsc;
|
||||||
use base32::Alphabet;
|
|
||||||
use pbkdf2::pbkdf2_hmac_array;
|
use pbkdf2::pbkdf2_hmac_array;
|
||||||
use regex::Regex;
|
use regex::{Match, Regex};
|
||||||
use sha1::Sha1;
|
use sha1::Sha1;
|
||||||
|
|
||||||
use std::str::{self};
|
use std::str::{self};
|
||||||
|
@ -19,19 +18,6 @@ use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
pub fn parse_b32_key(key: String) -> u32 {
|
|
||||||
let stripped = key.to_uppercase().replace(" ", "");
|
|
||||||
let pad = 8 - (stripped.len() % 8);
|
|
||||||
let padded = stripped + (&"=".repeat(pad));
|
|
||||||
let bytes = base32::decode(Alphabet::Rfc4648 { padding: true }, &padded).unwrap();
|
|
||||||
let mut bytes_array: [u8; 4] = [0, 0, 0, 0];
|
|
||||||
for i in 0..4 {
|
|
||||||
bytes_array[i] = bytes.get(i).map(|x| *x).unwrap_or(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return u32::from_be_bytes(bytes_array); // fixme: be or le?
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CredentialData<'a> {
|
pub struct CredentialData<'a> {
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
oath_type: OathType,
|
oath_type: OathType,
|
||||||
|
@ -135,33 +121,33 @@ fn _format_cred_id(issuer: Option<&str>, name: &str, oath_type: OathType, period
|
||||||
// Function to parse the credential ID
|
// Function to parse the credential ID
|
||||||
fn _parse_cred_id(cred_id: &[u8], oath_type: OathType) -> (Option<String>, String, u64) {
|
fn _parse_cred_id(cred_id: &[u8], oath_type: OathType) -> (Option<String>, String, u64) {
|
||||||
let data = match str::from_utf8(cred_id) {
|
let data = match str::from_utf8(cred_id) {
|
||||||
Ok(d) => d.to_string(),
|
Ok(d) => d,
|
||||||
Err(_) => return (None, String::new(), 0), // Handle invalid UTF-8
|
Err(_) => return (None, String::new(), 0), // Handle invalid UTF-8
|
||||||
};
|
};
|
||||||
|
|
||||||
if oath_type == OathType::Totp {
|
if oath_type == OathType::Totp {
|
||||||
let TOTP_ID_PATTERN = Regex::new(r"^((\d+)/)?(([^:]+):)?(.+)$").unwrap();
|
Regex::new(r"^((\d+)/)?(([^:]+):)?(.+)$")
|
||||||
if let Some(caps) = TOTP_ID_PATTERN.captures(&data) {
|
.ok()
|
||||||
let period_str = caps.get(2).map(|m| m.as_str()).unwrap_or("");
|
.and_then(|r| r.captures(&data))
|
||||||
let period = if !period_str.is_empty() {
|
.map_or((None, data.to_string(), DEFAULT_PERIOD as u64), |caps| {
|
||||||
period_str.parse::<u32>().unwrap_or(DEFAULT_PERIOD)
|
let period = caps
|
||||||
} else {
|
.get(2)
|
||||||
DEFAULT_PERIOD
|
.as_ref()
|
||||||
};
|
.map(Match::as_str)
|
||||||
|
.and_then(|s| s.parse::<u32>().ok())
|
||||||
return (
|
.unwrap_or(DEFAULT_PERIOD);
|
||||||
Some(caps[4].to_string()),
|
return (
|
||||||
caps[5].to_string(),
|
Some(caps[4].to_string()),
|
||||||
period.into(),
|
caps[5].to_string(),
|
||||||
);
|
period.into(),
|
||||||
} else {
|
);
|
||||||
return (None, data, DEFAULT_PERIOD.into());
|
})
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let mut components = data.split(':').rev();
|
return data
|
||||||
let name = components.next().unwrap().to_string();
|
.split_once(':')
|
||||||
let issuer = components.next().map(str::to_string);
|
.map_or((None, data.to_string(), 0), |(i, n)| {
|
||||||
return (issuer, name, 0);
|
(Some(i.to_string()), n.to_string(), 0)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +276,8 @@ impl<'a> OathSession<'a> {
|
||||||
let cred = OathCredential {
|
let cred = OathCredential {
|
||||||
device_id: &self.name,
|
device_id: &self.name,
|
||||||
id: meta.value().to_vec(),
|
id: meta.value().to_vec(),
|
||||||
issuer,
|
issuer: issuer,
|
||||||
name,
|
name: name,
|
||||||
period,
|
period,
|
||||||
touch_required: touch,
|
touch_required: touch,
|
||||||
oath_type,
|
oath_type,
|
||||||
|
|
Loading…
Add table
Reference in a new issue