mirror of
https://github.com/LordGrimmauld/yubi-oath-rs.git
synced 2025-03-04 05:44:40 +01:00
more progress
This commit is contained in:
parent
6350e1f6d1
commit
0f74a0945c
2 changed files with 39 additions and 19 deletions
|
@ -2,37 +2,31 @@ extern crate byteorder;
|
||||||
/// 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 base32::Alphabet;
|
||||||
use core::borrow;
|
|
||||||
use iso7816_tlv::simple::{Tag as TlvTag, Tlv};
|
use iso7816_tlv::simple::{Tag as TlvTag, Tlv};
|
||||||
|
use once_cell::unsync::OnceCell;
|
||||||
use openssl::hash::MessageDigest;
|
use openssl::hash::MessageDigest;
|
||||||
use openssl::version;
|
|
||||||
use ouroboros::self_referencing;
|
use ouroboros::self_referencing;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::mem::transmute_copy;
|
use std::collections::HashMap;
|
||||||
use std::str::{self, FromStr};
|
use std::str::{self};
|
||||||
|
|
||||||
use once_cell::unsync::OnceCell;
|
|
||||||
|
|
||||||
use apdu_core::{Command, Response};
|
use apdu_core::{Command, Response};
|
||||||
|
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
use openssl::pkcs5::pbkdf2_hmac;
|
use openssl::pkcs5::pbkdf2_hmac;
|
||||||
use pcsc::{Card, Context, Transaction};
|
use pcsc::{Card, Transaction};
|
||||||
use sha1::Sha1;
|
use sha1::Sha1;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
|
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::io::{Cursor, Read, Write};
|
use std::io::{Cursor, Read};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
pub type DetectResult<'a> = Result<Vec<YubiKey<'a>>, pcsc::Error>;
|
|
||||||
|
|
||||||
pub const INS_SELECT: u8 = 0xa4;
|
pub const INS_SELECT: u8 = 0xa4;
|
||||||
pub const OATH_AID: [u8; 7] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x21, 0x01];
|
pub const OATH_AID: [u8; 7] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x21, 0x01];
|
||||||
|
|
||||||
|
@ -522,11 +516,16 @@ impl TransactionContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OathSession<'a> {
|
pub struct OathSession<'a> {
|
||||||
version: OnceCell<&'a str>,
|
version: &'a [u8],
|
||||||
transaction_context: TransactionContext,
|
transaction_context: TransactionContext,
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_with_lifetime<'a>(data: &'a [u8]) -> Vec<u8> {
|
||||||
|
// Clone the slice into a new Vec<u8>
|
||||||
|
data.to_vec() // `to_vec()` will return a Vec<u8> that has its own ownership
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> OathSession<'a> {
|
impl<'a> OathSession<'a> {
|
||||||
pub fn new(name: &'a str) -> Self {
|
pub fn new(name: &'a str) -> Self {
|
||||||
let transaction_context = TransactionContext::from_name(name);
|
let transaction_context = TransactionContext::from_name(name);
|
||||||
|
@ -534,19 +533,24 @@ impl<'a> OathSession<'a> {
|
||||||
.apdu_read_all(0, INS_SELECT, 0x04, 0, Some(&OATH_AID))
|
.apdu_read_all(0, INS_SELECT, 0x04, 0, Some(&OATH_AID))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let info_map = tlv_to_map(info_buffer);
|
||||||
|
for (tag, data) in &info_map {
|
||||||
|
// Printing tag and data
|
||||||
|
println!("{:?}: {:?}", tag, data);
|
||||||
|
}
|
||||||
|
|
||||||
OathSession {
|
OathSession {
|
||||||
version: OnceCell::new(),
|
version: clone_with_lifetime(
|
||||||
|
info_map.get(&(Tag::Version as u8)).unwrap_or(&vec![0u8; 0]),
|
||||||
|
)
|
||||||
|
.leak(),
|
||||||
name,
|
name,
|
||||||
transaction_context,
|
transaction_context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_version(&self) -> &'a str {
|
pub fn get_version(&self) -> &[u8] {
|
||||||
return "test";
|
self.version
|
||||||
}
|
|
||||||
|
|
||||||
fn get_version(&self) -> &'a str {
|
|
||||||
*self.version.get_or_init(|| self.fetch_version())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the OATH codes from the device
|
/// Read the OATH codes from the device
|
||||||
|
@ -668,6 +672,21 @@ fn to_tlv(tag: Tag, value: &[u8]) -> Vec<u8> {
|
||||||
.to_vec()
|
.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tlv_to_map(data: Vec<u8>) -> HashMap<u8, Vec<u8>> {
|
||||||
|
let mut buf: &[u8] = data.leak();
|
||||||
|
let mut parsed_manual = HashMap::new();
|
||||||
|
while !buf.is_empty() {
|
||||||
|
let (r, remaining) = Tlv::parse(buf);
|
||||||
|
buf = remaining;
|
||||||
|
if let Ok(res) = r {
|
||||||
|
parsed_manual.insert(res.tag().into(), res.value().to_vec());
|
||||||
|
} else {
|
||||||
|
break; // Exit if parsing fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsed_manual;
|
||||||
|
}
|
||||||
|
|
||||||
fn time_challenge(timestamp: Option<SystemTime>) -> Vec<u8> {
|
fn time_challenge(timestamp: Option<SystemTime>) -> Vec<u8> {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let ts = match timestamp {
|
let ts = match timestamp {
|
||||||
|
|
|
@ -36,6 +36,7 @@ fn main() {
|
||||||
let device_label: &str = yubikey;
|
let device_label: &str = yubikey;
|
||||||
println!("Found device with label {}", device_label);
|
println!("Found device with label {}", device_label);
|
||||||
let session = OathSession::new(yubikey);
|
let session = OathSession::new(yubikey);
|
||||||
|
println!("YubiKey version is {:?}", session.get_version());
|
||||||
let codes = match session.get_oath_codes() {
|
let codes = match session.get_oath_codes() {
|
||||||
Ok(codes) => codes,
|
Ok(codes) => codes,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue