Make CardSigner accessible (for use in card-functionality crate)
This commit is contained in:
parent
27b6d686d9
commit
9e5bb9b5a6
2 changed files with 50 additions and 37 deletions
|
@ -32,7 +32,7 @@ use openpgp_card::{
|
||||||
use sequoia_openpgp::types::PublicKeyAlgorithm;
|
use sequoia_openpgp::types::PublicKeyAlgorithm;
|
||||||
|
|
||||||
mod decryptor;
|
mod decryptor;
|
||||||
mod signer;
|
pub mod signer;
|
||||||
|
|
||||||
/// Shorthand for public key data
|
/// Shorthand for public key data
|
||||||
pub(crate) type PublicKey = Key<key::PublicParts, key::UnspecifiedRole>;
|
pub(crate) type PublicKey = Key<key::PublicParts, key::UnspecifiedRole>;
|
||||||
|
@ -88,6 +88,15 @@ pub fn public_key_material_to_key(
|
||||||
PublicKeyMaterial::E(ecc) => {
|
PublicKeyMaterial::E(ecc) => {
|
||||||
let algo = ecc.algo.clone(); // FIXME?
|
let algo = ecc.algo.clone(); // FIXME?
|
||||||
if let Algo::Ecc(algo_ecc) = algo {
|
if let Algo::Ecc(algo_ecc) = algo {
|
||||||
|
let curve = match algo_ecc.curve {
|
||||||
|
Curve::NistP256r1 => openpgp::types::Curve::NistP256,
|
||||||
|
Curve::NistP384r1 => openpgp::types::Curve::NistP384,
|
||||||
|
Curve::NistP521r1 => openpgp::types::Curve::NistP521,
|
||||||
|
Curve::Ed25519 => openpgp::types::Curve::Ed25519,
|
||||||
|
Curve::Cv25519 => openpgp::types::Curve::Cv25519,
|
||||||
|
c => unimplemented!("unhandled curve: {:?}", c),
|
||||||
|
};
|
||||||
|
|
||||||
match key_type {
|
match key_type {
|
||||||
KeyType::Authentication | KeyType::Signing => {
|
KeyType::Authentication | KeyType::Signing => {
|
||||||
if algo_ecc.curve == Curve::Ed25519 {
|
if algo_ecc.curve == Curve::Ed25519 {
|
||||||
|
@ -102,41 +111,12 @@ pub fn public_key_material_to_key(
|
||||||
Ok(Key::from(k4))
|
Ok(Key::from(k4))
|
||||||
} else {
|
} else {
|
||||||
// ECDSA
|
// ECDSA
|
||||||
|
|
||||||
// The public key for ECDSA/DH consists of of two raw
|
|
||||||
// big-endian integers with the same length as a field element
|
|
||||||
// each. In compliance with EN 419212 the format is 04 || x || y
|
|
||||||
// where the first byte (04) indicates an uncompressed raw format.
|
|
||||||
|
|
||||||
let ec = &ecc.data;
|
|
||||||
|
|
||||||
assert_eq!(ec[0], 0x4);
|
|
||||||
|
|
||||||
let len = ec.len();
|
|
||||||
assert_eq!(len % 2, 1); // odd number of bytes
|
|
||||||
|
|
||||||
// ---
|
|
||||||
|
|
||||||
let curve = match algo_ecc.curve {
|
|
||||||
Curve::NistP256r1 => {
|
|
||||||
openpgp::types::Curve::NistP256
|
|
||||||
}
|
|
||||||
Curve::NistP384r1 => {
|
|
||||||
openpgp::types::Curve::NistP384
|
|
||||||
}
|
|
||||||
Curve::NistP521r1 => {
|
|
||||||
openpgp::types::Curve::NistP521
|
|
||||||
}
|
|
||||||
_ => unimplemented!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// NIST
|
|
||||||
let k4 = Key4::new(
|
let k4 = Key4::new(
|
||||||
time,
|
time,
|
||||||
PublicKeyAlgorithm::ECDSA,
|
PublicKeyAlgorithm::ECDSA,
|
||||||
mpi::PublicKey::ECDSA {
|
mpi::PublicKey::ECDSA {
|
||||||
curve,
|
curve,
|
||||||
q: mpi::MPI::new(&ec),
|
q: mpi::MPI::new(&ecc.data),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -144,7 +124,36 @@ pub fn public_key_material_to_key(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeyType::Decryption => {
|
KeyType::Decryption => {
|
||||||
unimplemented!("Decryption keys not implemented yet")
|
if algo_ecc.curve == Curve::Cv25519 {
|
||||||
|
// EdDSA
|
||||||
|
let k4: Key4<
|
||||||
|
key::PublicParts,
|
||||||
|
key::UnspecifiedRole,
|
||||||
|
> = Key4::import_public_cv25519(
|
||||||
|
&ecc.data, None, None, time,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
println!("k4 {:?}", k4);
|
||||||
|
|
||||||
|
Ok(Key::from(k4))
|
||||||
|
} else {
|
||||||
|
// FIXME: just defining `hash` and `sym` is not
|
||||||
|
// ok when a cert already exists
|
||||||
|
|
||||||
|
// ECDH
|
||||||
|
let k4 = Key4::new(
|
||||||
|
time,
|
||||||
|
PublicKeyAlgorithm::ECDH,
|
||||||
|
mpi::PublicKey::ECDH {
|
||||||
|
curve,
|
||||||
|
q: mpi::MPI::new(&ecc.data),
|
||||||
|
hash: Default::default(),
|
||||||
|
sym: Default::default(),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Key::from(k4))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => unimplemented!("Unsupported KeyType"),
|
_ => unimplemented!("Unsupported KeyType"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ use openpgp_card::Hash;
|
||||||
|
|
||||||
use crate::PublicKey;
|
use crate::PublicKey;
|
||||||
|
|
||||||
pub(crate) struct CardSigner<'a> {
|
pub struct CardSigner<'a> {
|
||||||
/// The OpenPGP card (authenticated to allow signing operations)
|
/// The OpenPGP card (authenticated to allow signing operations)
|
||||||
ca: &'a mut CardApp,
|
ca: &'a mut CardApp,
|
||||||
|
|
||||||
|
@ -58,10 +58,7 @@ impl<'a> CardSigner<'a> {
|
||||||
if keys.len() == 1 {
|
if keys.len() == 1 {
|
||||||
let public = keys[0].clone();
|
let public = keys[0].clone();
|
||||||
|
|
||||||
Ok(CardSigner {
|
Ok(Self::with_pubkey(ca, public))
|
||||||
ca,
|
|
||||||
public: public.role_as_unspecified().clone(),
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
Err(OpenpgpCardError::InternalError(anyhow!(
|
Err(OpenpgpCardError::InternalError(anyhow!(
|
||||||
"Failed to find a matching (sub)key in cert"
|
"Failed to find a matching (sub)key in cert"
|
||||||
|
@ -74,6 +71,13 @@ impl<'a> CardSigner<'a> {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_pubkey(
|
||||||
|
ca: &'a mut CardApp,
|
||||||
|
public: PublicKey,
|
||||||
|
) -> CardSigner<'a> {
|
||||||
|
CardSigner { ca, public }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> crypto::Signer for CardSigner<'a> {
|
impl<'a> crypto::Signer for CardSigner<'a> {
|
||||||
|
|
Loading…
Reference in a new issue