This commit is contained in:
Heiko Schaefer 2021-07-10 22:09:11 +02:00
parent 2343bd8310
commit 1187e816d0
4 changed files with 25 additions and 45 deletions

View file

@ -15,7 +15,6 @@ documentation = "https://docs.rs/crate/openpgp-card-sequoia"
sequoia-openpgp = "1.3" sequoia-openpgp = "1.3"
openpgp-card = { path = "../openpgp-card", version = "0.0.1" } openpgp-card = { path = "../openpgp-card", version = "0.0.1" }
openpgp-card-scdc = { path = "../scdc" } openpgp-card-scdc = { path = "../scdc" }
tokio = "0.2"
chrono = "0.4" chrono = "0.4"
anyhow = "1" anyhow = "1"
thiserror = "1" thiserror = "1"

View file

@ -24,7 +24,6 @@ const TEST_ENC_MSG: &str = "example/encrypted_to_rsa4k.asc";
const SOCKET: &str = "/run/user/1000/gnupg/S.scdaemon"; const SOCKET: &str = "/run/user/1000/gnupg/S.scdaemon";
// #[tokio::main]
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
env_logger::init(); env_logger::init();

View file

@ -26,8 +26,6 @@ pub(crate) fn upload_key(
key_type: KeyType, key_type: KeyType,
algo_list: Option<AlgoInfo>, algo_list: Option<AlgoInfo>,
) -> Result<(), OpenpgpCardError> { ) -> Result<(), OpenpgpCardError> {
println!("upload key");
let (algo_cmd, key_cmd) = match key.get_key()? { let (algo_cmd, key_cmd) = match key.get_key()? {
PrivateKeyMaterial::R(rsa_key) => { PrivateKeyMaterial::R(rsa_key) => {
// RSA bitsize // RSA bitsize

View file

@ -1,17 +1,17 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use futures::StreamExt; use futures::StreamExt;
use lazy_static::lazy_static;
use sequoia_ipc::assuan::{Client, Response}; use sequoia_ipc::assuan::{Client, Response};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use lazy_static::lazy_static;
use openpgp_card::card_app::CardApp; use openpgp_card::card_app::CardApp;
use openpgp_card::errors::OpenpgpCardError; use openpgp_card::errors::OpenpgpCardError;
use openpgp_card::{CardBase, CardCaps, CardClient}; use openpgp_card::{CardBase, CardCaps, CardClient};
lazy_static! { lazy_static! {
pub(crate) static ref RT: Mutex<Runtime> = pub(crate) static ref RT: Mutex<Runtime> =
{ Mutex::new(tokio::runtime::Runtime::new().unwrap()) }; Mutex::new(tokio::runtime::Runtime::new().unwrap());
} }
pub struct ScdClient { pub struct ScdClient {
@ -22,20 +22,14 @@ impl ScdClient {
/// Create a CardBase object that uses an scdaemon instance as its /// Create a CardBase object that uses an scdaemon instance as its
/// backend. /// backend.
pub fn open_scdc(socket: &str) -> Result<CardBase, OpenpgpCardError> { pub fn open_scdc(socket: &str) -> Result<CardBase, OpenpgpCardError> {
println!("open_scdc");
let card_client = ScdClient::new(socket)?; let card_client = ScdClient::new(socket)?;
let card_client_box =
let ccb = Box::new(card_client) as Box<dyn CardClient + Send + Sync>; Box::new(card_client) as Box<dyn CardClient + Send + Sync>;
println!("get ard");
// read and cache "application related data" // read and cache "application related data"
let mut card_app = CardApp::new(ccb); let mut card_app = CardApp::new(card_client_box);
let ard = card_app.get_app_data()?; let ard = card_app.get_app_data()?;
println!("got ard");
// Determine chaining/extended length support from card // Determine chaining/extended length support from card
// metadata and cache this information in CardApp (as a // metadata and cache this information in CardApp (as a
// CardCaps) // CardCaps)
@ -59,6 +53,7 @@ impl ScdClient {
}; };
let caps = CardCaps::new(ext_support, chaining_support, max_cmd_bytes); let caps = CardCaps::new(ext_support, chaining_support, max_cmd_bytes);
let card_app = card_app.set_caps(caps); let card_app = card_app.set_caps(caps);
Ok(CardBase::new(card_app, ard)) Ok(CardBase::new(card_app, ard))
@ -69,47 +64,36 @@ impl ScdClient {
let client = Arc::new(Mutex::new(client)); let client = Arc::new(Mutex::new(client));
Ok(Self { client }) Ok(Self { client })
} }
}
async fn transmit_async(&mut self, cmd: &[u8]) -> Result<Vec<u8>> { impl CardClient for ScdClient {
fn transmit(&mut self, cmd: &[u8], _: usize) -> Result<Vec<u8>> {
let hex = hex::encode(cmd); let hex = hex::encode(cmd);
let mut client = self.client.lock().unwrap(); let mut client = self.client.lock().unwrap();
let mut res = None;
{
let send = format!("APDU {}\n", hex); let send = format!("APDU {}\n", hex);
println!("send: '{}'", send); println!("send: '{}'", send);
client.send(send)?; client.send(send)?;
while let Some(response) = client.next().await { let mut rt = RT.lock().unwrap();
println!("res: {:?}", response);
while let Some(response) = rt.block_on(client.next()) {
println!("res: {:x?}", response);
if let Ok(Response::Data { partial }) = response { if let Ok(Response::Data { partial }) = response {
res = Some(partial); let res = partial;
// drop remaining lines // drop remaining lines
while let Some(_) = client.next().await {} while let Some(drop) = rt.block_on(client.next()) {
println!("drop: {:x?}", drop);
break;
} }
println!();
return Ok(res);
} }
} }
match res { Err(anyhow!("no response found"))
Some(s) => Ok(s),
None => Err(anyhow!("no response found")),
}
}
}
impl CardClient for ScdClient {
fn transmit(&mut self, cmd: &[u8], _buf_size: usize) -> Result<Vec<u8>> {
let mut res = None;
{
res = Some(RT.lock().unwrap().block_on(self.transmit_async(cmd)));
}
res.unwrap()
} }
} }