Implement 'opgpcard admin touch' to set the touch confirmation policy.

This commit is contained in:
Heiko Schaefer 2022-05-29 21:27:52 +02:00
parent bc58a346c2
commit f9d69dbefb
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
3 changed files with 72 additions and 3 deletions

View file

@ -127,7 +127,7 @@ Authentication key
Remaining PIN attempts: User: 3, Admin: 3, Reset Code: 0
Touch policy attestation: Cached [Features: Button]
Touch policy attestation: Cached [Features: Button]
Key Status (#129): imported
```
@ -291,6 +291,37 @@ for non-interactive use.
Alternatively, the PIN can be entered interactively on the host computer, or via a pinpad if the OpenPGP card is
used in a smartcard reader that has a pinpad.
#### Set touch policy
Cards can require a type of confirmation before cryptographic operations are performed
(the feature is often implemented as a mechanical button on the card).
Not all cards implement this feature.
Rationale: when the card requires touch confirmation, an attacker who gains control of the user's host computer
cannot perform cryptographic operations on the card at will - even after they learn the user's PINs.
This feature is configured per key slot. The user can choose to require (or not require) touch confirmation separately
for signing, decryption, authentication and attestation operations.
E.g., when the touch policy is set to `On` for the `SIG` key slot, then every signing operation requires a touch button
confirmation:
```
opgpcard admin -c ABCD:01234567 touch --key SIG --policy On
```
Valid values for the key slot are: `SIG`, `DEC`, `AUT`, `ATT` (some cards only support the first three).
Available policies can include: `Off`, `On`, `Fixed`, `Cached`, `CachedFixed`.
Some cards only support a subset of these.
- `Off` means that no touch confirmation is required.
- `On` means that each operation requires on touch confirmation.
- The `Fixed` policies are like `On`, but the policies cannot be changed without performing a factory reset on the card.
- With the `Cached` policies, a touch confirmation is valid for multiple operations within 15 seconds.
#### Set cardholder name
Set cardholder name, with pin file:

View file

@ -182,6 +182,19 @@ pub enum AdminCommand {
#[clap()]
algo: Option<String>,
},
/// Set touch policy
Touch {
#[clap(name = "Key slot (SIG|DEC|AUT|ATT)", short = 'k', long = "key")]
key: String,
#[clap(
name = "Policy (Off|On|Fixed|Cached|Cached-Fixed)",
short = 'p',
long = "policy"
)]
policy: String,
},
}
#[derive(Parser, Debug)]

View file

@ -12,7 +12,7 @@ use sequoia_openpgp::serialize::SerializeInto;
use sequoia_openpgp::Cert;
use openpgp_card::algorithm::AlgoSimple;
use openpgp_card::card_do::Sex;
use openpgp_card::card_do::{Sex, TouchPolicy};
use openpgp_card::{CardBackend, KeyType, OpenPgp};
use openpgp_card_sequoia::card::{Admin, Open};
use openpgp_card_sequoia::util::{
@ -221,6 +221,31 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
algo,
)?;
}
cli::AdminCommand::Touch { key, policy } => {
let kt = match key.as_str() {
"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() {
"Off" => TouchPolicy::Off,
"On" => TouchPolicy::On,
"Fixed" => TouchPolicy::Fixed,
"Cached" => TouchPolicy::Cached,
"Cached-Fixed" => TouchPolicy::CachedFixed,
_ => {
return Err(anyhow!("Unexpected Policy {}", policy).into());
}
};
let mut admin = util::verify_to_admin(&mut open, admin_pin.as_deref())?;
let _ = admin.set_uif(kt, pol)?;
}
}
}
cli::Command::Pin { ident, cmd } => {
@ -667,7 +692,7 @@ fn print_status(ident: Option<String>, verbose: bool, pkm: bool) -> Result<()> {
if let Some(uif) = ard.uif_attestation()? {
println!(
"Touch policy attestation: {} [Features: {}]",
"Touch policy attestation: {} [Features: {}]",
uif.touch_policy(),
uif.features()
);