use crate::algorithm::AlgorithmAttributes;
use crate::card_do::{Fingerprint, KeyGenerationTime};
use crate::{oid, Error};
#[non_exhaustive]
pub enum Hash<'a> {
SHA256([u8; 0x20]),
SHA384([u8; 0x30]),
SHA512([u8; 0x40]),
ECDSA(&'a [u8]),
EdDSA(&'a [u8]),
}
impl Hash<'_> {
pub(crate) fn oid(&self) -> Option<&'static [u8]> {
match self {
Self::SHA256(_) => Some(oid::SHA256),
Self::SHA384(_) => Some(oid::SHA384),
Self::SHA512(_) => Some(oid::SHA512),
Self::EdDSA(_) => panic!("OIDs for EdDSA are unimplemented"),
Self::ECDSA(_) => panic!("OIDs for ECDSA are unimplemented"),
}
}
pub(crate) fn digest(&self) -> &[u8] {
match self {
Self::SHA256(d) => &d[..],
Self::SHA384(d) => &d[..],
Self::SHA512(d) => &d[..],
Self::EdDSA(d) => d,
Self::ECDSA(d) => d,
}
}
}
#[non_exhaustive]
pub enum Cryptogram<'a> {
RSA(&'a [u8]),
ECDH(&'a [u8]),
}
pub trait CardUploadableKey {
fn private_key(&self) -> Result<PrivateKeyMaterial, crate::Error>;
fn timestamp(&self) -> KeyGenerationTime;
fn fingerprint(&self) -> Result<Fingerprint, Error>;
}
#[non_exhaustive]
pub enum PrivateKeyMaterial {
R(Box<dyn RSAKey>),
E(Box<dyn EccKey>),
}
pub trait RSAKey {
fn e(&self) -> &[u8];
fn p(&self) -> &[u8];
fn q(&self) -> &[u8];
fn pq(&self) -> Box<[u8]>;
fn dp1(&self) -> Box<[u8]>;
fn dq1(&self) -> Box<[u8]>;
fn n(&self) -> &[u8];
}
pub trait EccKey {
fn oid(&self) -> &[u8];
fn private(&self) -> Vec<u8>;
fn public(&self) -> Vec<u8>;
fn ecc_type(&self) -> EccType;
}
#[derive(Debug)]
#[non_exhaustive]
pub enum PublicKeyMaterial {
R(RSAPub),
E(EccPub),
}
impl std::fmt::Display for PublicKeyMaterial {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use hex_slice::AsHex;
match self {
Self::R(rsa) => {
write!(
f,
"RSA, n: {:02X}, e: {:02X}",
rsa.n.plain_hex(false),
rsa.v.plain_hex(false)
)
}
Self::E(ecc) => {
write!(
f,
"ECC [{}], data: {:02X}",
ecc.algo(),
ecc.data.plain_hex(false)
)
}
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub struct RSAPub {
n: Vec<u8>,
v: Vec<u8>,
}
impl RSAPub {
pub fn new(n: Vec<u8>, v: Vec<u8>) -> Self {
Self { n, v }
}
pub fn n(&self) -> &[u8] {
&self.n
}
pub fn v(&self) -> &[u8] {
&self.v
}
}
#[derive(Debug)]
#[non_exhaustive]
pub struct EccPub {
data: Vec<u8>,
algo: AlgorithmAttributes,
}
impl EccPub {
pub fn new(data: Vec<u8>, algo: AlgorithmAttributes) -> Self {
Self { data, algo }
}
pub fn data(&self) -> &[u8] {
&self.data
}
pub fn algo(&self) -> &AlgorithmAttributes {
&self.algo
}
}
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
#[non_exhaustive]
pub enum EccType {
ECDH,
ECDSA,
EdDSA,
}