opgpcard: Make the KeySlots type safe

This commit is contained in:
Nora Widdecke 2022-10-24 23:06:16 +02:00
parent af9d4f49ad
commit 9dd4f3ab56
No known key found for this signature in database
GPG key ID: 2D4111B31DBB99B6
2 changed files with 60 additions and 31 deletions

View file

@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name> // SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
use clap::{AppSettings, Parser}; use clap::{AppSettings, Parser, ValueEnum};
use std::path::PathBuf; use std::path::PathBuf;
use crate::{OutputFormat, OutputVersion}; use crate::{OutputFormat, OutputVersion};
@ -204,8 +204,8 @@ pub enum AdminCommand {
/// Set touch policy /// Set touch policy
Touch { Touch {
#[clap(name = "Key slot (SIG|DEC|AUT|ATT)", short = 'k', long = "key")] #[clap(name = "Key slot", short = 'k', long = "key", value_enum)]
key: String, key: BasePlusAttKeySlot,
#[clap( #[clap(
name = "Policy (Off|On|Fixed|Cached|Cached-Fixed)", name = "Policy (Off|On|Fixed|Cached|Cached-Fixed)",
@ -277,8 +277,8 @@ pub enum AttCommand {
#[clap(name = "card ident", short = 'c', long = "card")] #[clap(name = "card ident", short = 'c', long = "card")]
ident: String, ident: String,
#[clap(name = "Key slot (SIG|DEC|AUT)", short = 'k', long = "key")] #[clap(name = "Key slot", short = 'k', long = "key", value_enum)]
key: String, key: BaseKeySlot,
#[clap(name = "User PIN file", short = 'p', long = "user-pin")] #[clap(name = "User PIN file", short = 'p', long = "user-pin")]
user_pin: Option<PathBuf>, user_pin: Option<PathBuf>,
@ -290,7 +290,47 @@ pub enum AttCommand {
#[clap(name = "card ident", short = 'c', long = "card")] #[clap(name = "card ident", short = 'c', long = "card")]
ident: Option<String>, ident: Option<String>,
#[clap(name = "Key slot (SIG|DEC|AUT)", short = 'k', long = "key")] #[clap(name = "Key slot", short = 'k', long = "key", value_enum)]
key: String, key: BaseKeySlot,
}, },
} }
#[derive(ValueEnum, Debug, Clone)]
#[clap(rename_all = "UPPER")]
pub enum BaseKeySlot {
Sig,
Dec,
Aut,
}
impl From<BaseKeySlot> for openpgp_card_sequoia::types::KeyType {
fn from(ks: BaseKeySlot) -> Self {
use openpgp_card_sequoia::types::KeyType;
match ks {
BaseKeySlot::Sig => KeyType::Signing,
BaseKeySlot::Dec => KeyType::Decryption,
BaseKeySlot::Aut => KeyType::Authentication,
}
}
}
#[derive(ValueEnum, Debug, Clone)]
#[clap(rename_all = "UPPER")]
pub enum BasePlusAttKeySlot {
Sig,
Dec,
Aut,
Att,
}
impl From<BasePlusAttKeySlot> for openpgp_card_sequoia::types::KeyType {
fn from(ks: BasePlusAttKeySlot) -> Self {
use openpgp_card_sequoia::types::KeyType;
match ks {
BasePlusAttKeySlot::Sig => KeyType::Signing,
BasePlusAttKeySlot::Dec => KeyType::Decryption,
BasePlusAttKeySlot::Aut => KeyType::Authentication,
BasePlusAttKeySlot::Att => KeyType::Attestation,
}
}
}

View file

@ -3,6 +3,7 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clap::Parser; use clap::Parser;
use cli::BaseKeySlot;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use sequoia_openpgp::cert::prelude::ValidErasedKeyAmalgamation; use sequoia_openpgp::cert::prelude::ValidErasedKeyAmalgamation;
@ -128,14 +129,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut sign = util::verify_to_sign(&mut open, user_pin.as_deref())?; let mut sign = util::verify_to_sign(&mut open, user_pin.as_deref())?;
let kt = match key.as_str() { let kt = KeyType::from(key);
"SIG" => KeyType::Signing,
"DEC" => KeyType::Decryption,
"AUT" => KeyType::Authentication,
_ => {
return Err(anyhow!("Unexpected Key Type {}", key).into());
}
};
sign.generate_attestation(kt, &|| { sign.generate_attestation(kt, &|| {
println!("Touch confirmation needed to generate an attestation") println!("Touch confirmation needed to generate an attestation")
})?; })?;
@ -160,13 +154,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
// Select cardholder certificate // Select cardholder certificate
match key.as_str() { match key {
"AUT" => open.select_data(0, &[0x7F, 0x21], select_data_workaround)?, BaseKeySlot::Aut => {
"DEC" => open.select_data(1, &[0x7F, 0x21], select_data_workaround)?, open.select_data(0, &[0x7F, 0x21], select_data_workaround)?
"SIG" => open.select_data(2, &[0x7F, 0x21], select_data_workaround)?, }
BaseKeySlot::Dec => {
_ => { open.select_data(1, &[0x7F, 0x21], select_data_workaround)?
return Err(anyhow!("Unexpected Key Type {}", key).into()); }
BaseKeySlot::Sig => {
open.select_data(2, &[0x7F, 0x21], select_data_workaround)?
} }
}; };
@ -337,15 +333,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
)?; )?;
} }
cli::AdminCommand::Touch { key, policy } => { cli::AdminCommand::Touch { key, policy } => {
let kt = match key.as_str() { let kt = KeyType::from(key);
"SIG" => KeyType::Signing,
"DEC" => KeyType::Decryption,
"AUT" => KeyType::Authentication,
"ATT" => KeyType::Attestation,
_ => {
return Err(anyhow!("Unexpected Key Type {}", key).into());
}
};
let pol = match policy.as_str() { let pol = match policy.as_str() {
"Off" => TouchPolicy::Off, "Off" => TouchPolicy::Off,
"On" => TouchPolicy::On, "On" => TouchPolicy::On,