opgpcard: Extract sign command into module
This commit is contained in:
parent
9e5e30cea4
commit
3615087065
4 changed files with 73 additions and 59 deletions
|
@ -78,21 +78,7 @@ pub enum Command {
|
|||
Decrypt(commands::decrypt::DecryptCommand),
|
||||
|
||||
/// Sign data using a card
|
||||
Sign {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
ident: String,
|
||||
|
||||
/// User PIN file
|
||||
#[clap(short = 'p', long = "user-pin")]
|
||||
user_pin: Option<PathBuf>,
|
||||
|
||||
#[clap(name = "detached", short = 'd', long = "detached")]
|
||||
detached: bool,
|
||||
|
||||
/// Input file (stdin if unset)
|
||||
#[clap(name = "input")]
|
||||
input: Option<PathBuf>,
|
||||
},
|
||||
Sign(commands::sign::SignCommand),
|
||||
|
||||
/// Attestation management (Yubico)
|
||||
Attestation {
|
||||
|
|
|
@ -5,5 +5,6 @@
|
|||
pub mod decrypt;
|
||||
pub mod info;
|
||||
pub mod pubkey;
|
||||
pub mod sign;
|
||||
pub mod ssh;
|
||||
pub mod status;
|
||||
|
|
68
tools/src/bin/opgpcard/commands/sign.rs
Normal file
68
tools/src/bin/opgpcard/commands/sign.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
|
||||
// SPDX-FileCopyrightText: 2022 Nora Widdecke <mail@nora.pink>
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::Parser;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use sequoia_openpgp::serialize::stream::{Armorer, Message, Signer};
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
|
||||
use crate::util;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct SignCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
pub ident: String,
|
||||
|
||||
/// User PIN file
|
||||
#[clap(short = 'p', long = "user-pin")]
|
||||
pub user_pin: Option<PathBuf>,
|
||||
|
||||
#[clap(name = "detached", short = 'd', long = "detached")]
|
||||
pub detached: bool,
|
||||
|
||||
/// Input file (stdin if unset)
|
||||
#[clap(name = "input")]
|
||||
pub input: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub fn sign(command: SignCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if command.detached {
|
||||
sign_detached(&command.ident, command.user_pin, command.input.as_deref())
|
||||
} else {
|
||||
Err(anyhow::anyhow!("Only detached signatures are supported for now").into())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign_detached(
|
||||
ident: &str,
|
||||
pin_file: Option<PathBuf>,
|
||||
input: Option<&Path>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut input = util::open_or_stdin(input)?;
|
||||
|
||||
let backend = util::open_card(ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
|
||||
if open.fingerprints()?.signature().is_none() {
|
||||
return Err(anyhow!("Can't sign: this card has no key in the signing slot.").into());
|
||||
}
|
||||
|
||||
let user_pin = util::get_pin(&mut open, pin_file, crate::ENTER_USER_PIN);
|
||||
|
||||
let mut sign = util::verify_to_sign(&mut open, user_pin.as_deref())?;
|
||||
let s = sign.signer(&|| println!("Touch confirmation needed for signing"))?;
|
||||
|
||||
let message = Armorer::new(Message::new(std::io::stdout())).build()?;
|
||||
let mut signer = Signer::new(message, s).detached().build()?;
|
||||
|
||||
std::io::copy(&mut input, &mut signer)?;
|
||||
signer.finalize()?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -5,14 +5,13 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use clap::Parser;
|
||||
use cli::BaseKeySlot;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use sequoia_openpgp::cert::prelude::ValidErasedKeyAmalgamation;
|
||||
use sequoia_openpgp::packet::key::{SecretParts, UnspecifiedRole};
|
||||
use sequoia_openpgp::packet::Key;
|
||||
use sequoia_openpgp::parse::Parse;
|
||||
use sequoia_openpgp::policy::{Policy, StandardPolicy};
|
||||
use sequoia_openpgp::serialize::stream::{Armorer, Message, Signer};
|
||||
use sequoia_openpgp::serialize::SerializeInto;
|
||||
use sequoia_openpgp::types::{HashAlgorithm, SymmetricAlgorithm};
|
||||
use sequoia_openpgp::Cert;
|
||||
|
@ -67,19 +66,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
cli::Command::Decrypt(cmd) => {
|
||||
commands::decrypt::decrypt(cmd)?;
|
||||
}
|
||||
cli::Command::Sign {
|
||||
ident,
|
||||
user_pin,
|
||||
detached,
|
||||
input,
|
||||
} => {
|
||||
if detached {
|
||||
sign_detached(&ident, user_pin, input.as_deref())?;
|
||||
} else {
|
||||
return Err(
|
||||
anyhow::anyhow!("Only detached signatures are supported for now").into(),
|
||||
);
|
||||
}
|
||||
cli::Command::Sign(cmd) => {
|
||||
commands::sign::sign(cmd)?;
|
||||
}
|
||||
cli::Command::Attestation { cmd } => match cmd {
|
||||
cli::AttCommand::Cert { ident } => {
|
||||
|
@ -591,35 +579,6 @@ fn pick_card_for_reading(ident: Option<String>) -> Result<Box<dyn CardBackend +
|
|||
}
|
||||
}
|
||||
|
||||
fn sign_detached(
|
||||
ident: &str,
|
||||
pin_file: Option<PathBuf>,
|
||||
input: Option<&Path>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut input = util::open_or_stdin(input)?;
|
||||
|
||||
let backend = util::open_card(ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
|
||||
if open.fingerprints()?.signature().is_none() {
|
||||
return Err(anyhow!("Can't sign: this card has no key in the signing slot.").into());
|
||||
}
|
||||
|
||||
let user_pin = util::get_pin(&mut open, pin_file, ENTER_USER_PIN);
|
||||
|
||||
let mut sign = util::verify_to_sign(&mut open, user_pin.as_deref())?;
|
||||
let s = sign.signer(&|| println!("Touch confirmation needed for signing"))?;
|
||||
|
||||
let message = Armorer::new(Message::new(std::io::stdout())).build()?;
|
||||
let mut signer = Signer::new(message, s).detached().build()?;
|
||||
|
||||
std::io::copy(&mut input, &mut signer)?;
|
||||
signer.finalize()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn factory_reset(ident: &str) -> Result<()> {
|
||||
println!("Resetting Card {}", ident);
|
||||
let card = util::open_card(ident)?;
|
||||
|
|
Loading…
Reference in a new issue