Experiment: wrap Arc<Mutex<CardSign>> in CardSigner
This commit is contained in:
parent
3872b585d8
commit
89745c0268
4 changed files with 40 additions and 34 deletions
|
@ -24,6 +24,7 @@ use openpgp_card::{
|
||||||
errors::OpenpgpCardError, CardAdmin, CardSign, CardUploadableKey,
|
errors::OpenpgpCardError, CardAdmin, CardSign, CardUploadableKey,
|
||||||
CardUser, EccKey, EccType, KeyType, PrivateKeyMaterial, RSAKey,
|
CardUser, EccKey, EccType, KeyType, PrivateKeyMaterial, RSAKey,
|
||||||
};
|
};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
mod decryptor;
|
mod decryptor;
|
||||||
mod signer;
|
mod signer;
|
||||||
|
@ -282,7 +283,7 @@ pub fn decrypt(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sign(
|
pub fn sign(
|
||||||
ocu: &mut CardSign,
|
ocu: Arc<Mutex<CardSign>>,
|
||||||
cert: &sequoia_openpgp::Cert,
|
cert: &sequoia_openpgp::Cert,
|
||||||
input: &mut dyn io::Read,
|
input: &mut dyn io::Read,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
|
|
|
@ -10,6 +10,7 @@ use sequoia_openpgp::Cert;
|
||||||
|
|
||||||
use openpgp_card::{CardBase, KeyType};
|
use openpgp_card::{CardBase, KeyType};
|
||||||
use openpgp_card_scdc::ScdClient;
|
use openpgp_card_scdc::ScdClient;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
// Filename of test key and test message to use:
|
// Filename of test key and test message to use:
|
||||||
|
|
||||||
|
@ -197,7 +198,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let text = "Hello world, I am signed.";
|
let text = "Hello world, I am signed.";
|
||||||
let res = openpgp_card_sequoia::sign(
|
let res = openpgp_card_sequoia::sign(
|
||||||
&mut oc_user,
|
Arc::new(Mutex::new(oc_user)),
|
||||||
&cert,
|
&cert,
|
||||||
&mut text.as_bytes(),
|
&mut text.as_bytes(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,27 +15,28 @@ use openpgp_card::CardSign;
|
||||||
use openpgp_card::Hash;
|
use openpgp_card::Hash;
|
||||||
|
|
||||||
use crate::PublicKey;
|
use crate::PublicKey;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
pub(crate) struct CardSigner<'a> {
|
pub(crate) struct CardSigner {
|
||||||
/// The OpenPGP card (authenticated to allow signing operations)
|
/// The OpenPGP card (authenticated to allow signing operations)
|
||||||
ocu: &'a mut CardSign,
|
ocu: Arc<Mutex<CardSign>>,
|
||||||
|
|
||||||
/// The matching public key for the card's signing key
|
/// The matching public key for the card's signing key
|
||||||
public: PublicKey,
|
public: PublicKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CardSigner<'a> {
|
impl CardSigner {
|
||||||
/// Try to create a CardSigner.
|
/// Try to create a CardSigner.
|
||||||
///
|
///
|
||||||
/// An Error is returned if no match between the card's signing
|
/// An Error is returned if no match between the card's signing
|
||||||
/// key and a (sub)key of `cert` can be made.
|
/// key and a (sub)key of `cert` can be made.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
ocs: &'a mut CardSign,
|
cs: Arc<Mutex<CardSign>>,
|
||||||
cert: &openpgp::Cert,
|
cert: &openpgp::Cert,
|
||||||
policy: &dyn Policy,
|
policy: &dyn Policy,
|
||||||
) -> Result<CardSigner<'a>, OpenpgpCardError> {
|
) -> Result<CardSigner, OpenpgpCardError> {
|
||||||
// Get the fingerprint for the signing key from the card.
|
// Get the fingerprint for the signing key from the card.
|
||||||
let fps = ocs.get_fingerprints()?;
|
let fps = cs.lock().unwrap().get_fingerprints()?;
|
||||||
let fp = fps.signature();
|
let fp = fps.signature();
|
||||||
|
|
||||||
if let Some(fp) = fp {
|
if let Some(fp) = fp {
|
||||||
|
@ -58,7 +59,7 @@ impl<'a> CardSigner<'a> {
|
||||||
let public = keys[0].clone();
|
let public = keys[0].clone();
|
||||||
|
|
||||||
Ok(CardSigner {
|
Ok(CardSigner {
|
||||||
ocu: ocs,
|
ocu: cs,
|
||||||
public: public.role_as_unspecified().clone(),
|
public: public.role_as_unspecified().clone(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -75,7 +76,7 @@ impl<'a> CardSigner<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> crypto::Signer for CardSigner<'a> {
|
impl<'a> crypto::Signer for CardSigner {
|
||||||
fn public(&self) -> &PublicKey {
|
fn public(&self) -> &PublicKey {
|
||||||
&self.public
|
&self.public
|
||||||
}
|
}
|
||||||
|
@ -98,28 +99,22 @@ impl<'a> crypto::Signer for CardSigner<'a> {
|
||||||
PublicKeyAlgorithm::RSAEncryptSign,
|
PublicKeyAlgorithm::RSAEncryptSign,
|
||||||
mpi::PublicKey::RSA { .. },
|
mpi::PublicKey::RSA { .. },
|
||||||
) => {
|
) => {
|
||||||
let sig = match hash_algo {
|
let hash = match hash_algo {
|
||||||
openpgp::types::HashAlgorithm::SHA256 => {
|
openpgp::types::HashAlgorithm::SHA256 => Hash::SHA256(
|
||||||
let hash =
|
digest
|
||||||
Hash::SHA256(digest.try_into().map_err(|_| {
|
.try_into()
|
||||||
anyhow!("invalid slice length")
|
.map_err(|_| anyhow!("invalid slice length"))?,
|
||||||
})?);
|
),
|
||||||
self.ocu.signature_for_hash(hash)?
|
openpgp::types::HashAlgorithm::SHA384 => Hash::SHA384(
|
||||||
}
|
digest
|
||||||
openpgp::types::HashAlgorithm::SHA384 => {
|
.try_into()
|
||||||
let hash =
|
.map_err(|_| anyhow!("invalid slice length"))?,
|
||||||
Hash::SHA384(digest.try_into().map_err(|_| {
|
),
|
||||||
anyhow!("invalid slice length")
|
openpgp::types::HashAlgorithm::SHA512 => Hash::SHA512(
|
||||||
})?);
|
digest
|
||||||
self.ocu.signature_for_hash(hash)?
|
.try_into()
|
||||||
}
|
.map_err(|_| anyhow!("invalid slice length"))?,
|
||||||
openpgp::types::HashAlgorithm::SHA512 => {
|
),
|
||||||
let hash =
|
|
||||||
Hash::SHA512(digest.try_into().map_err(|_| {
|
|
||||||
anyhow!("invalid slice length")
|
|
||||||
})?);
|
|
||||||
self.ocu.signature_for_hash(hash)?
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Unsupported hash algorithm for RSA {:?}",
|
"Unsupported hash algorithm for RSA {:?}",
|
||||||
|
@ -128,12 +123,21 @@ impl<'a> crypto::Signer for CardSigner<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let cs = self.ocu.clone();
|
||||||
|
let mut cs = cs.lock().unwrap();
|
||||||
|
|
||||||
|
let sig = cs.signature_for_hash(hash)?;
|
||||||
|
|
||||||
let mpi = mpi::MPI::new(&sig[..]);
|
let mpi = mpi::MPI::new(&sig[..]);
|
||||||
Ok(mpi::Signature::RSA { s: mpi })
|
Ok(mpi::Signature::RSA { s: mpi })
|
||||||
}
|
}
|
||||||
(PublicKeyAlgorithm::EdDSA, mpi::PublicKey::EdDSA { .. }) => {
|
(PublicKeyAlgorithm::EdDSA, mpi::PublicKey::EdDSA { .. }) => {
|
||||||
let hash = Hash::EdDSA(digest);
|
let hash = Hash::EdDSA(digest);
|
||||||
let sig = self.ocu.signature_for_hash(hash)?;
|
|
||||||
|
let cs = self.ocu.clone();
|
||||||
|
let mut cs = cs.lock().unwrap();
|
||||||
|
|
||||||
|
let sig = cs.signature_for_hash(hash)?;
|
||||||
|
|
||||||
let r = mpi::MPI::new(&sig[..32]);
|
let r = mpi::MPI::new(&sig[..32]);
|
||||||
let s = mpi::MPI::new(&sig[32..]);
|
let s = mpi::MPI::new(&sig[32..]);
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub trait CardClient {
|
||||||
fn transmit(&mut self, cmd: &[u8], buf_size: usize) -> Result<Vec<u8>>;
|
fn transmit(&mut self, cmd: &[u8], buf_size: usize) -> Result<Vec<u8>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CardClientBox = Box<dyn CardClient + Send + Sync>;
|
pub type CardClientBox = Box<dyn CardClient + Send>;
|
||||||
|
|
||||||
/// Information about the capabilities of the card.
|
/// Information about the capabilities of the card.
|
||||||
/// (feature configuration from card metadata)
|
/// (feature configuration from card metadata)
|
||||||
|
|
Loading…
Reference in a new issue