Implement 'opgpcard admin touch' to set the touch confirmation policy.
This commit is contained in:
parent
bc58a346c2
commit
f9d69dbefb
3 changed files with 72 additions and 3 deletions
|
@ -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
|
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.
|
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
|
||||||
|
|
||||||
Set cardholder name, with pin file:
|
Set cardholder name, with pin file:
|
||||||
|
|
|
@ -182,6 +182,19 @@ pub enum AdminCommand {
|
||||||
#[clap()]
|
#[clap()]
|
||||||
algo: Option<String>,
|
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)]
|
#[derive(Parser, Debug)]
|
||||||
|
|
|
@ -12,7 +12,7 @@ use sequoia_openpgp::serialize::SerializeInto;
|
||||||
use sequoia_openpgp::Cert;
|
use sequoia_openpgp::Cert;
|
||||||
|
|
||||||
use openpgp_card::algorithm::AlgoSimple;
|
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::{CardBackend, KeyType, OpenPgp};
|
||||||
use openpgp_card_sequoia::card::{Admin, Open};
|
use openpgp_card_sequoia::card::{Admin, Open};
|
||||||
use openpgp_card_sequoia::util::{
|
use openpgp_card_sequoia::util::{
|
||||||
|
@ -221,6 +221,31 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
algo,
|
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 } => {
|
cli::Command::Pin { ident, cmd } => {
|
||||||
|
|
Loading…
Reference in a new issue