openpgp-card/tools/src/bin/opgpcard/util.rs

112 lines
3.2 KiB
Rust

// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
use anyhow::{anyhow, Context, Result};
use std::path::{Path, PathBuf};
use openpgp_card::Error;
use openpgp_card_pcsc::PcscCard;
use openpgp_card_sequoia::card::{Admin, Open, Sign, User};
pub(crate) fn cards() -> Result<Vec<PcscCard>, Error> {
PcscCard::cards(None)
}
pub(crate) fn open_card(ident: &str) -> Result<PcscCard, Error> {
PcscCard::open_by_ident(ident, None)
}
pub(crate) fn verify_to_user<'app, 'open>(
open: &'app mut Open<'app>,
pin_file: Option<PathBuf>,
) -> Result<User<'app, 'open>, Box<dyn std::error::Error>> {
if let Some(path) = pin_file {
open.verify_user(&load_pin(&path)?)?;
} else {
if !open.feature_pinpad_verify() {
return Err(anyhow!(
"No user PIN file provided, and no pinpad found"
)
.into());
};
open.verify_user_pinpad(&|| {
println!("Enter user PIN on card reader pinpad.")
})?;
}
open.user_card()
.ok_or_else(|| anyhow!("Couldn't get user access").into())
}
pub(crate) fn verify_to_sign<'app, 'open>(
open: &'app mut Open<'app>,
pin_file: Option<PathBuf>,
) -> Result<Sign<'app, 'open>, Box<dyn std::error::Error>> {
if let Some(path) = pin_file {
open.verify_user_for_signing(&load_pin(&path)?)?;
} else {
if !open.feature_pinpad_verify() {
return Err(anyhow!(
"No user PIN file provided, and no pinpad found"
)
.into());
}
open.verify_user_for_signing_pinpad(&|| {
println!("Enter user PIN on card reader pinpad.")
})?;
}
open.signing_card()
.ok_or_else(|| anyhow!("Couldn't get sign access").into())
}
// pub fn admin_card<'b>(&'b mut self) -> Option<Admin<'a, 'b>> {
pub(crate) fn verify_to_admin<'app, 'open>(
open: &'open mut Open<'app>,
pin_file: Option<PathBuf>,
) -> Result<Admin<'app, 'open>, Box<dyn std::error::Error>> {
if let Some(path) = pin_file {
open.verify_admin(&load_pin(&path)?)?;
} else {
if !open.feature_pinpad_verify() {
return Err(anyhow!(
"No admin PIN file provided, and no pinpad found"
)
.into());
}
open.verify_admin_pinpad(&|| {
println!("Enter admin PIN on card reader pinpad.")
})?;
}
open.admin_card()
.ok_or_else(|| anyhow!("Couldn't get admin access").into())
}
pub(crate) fn load_pin(pin_file: &Path) -> Result<String> {
let pin = std::fs::read_to_string(pin_file)?;
Ok(pin.trim().to_string())
}
pub(crate) fn open_or_stdin(
f: Option<&Path>,
) -> Result<Box<dyn std::io::Read + Send + Sync>> {
match f {
Some(f) => Ok(Box::new(
std::fs::File::open(f).context("Failed to open input file")?,
)),
None => Ok(Box::new(std::io::stdin())),
}
}
pub(crate) fn open_or_stdout(
f: Option<&Path>,
) -> Result<Box<dyn std::io::Write + Send + Sync>> {
match f {
Some(f) => Ok(Box::new(
std::fs::File::create(f).context("Failed to open input file")?,
)),
None => Ok(Box::new(std::io::stdout())),
}
}