Don't apply Policy when picking (sub)key from Cert for sign/decrypt.
This commit is contained in:
parent
b04295543e
commit
383f592865
10 changed files with 25 additions and 99 deletions
|
@ -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())?);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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()?;
|
||||
|
|
Loading…
Reference in a new issue