use super::*;
use std::io::Cursor;
use tokio::time::{sleep,Duration};
#[cfg(target_os="linux")]
pub async fn get_key_ans_certs(
key_path: &str,
cert_path: &str,
)->(Vec<u8>,Vec<u8>) {
tracing::info!("get_key_ans_certs");
loop {
let media_path=std::path::Path::new(&format!("/media/{}",std::env::var("USER").unwrap())).to_path_buf();
let dir_content = tokio::fs::read_dir(&media_path).await;
if let Ok(mut dir_content)=dir_content {
loop {
let entry = dir_content.next_entry().await;
if !entry.is_ok() {
continue;
}
let entry= entry.unwrap();
if entry.is_none() {
break;
}
let file_path = entry.unwrap().path();
if file_path.is_dir() {
let key_path=file_path.join(key_path);
let cert_path=file_path.join(cert_path);
tracing::info!("checking {} and {}...",key_path.display(),cert_path.display());
if key_path.is_file() && cert_path.is_file() {
if let Ok(cert_pem)= tokio::fs::read(&cert_path).await {
if let Ok(key_pem) = tokio::fs::read(&key_path).await {
return (key_pem,cert_pem);
}
}
}
tracing::info!("not found.");
}
}
}
sleep(Duration::from_secs(1)).await;
}
}
#[cfg(target_os="windows")]
use winapi::um::fileapi::{GetLogicalDrives, GetDriveTypeW};
#[cfg(target_os="windows")]
use winapi::um::winbase::{DRIVE_REMOVABLE, DRIVE_NO_ROOT_DIR, };
#[cfg(target_os="windows")]
pub async fn get_key_ans_certs(
key_path: &str,
cert_path: &str,
)->(Vec<u8>,Vec<u8>) {
tracing::info!("get_key_ans_certs");
loop {
let drives = unsafe { GetLogicalDrives() };
for i in 0..26 {
let drive_number = 1 << i;
if drives & drive_number != 0 {
let drive_name = format!("{}:\\", (b'A' + i) as char);
let drive_type = unsafe { GetDriveTypeW(drive_name.as_ptr() as *const u16) };
if drive_type == DRIVE_REMOVABLE || drive_type == DRIVE_NO_ROOT_DIR {
let key_path=std::path::Path::new(&drive_name).join(key_path);
let cert_path=std::path::Path::new(&drive_name).join(cert_path);
tracing::info!("checking {} and {}...",key_path.display(),cert_path.display());
if key_path.is_file() && cert_path.is_file() {
if let Ok(cert_pem)= tokio::fs::read(&cert_path).await {
if let Ok(key_pem) = tokio::fs::read(&key_path).await {
return (key_pem,cert_pem);
}
}
}
}
}
}
sleep(Duration::from_secs(1)).await;
}
}
pub struct InsecureRemovableMediaKeyProvider {
private_key: rustls::pki_types::PrivatePkcs8KeyDer<'static>,
certificates: Vec<rustls::pki_types::CertificateDer<'static>>,
}
impl InsecureRemovableMediaKeyProvider {
pub async fn new(key_path: &str,cert_path: &str)->anyhow::Result<Box<dyn KeyProvider>> {
let (mut pkey_pem,mut certs_pem)=get_key_ans_certs(key_path,cert_path).await;
let certificates =
rustls_pemfile::certs(&mut Cursor::new(&mut certs_pem))
.into_iter()
.filter_map(|x| x.ok())
.collect::<Vec<_>>();
let private_key =
rustls_pemfile::pkcs8_private_keys(&mut Cursor::new(&mut pkey_pem))
.filter_map(|x| x.ok())
.next();
if private_key.is_none() {
return Err(anyhow::anyhow!(
"No valid key found in {}",
key_path
));
}
let private_key = private_key.unwrap();
Ok(Box::new(Self {
private_key,
certificates,
}))
}
}
impl KeyProvider for InsecureRemovableMediaKeyProvider {
fn get_private_key(&self)->&'_ rustls::pki_types::PrivatePkcs8KeyDer<'static> {
&self.private_key
}
fn get_certificates(&self)->&'_ Vec<rustls::pki_types::CertificateDer<'static>> {
&self.certificates
}
}