Rename structs that represent different verification states of the OpenPGP card.
This commit is contained in:
parent
3fcb78caa5
commit
920da0442b
7 changed files with 76 additions and 60 deletions
|
@ -16,13 +16,13 @@ use openpgp::Cert;
|
|||
use sequoia_openpgp as openpgp;
|
||||
|
||||
use openpgp_card::errors::OpenpgpCardError;
|
||||
use openpgp_card::{DecryptMe, OpenPGPCardUser};
|
||||
use openpgp_card::{CardUser, DecryptMe};
|
||||
|
||||
use crate::PublicKey;
|
||||
|
||||
pub(crate) struct CardDecryptor<'a> {
|
||||
/// The OpenPGP card (authenticated to allow decryption operations)
|
||||
ocu: &'a OpenPGPCardUser,
|
||||
ocu: &'a CardUser,
|
||||
|
||||
/// The matching public key for the card's decryption key
|
||||
public: PublicKey,
|
||||
|
@ -34,7 +34,7 @@ impl<'a> CardDecryptor<'a> {
|
|||
/// An Error is returned if no match between the card's decryption
|
||||
/// key and a (sub)key of `cert` can be made.
|
||||
pub fn new(
|
||||
ocu: &'a OpenPGPCardUser,
|
||||
ocu: &'a CardUser,
|
||||
cert: &Cert,
|
||||
policy: &dyn Policy,
|
||||
) -> Result<CardDecryptor<'a>, OpenpgpCardError> {
|
||||
|
|
|
@ -21,8 +21,8 @@ use openpgp::serialize::stream::{Message, Signer};
|
|||
use sequoia_openpgp as openpgp;
|
||||
|
||||
use openpgp_card::{
|
||||
errors::OpenpgpCardError, CardUploadableKey, EccKey, EccType, KeyType,
|
||||
OpenPGPCardAdmin, OpenPGPCardUser, PrivateKeyMaterial, RSAKey,
|
||||
errors::OpenpgpCardError, CardAdmin, CardSign, CardUploadableKey,
|
||||
CardUser, EccKey, EccType, KeyType, PrivateKeyMaterial, RSAKey,
|
||||
};
|
||||
|
||||
mod decryptor;
|
||||
|
@ -216,7 +216,7 @@ impl EccKey for SqEccKey {
|
|||
/// FIXME: picking the (sub)key to upload should probably done with
|
||||
/// more intent.
|
||||
pub fn upload_from_cert_yolo(
|
||||
oca: &OpenPGPCardAdmin,
|
||||
oca: &CardAdmin,
|
||||
cert: &sequoia_openpgp::Cert,
|
||||
key_type: KeyType,
|
||||
password: Option<String>,
|
||||
|
@ -249,7 +249,7 @@ pub fn upload_from_cert_yolo(
|
|||
///
|
||||
/// The caller needs to make sure that `vka` is suitable for `key_type`.
|
||||
pub fn upload_key(
|
||||
oca: &OpenPGPCardAdmin,
|
||||
oca: &CardAdmin,
|
||||
vka: ValidErasedKeyAmalgamation<SecretParts>,
|
||||
key_type: KeyType,
|
||||
password: Option<String>,
|
||||
|
@ -260,7 +260,7 @@ pub fn upload_key(
|
|||
}
|
||||
|
||||
pub fn decrypt(
|
||||
ocu: &OpenPGPCardUser,
|
||||
ocu: &CardUser,
|
||||
cert: &sequoia_openpgp::Cert,
|
||||
msg: Vec<u8>,
|
||||
) -> Result<Vec<u8>> {
|
||||
|
@ -282,7 +282,7 @@ pub fn decrypt(
|
|||
}
|
||||
|
||||
pub fn sign(
|
||||
ocu: &OpenPGPCardUser,
|
||||
ocu: &CardSign,
|
||||
cert: &sequoia_openpgp::Cert,
|
||||
input: &mut dyn io::Read,
|
||||
) -> Result<String> {
|
||||
|
|
|
@ -8,7 +8,7 @@ use anyhow::Result;
|
|||
use sequoia_openpgp::parse::Parse;
|
||||
use sequoia_openpgp::Cert;
|
||||
|
||||
use openpgp_card::{KeyType, OpenPGPCard};
|
||||
use openpgp_card::{CardBase, KeyType};
|
||||
|
||||
// Filename of test key and test message to use:
|
||||
|
||||
|
@ -29,7 +29,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
if let Ok(test_card_serial) = test_card_serial {
|
||||
println!("** get card");
|
||||
let oc = OpenPGPCard::open_by_serial(&test_card_serial)?;
|
||||
let oc = CardBase::open_by_serial(&test_card_serial)?;
|
||||
|
||||
// card metadata
|
||||
|
||||
|
@ -127,13 +127,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
// Open fresh Card for decrypt
|
||||
// -----------------------------
|
||||
|
||||
let oc = OpenPGPCard::open_by_serial(&test_card_serial)?;
|
||||
let oc = CardBase::open_by_serial(&test_card_serial)?;
|
||||
let app_id = oc.get_aid()?;
|
||||
|
||||
// Check that we're still using the expected card
|
||||
assert_eq!(app_id.serial(), test_card_serial);
|
||||
|
||||
match oc.verify_pw1_82("123456") {
|
||||
match oc.verify_pw1("123456") {
|
||||
Ok(oc_user) => {
|
||||
println!("pw1 82 verify ok");
|
||||
|
||||
|
@ -160,10 +160,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
// -----------------------------
|
||||
// Open fresh Card for signing
|
||||
// -----------------------------
|
||||
let oc = OpenPGPCard::open_by_serial(&test_card_serial)?;
|
||||
let oc = CardBase::open_by_serial(&test_card_serial)?;
|
||||
|
||||
// Sign
|
||||
match oc.verify_pw1_81("123456") {
|
||||
match oc.verify_pw1_for_signing("123456") {
|
||||
Ok(oc_user) => {
|
||||
println!("pw1 81 verify ok");
|
||||
|
||||
|
@ -194,7 +194,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
println!("The following OpenPGP cards are connected to your system:");
|
||||
|
||||
let cards = openpgp_card::OpenPGPCard::list_cards()?;
|
||||
let cards = openpgp_card::CardBase::list_cards()?;
|
||||
for c in cards {
|
||||
println!(" '{}'", c.get_aid()?.serial());
|
||||
}
|
||||
|
|
|
@ -11,14 +11,14 @@ use openpgp::types::PublicKeyAlgorithm;
|
|||
use sequoia_openpgp as openpgp;
|
||||
|
||||
use openpgp_card::errors::OpenpgpCardError;
|
||||
use openpgp_card::CardSign;
|
||||
use openpgp_card::Hash;
|
||||
use openpgp_card::OpenPGPCardUser;
|
||||
|
||||
use crate::PublicKey;
|
||||
|
||||
pub(crate) struct CardSigner<'a> {
|
||||
/// The OpenPGP card (authenticated to allow signing operations)
|
||||
ocu: &'a OpenPGPCardUser,
|
||||
ocu: &'a CardSign,
|
||||
|
||||
/// The matching public key for the card's signing key
|
||||
public: PublicKey,
|
||||
|
@ -30,12 +30,12 @@ impl<'a> CardSigner<'a> {
|
|||
/// An Error is returned if no match between the card's signing
|
||||
/// key and a (sub)key of `cert` can be made.
|
||||
pub fn new(
|
||||
ocu: &'a OpenPGPCardUser,
|
||||
ocs: &'a CardSign,
|
||||
cert: &openpgp::Cert,
|
||||
policy: &dyn Policy,
|
||||
) -> Result<CardSigner<'a>, OpenpgpCardError> {
|
||||
// Get the fingerprint for the signing key from the card.
|
||||
let fps = ocu.get_fingerprints()?;
|
||||
let fps = ocs.get_fingerprints()?;
|
||||
let fp = fps.signature();
|
||||
|
||||
if let Some(fp) = fp {
|
||||
|
@ -58,7 +58,7 @@ impl<'a> CardSigner<'a> {
|
|||
let public = keys[0].clone();
|
||||
|
||||
Ok(CardSigner {
|
||||
ocu,
|
||||
ocu: ocs,
|
||||
public: public.role_as_unspecified().clone(),
|
||||
})
|
||||
} else {
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::convert::TryFrom;
|
|||
use crate::apdu::command::Command;
|
||||
use crate::apdu::response::Response;
|
||||
use crate::errors::{OcErrorStatus, OpenpgpCardError, SmartcardError};
|
||||
use crate::OpenPGPCard;
|
||||
use crate::CardBase;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub(crate) enum Le {
|
||||
|
@ -28,7 +28,7 @@ pub(crate) fn send_command(
|
|||
card: &Card,
|
||||
cmd: Command,
|
||||
ext: Le,
|
||||
oc: Option<&OpenPGPCard>,
|
||||
oc: Option<&CardBase>,
|
||||
) -> Result<Response, OpenpgpCardError> {
|
||||
let mut resp =
|
||||
Response::try_from(send_command_low_level(&card, cmd, ext, oc)?)?;
|
||||
|
@ -68,7 +68,7 @@ fn send_command_low_level(
|
|||
card: &Card,
|
||||
cmd: Command,
|
||||
ext: Le,
|
||||
oc: Option<&OpenPGPCard>,
|
||||
oc: Option<&CardBase>,
|
||||
) -> Result<Vec<u8>, OpenpgpCardError> {
|
||||
log::trace!(" -> full APDU command: {:x?}", cmd);
|
||||
log::trace!(" serialized: {:x?}", cmd.serialize(ext));
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::parse::algo_attrs::{Algo, RsaAttrs};
|
|||
use crate::parse::algo_info::AlgoInfo;
|
||||
use crate::tlv::{tag::Tag, Tlv, TlvEntry};
|
||||
use crate::{
|
||||
tlv, CardUploadableKey, EccKey, EccType, KeyType, OpenPGPCardAdmin,
|
||||
tlv, CardAdmin, CardUploadableKey, EccKey, EccType, KeyType,
|
||||
PrivateKeyMaterial, RSAKey,
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||
///
|
||||
/// The client needs to make sure that the key is suitable for `key_type`.
|
||||
pub(crate) fn upload_key(
|
||||
oca: &OpenPGPCardAdmin,
|
||||
oca: &CardAdmin,
|
||||
key: Box<dyn CardUploadableKey>,
|
||||
key_type: KeyType,
|
||||
) -> Result<(), OpenpgpCardError> {
|
||||
|
@ -369,7 +369,7 @@ fn ecc_algo_attrs_cmd(
|
|||
}
|
||||
|
||||
fn copy_key_to_card(
|
||||
oca: &OpenPGPCardAdmin,
|
||||
oca: &CardAdmin,
|
||||
key_type: KeyType,
|
||||
ts: u64,
|
||||
fp: Vec<u8>,
|
||||
|
|
|
@ -27,6 +27,8 @@ mod key_upload;
|
|||
mod parse;
|
||||
mod tlv;
|
||||
|
||||
/// Container for a hash value.
|
||||
/// These hash values can be signed by the card.
|
||||
pub enum Hash<'a> {
|
||||
SHA256([u8; 0x20]),
|
||||
SHA384([u8; 0x30]),
|
||||
|
@ -97,6 +99,8 @@ pub trait EccKey {
|
|||
fn get_type(&self) -> EccType;
|
||||
}
|
||||
|
||||
/// A marker to distinguish between elliptic curve algorithms (ECDH, ECDSA,
|
||||
/// EdDSA)
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum EccType {
|
||||
ECDH,
|
||||
|
@ -203,9 +207,9 @@ impl KeyType {
|
|||
}
|
||||
}
|
||||
|
||||
/// Representation of an opened OpenPGP card, with default privileges (i.e.
|
||||
/// no passwords have been verified)
|
||||
pub struct OpenPGPCard {
|
||||
/// Representation of an opened OpenPGP card in its basic, freshly opened,
|
||||
/// state (i.e. no passwords have been verified, default privileges apply).
|
||||
pub struct CardBase {
|
||||
card: Card,
|
||||
|
||||
// Cache of "application related data".
|
||||
|
@ -215,7 +219,7 @@ pub struct OpenPGPCard {
|
|||
ard: Tlv,
|
||||
}
|
||||
|
||||
impl OpenPGPCard {
|
||||
impl CardBase {
|
||||
/// Get all cards that can be opened as an OpenPGP card applet
|
||||
pub fn list_cards() -> Result<Vec<Self>> {
|
||||
let cards = card::get_cards().map_err(|err| anyhow!(err))?;
|
||||
|
@ -229,7 +233,7 @@ impl OpenPGPCard {
|
|||
Ok(ocs)
|
||||
}
|
||||
|
||||
/// Find an OpenPGP card by serial number and return it.
|
||||
/// Find an OpenPGP card by serial number, open and return it.
|
||||
pub fn open_by_serial(serial: &str) -> Result<Self, OpenpgpCardError> {
|
||||
let cards = card::get_cards().map_err(|e| {
|
||||
OpenpgpCardError::Smartcard(SmartcardError::Error(format!(
|
||||
|
@ -547,10 +551,10 @@ impl OpenPGPCard {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn verify_pw1_81(
|
||||
pub fn verify_pw1_for_signing(
|
||||
self,
|
||||
pin: &str,
|
||||
) -> Result<OpenPGPCardUser, OpenPGPCard> {
|
||||
) -> Result<CardSign, CardBase> {
|
||||
assert!(pin.len() >= 6); // FIXME: Err
|
||||
|
||||
let verify = commands::verify_pw1_81(pin.as_bytes().to_vec());
|
||||
|
@ -559,17 +563,14 @@ impl OpenPGPCard {
|
|||
|
||||
if let Ok(resp) = res {
|
||||
if resp.is_ok() {
|
||||
return Ok(OpenPGPCardUser { oc: self });
|
||||
return Ok(CardSign { oc: self });
|
||||
}
|
||||
}
|
||||
|
||||
Err(self)
|
||||
}
|
||||
|
||||
pub fn verify_pw1_82(
|
||||
self,
|
||||
pin: &str,
|
||||
) -> Result<OpenPGPCardUser, OpenPGPCard> {
|
||||
pub fn verify_pw1(self, pin: &str) -> Result<CardUser, CardBase> {
|
||||
assert!(pin.len() >= 6); // FIXME: Err
|
||||
|
||||
let verify = commands::verify_pw1_82(pin.as_bytes().to_vec());
|
||||
|
@ -578,17 +579,14 @@ impl OpenPGPCard {
|
|||
|
||||
if let Ok(resp) = res {
|
||||
if resp.is_ok() {
|
||||
return Ok(OpenPGPCardUser { oc: self });
|
||||
return Ok(CardUser { oc: self });
|
||||
}
|
||||
}
|
||||
|
||||
Err(self)
|
||||
}
|
||||
|
||||
pub fn verify_pw3(
|
||||
self,
|
||||
pin: &str,
|
||||
) -> Result<OpenPGPCardAdmin, OpenPGPCard> {
|
||||
pub fn verify_pw3(self, pin: &str) -> Result<CardAdmin, CardBase> {
|
||||
assert!(pin.len() >= 8); // FIXME: Err
|
||||
|
||||
let verify = commands::verify_pw3(pin.as_bytes().to_vec());
|
||||
|
@ -597,7 +595,7 @@ impl OpenPGPCard {
|
|||
|
||||
if let Ok(resp) = res {
|
||||
if resp.is_ok() {
|
||||
return Ok(OpenPGPCardAdmin { oc: self });
|
||||
return Ok(CardAdmin { oc: self });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -605,22 +603,22 @@ impl OpenPGPCard {
|
|||
}
|
||||
}
|
||||
|
||||
/// An OpenPGP card after successful verification of PW1 (needs to be split
|
||||
/// further to model authentication for signing)
|
||||
pub struct OpenPGPCardUser {
|
||||
oc: OpenPGPCard,
|
||||
/// An OpenPGP card after successful verification of PW1 in mode 82
|
||||
/// (verification for operations other than signing)
|
||||
pub struct CardUser {
|
||||
oc: CardBase,
|
||||
}
|
||||
|
||||
/// Allow access to fn of OpenPGPCard, through OpenPGPCardUser.
|
||||
impl Deref for OpenPGPCardUser {
|
||||
type Target = OpenPGPCard;
|
||||
impl Deref for CardUser {
|
||||
type Target = CardBase;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.oc
|
||||
}
|
||||
}
|
||||
|
||||
impl OpenPGPCardUser {
|
||||
impl CardUser {
|
||||
/// Decrypt the ciphertext in `dm`, on the card.
|
||||
pub fn decrypt(&self, dm: DecryptMe) -> Result<Vec<u8>, OpenpgpCardError> {
|
||||
match dm {
|
||||
|
@ -660,7 +658,26 @@ impl OpenPGPCardUser {
|
|||
|
||||
Ok(resp.data().map(|d| d.to_vec())?)
|
||||
}
|
||||
}
|
||||
|
||||
/// An OpenPGP card after successful verification of PW1 in mode 81
|
||||
/// (verification for signing)
|
||||
pub struct CardSign {
|
||||
oc: CardBase,
|
||||
}
|
||||
|
||||
/// Allow access to fn of OpenPGPCard, through OpenPGPCardUser.
|
||||
impl Deref for CardSign {
|
||||
type Target = CardBase;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.oc
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: depending on the setting in "PW1 Status byte", only one
|
||||
// signature can be made after verification for signing
|
||||
impl CardSign {
|
||||
/// Sign the message in `hash`, on the card.
|
||||
pub fn signature_for_hash(
|
||||
&self,
|
||||
|
@ -676,8 +693,7 @@ impl OpenPGPCardUser {
|
|||
TlvEntry::C(vec![
|
||||
Tlv(
|
||||
Tag(vec![0x06]),
|
||||
// unwrapping is
|
||||
// ok, for SHA*
|
||||
// unwrapping is ok, for SHA*
|
||||
TlvEntry::S(hash.oid().unwrap().to_vec()),
|
||||
),
|
||||
Tlv(Tag(vec![0x05]), TlvEntry::S(vec![])),
|
||||
|
@ -711,21 +727,21 @@ impl OpenPGPCardUser {
|
|||
}
|
||||
}
|
||||
|
||||
/// An OpenPGP card after successful verification of PW3
|
||||
pub struct OpenPGPCardAdmin {
|
||||
oc: OpenPGPCard,
|
||||
/// An OpenPGP card after successful verification of PW3 ("Admin privileges")
|
||||
pub struct CardAdmin {
|
||||
oc: CardBase,
|
||||
}
|
||||
|
||||
/// Allow access to fn of OpenPGPCard, through OpenPGPCardAdmin.
|
||||
impl Deref for OpenPGPCardAdmin {
|
||||
type Target = OpenPGPCard;
|
||||
impl Deref for CardAdmin {
|
||||
type Target = CardBase;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.oc
|
||||
}
|
||||
}
|
||||
|
||||
impl OpenPGPCardAdmin {
|
||||
impl CardAdmin {
|
||||
pub(crate) fn card(&self) -> &Card {
|
||||
&self.card
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue