Don't apply Policy when picking (sub)key from Cert for sign/decrypt.

This commit is contained in:
Heiko Schaefer 2021-12-11 23:35:58 +01:00
parent b04295543e
commit 383f592865
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
10 changed files with 25 additions and 99 deletions

View file

@ -93,15 +93,9 @@ pub fn test_sign(
let cert = Cert::from_str(param[0])?;
let p = StandardPolicy::new();
let msg = "Hello world, I am signed.";
let sig = openpgp_card_sequoia::util::sign(
&mut ca,
&cert,
&mut msg.as_bytes(),
&p,
)?;
let sig =
openpgp_card_sequoia::util::sign(&mut ca, &cert, &mut msg.as_bytes())?;
// validate sig
assert!(util::verify_sig(&cert, msg.as_bytes(), sig.as_bytes())?);

View file

@ -33,7 +33,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let p = StandardPolicy::new();
let cert = Cert::from_file(cert_file)?;
let d = user.decryptor(&cert, &p)?;
let d = user.decryptor(&cert)?;
let stdin = std::io::stdin();
let mut stdout = std::io::stdout();

View file

@ -6,7 +6,6 @@ use openpgp_card_pcsc::PcscClient;
use openpgp_card_sequoia::card::Open;
use openpgp::parse::Parse;
use openpgp::policy::StandardPolicy;
use openpgp::serialize::stream::{Armorer, Message, Signer};
use openpgp::Cert;
use sequoia_openpgp as openpgp;
@ -32,9 +31,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut user = open.signing_card().unwrap();
let p = StandardPolicy::new();
let cert = Cert::from_file(cert_file)?;
let s = user.signer(&cert, &p)?;
let s = user.signer(&cert)?;
let stdout = std::io::stdout();

View file

@ -8,7 +8,6 @@ use anyhow::{anyhow, Result};
use sequoia_openpgp::cert::amalgamation::key::ValidErasedKeyAmalgamation;
use sequoia_openpgp::packet::key::SecretParts;
use sequoia_openpgp::policy::Policy;
use sequoia_openpgp::Cert;
use openpgp_card::algorithm::{Algo, AlgoInfo, AlgoSimple};
@ -355,12 +354,8 @@ pub struct User<'app, 'open> {
}
impl User<'_, '_> {
pub fn decryptor(
&mut self,
cert: &Cert,
policy: &dyn Policy,
) -> Result<CardDecryptor, Error> {
CardDecryptor::new(&mut self.oc.card_app, cert, policy)
pub fn decryptor(&mut self, cert: &Cert) -> Result<CardDecryptor, Error> {
CardDecryptor::new(&mut self.oc.card_app, cert)
}
}
@ -374,12 +369,11 @@ impl Sign<'_, '_> {
pub fn signer(
&mut self,
cert: &Cert,
policy: &dyn Policy,
) -> std::result::Result<CardSigner, Error> {
// FIXME: depending on the setting in "PW1 Status byte", only one
// signature can be made after verification for signing
CardSigner::new(&mut self.oc.card_app, cert, policy)
CardSigner::new(&mut self.oc.card_app, cert)
}
pub fn signer_from_pubkey(&mut self, pubkey: PublicKey) -> CardSigner {

View file

@ -10,7 +10,6 @@ use openpgp::packet;
use openpgp::parse::stream::{
DecryptionHelper, MessageStructure, VerificationHelper,
};
use openpgp::policy::Policy;
use openpgp::types::{Curve, SymmetricAlgorithm};
use openpgp::Cert;
use sequoia_openpgp as openpgp;
@ -37,7 +36,6 @@ impl<'a> CardDecryptor<'a> {
pub fn new(
ca: &'a mut CardApp,
cert: &Cert,
policy: &dyn Policy,
) -> Result<CardDecryptor<'a>, Error> {
// Get the fingerprint for the decryption key from the card.
let ard = ca.application_related_data()?;
@ -48,19 +46,9 @@ impl<'a> CardDecryptor<'a> {
// Transform into Sequoia Fingerprint
let fp = openpgp::Fingerprint::from_bytes(fp.as_bytes());
if let Some(vk) =
sq_util::get_subkey_by_fingerprint(cert, policy, &fp, false)?
{
if vk.for_storage_encryption() || vk.for_transport_encryption()
{
let public = vk.key().clone();
Ok(Self { ca, public })
} else {
Err(Error::InternalError(anyhow!(
"(Sub)key {} in the cert isn't encryption capable",
fp
)))
}
if let Some(eka) = sq_util::get_subkey_by_fingerprint(cert, &fp)? {
let public = eka.key().clone();
Ok(Self { ca, public })
} else {
Err(Error::InternalError(anyhow!(
"Failed to find (sub)key {} in cert",

View file

@ -172,7 +172,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Encrypted message:\n{}", msg);
let sp = StandardPolicy::new();
let d = user.decryptor(&cert, &sp)?;
let d = user.decryptor(&cert)?;
let res = sq_util::decryption_helper(d, msg.into_bytes(), &sp)?;
let plain = String::from_utf8_lossy(&res);
@ -197,7 +197,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let text = "Hello world, I am signed.";
let signer = sign.signer(&cert, &StandardPolicy::new())?;
let signer = sign.signer(&cert)?;
let sig = sq_util::sign_helper(signer, &mut text.as_bytes())?;
println!("Signature from card:\n{}", sig)

View file

@ -7,7 +7,6 @@ use anyhow::anyhow;
use openpgp::crypto;
use openpgp::crypto::mpi;
use openpgp::policy::Policy;
use openpgp::types::{Curve, PublicKeyAlgorithm};
use sequoia_openpgp as openpgp;
@ -33,7 +32,6 @@ impl<'a> CardSigner<'a> {
pub fn new(
ca: &'a mut CardApp,
cert: &openpgp::Cert,
policy: &dyn Policy,
) -> Result<CardSigner<'a>, Error> {
// Get the fingerprint for the signing key from the card.
let ard = ca.application_related_data()?;
@ -44,18 +42,9 @@ impl<'a> CardSigner<'a> {
// Transform into Sequoia Fingerprint
let fp = openpgp::Fingerprint::from_bytes(fp.as_bytes());
if let Some(vk) =
sq_util::get_subkey_by_fingerprint(cert, policy, &fp, true)?
{
if vk.for_signing() {
let key = vk.key().clone();
Ok(Self::with_pubkey(ca, key))
} else {
Err(Error::InternalError(anyhow!(
"(Sub)key {} in the cert isn't signing capable",
fp
)))
}
if let Some(eka) = sq_util::get_subkey_by_fingerprint(cert, &fp)? {
let key = eka.key().clone();
Ok(Self::with_pubkey(ca, key))
} else {
Err(Error::InternalError(anyhow!(
"Failed to find (sub)key {} in cert",

View file

@ -9,9 +9,7 @@ use anyhow::{anyhow, Context, Result};
use std::io;
use openpgp::armor;
use openpgp::cert::amalgamation::{
key::ValidErasedKeyAmalgamation, ValidAmalgamation, ValidateAmalgamation,
};
use openpgp::cert::amalgamation::key::ValidErasedKeyAmalgamation;
use openpgp::crypto;
use openpgp::packet::key::{PublicParts, SecretParts};
use openpgp::parse::{
@ -20,11 +18,11 @@ use openpgp::parse::{
};
use openpgp::policy::Policy;
use openpgp::serialize::stream::{Message, Signer};
use openpgp::types::RevocationStatus;
use openpgp::{Cert, Fingerprint};
use sequoia_openpgp as openpgp;
use openpgp_card::{Error, KeyType};
use sequoia_openpgp::cert::amalgamation::key::ErasedKeyAmalgamation;
/// Retrieve a (sub)key from a Cert, for a given KeyType.
///
@ -96,50 +94,17 @@ pub fn private_subkey_by_fingerprint<'a>(
/// Retrieve a public (sub)key from a Cert, by fingerprint.
pub fn get_subkey_by_fingerprint<'a>(
cert: &'a Cert,
policy: &'a dyn Policy,
fp: &Fingerprint,
check_revocation: bool,
) -> Result<Option<ValidErasedKeyAmalgamation<'a, PublicParts>>, Error> {
// FIXME: if `test_revocation`, then first check if the primary key is
// revoked?
) -> Result<Option<ErasedKeyAmalgamation<'a, PublicParts>>, Error> {
// Find the (sub)key in `cert` that matches the fingerprint from
// the Card's signing-key slot.
let keys: Vec<_> =
cert.keys().filter(|ka| &ka.fingerprint() == fp).collect();
// Exactly one matching (sub)key should be found. If not, fail!
if keys.len() == 1 {
// Check if the (sub)key is valid/alive, return error
// otherwise
let validkey = keys[0].clone().with_policy(policy, None)?;
validkey.alive()?;
if check_revocation {
if let RevocationStatus::Revoked(_) = validkey.revocation_status()
{
return Err(Error::InternalError(anyhow!(
"(Sub)key {} in the cert is revoked",
fp
)));
}
}
Ok(Some(validkey))
} else if keys.is_empty() {
if keys.is_empty() {
Ok(None)
} else if keys.len() == 2 {
Err(Error::InternalError(anyhow!(
"Found two results for {}, probably the cert has the \
primary as a subkey?",
fp
)))
} else {
Err(Error::InternalError(anyhow!(
"Found {} results for (sub)key {}, this is unexpected",
keys.len(),
fp
)))
Ok(Some(keys[0].clone()))
}
}

View file

@ -19,7 +19,6 @@ use openpgp::packet::{
Key, UserID,
};
use openpgp::parse::{stream::DecryptorBuilder, Parse};
use openpgp::policy::Policy;
use openpgp::serialize::stream::{Message, Signer};
use openpgp::types::{KeyFlags, PublicKeyAlgorithm, SignatureType, Timestamp};
use openpgp::{Cert, Packet};
@ -33,6 +32,7 @@ use openpgp_card::{CardApp, Error, KeyType};
use crate::card::Open;
use crate::privkey::SequoiaKey;
use crate::{decryptor, signer, PublicKey};
use sequoia_openpgp::policy::Policy;
/// Create a Cert from the three subkeys on a card.
/// (Calling this multiple times will result in different Certs!)
@ -294,11 +294,10 @@ pub fn sign(
ca: &mut CardApp,
cert: &Cert,
input: &mut dyn io::Read,
p: &dyn Policy,
) -> Result<String> {
let mut armorer = armor::Writer::new(vec![], armor::Kind::Signature)?;
{
let s = signer::CardSigner::new(ca, cert, p)?;
let s = signer::CardSigner::new(ca, cert)?;
let message = Message::new(&mut armorer);
let mut message = Signer::new(message, s).detached().build()?;
@ -325,7 +324,7 @@ pub fn decrypt(
{
let reader = io::BufReader::new(&msg[..]);
let d = decryptor::CardDecryptor::new(ca, cert, p)?;
let d = decryptor::CardDecryptor::new(ca, cert)?;
let db = DecryptorBuilder::from_reader(reader)?;
let mut decryptor = db.with_policy(p, None, d)?;

View file

@ -321,7 +321,7 @@ fn decrypt(
let mut open = Open::new(&mut card)?;
let mut user = util::verify_to_user(&mut open, pin_file)?;
let d = user.decryptor(&cert, &p)?;
let d = user.decryptor(&cert)?;
let db = DecryptorBuilder::from_reader(input)?;
let mut decryptor = db.with_policy(&p, None, d)?;
@ -337,7 +337,6 @@ fn sign_detached(
cert_file: &Path,
input: Option<&Path>,
) -> Result<(), Box<dyn std::error::Error>> {
let p = StandardPolicy::new();
let cert = Cert::from_file(cert_file)?;
let mut input = util::open_or_stdin(input.as_deref())?;
@ -346,7 +345,7 @@ fn sign_detached(
let mut open = Open::new(&mut card)?;
let mut sign = util::verify_to_sign(&mut open, pin_file)?;
let s = sign.signer(&cert, &p)?;
let s = sign.signer(&cert)?;
let message = Armorer::new(Message::new(std::io::stdout())).build()?;
let mut signer = Signer::new(message, s).detached().build()?;