use crate::{CertType, ErasedKey, InvalidCertError, KeyUnknownCert, Result};
use tor_cert::{Ed25519Cert, EncodedEd25519Cert, SigCheckedCert, UncheckedCert};
use tor_llcrypto::pk::ed25519::{self, Ed25519Identity};
use std::{result::Result as StdResult, time::SystemTime};
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum CertData {
TorEd25519Cert(EncodedEd25519Cert),
}
impl CertData {
#[allow(clippy::unnecessary_wraps)]
pub(crate) fn into_erased(self) -> Result<ErasedKey> {
match self {
Self::TorEd25519Cert(cert) => Ok(Box::new(cert)),
}
}
pub(crate) fn cert_type(&self) -> CertType {
match self {
CertData::TorEd25519Cert(_) => CertType::Ed25519TorCert,
}
}
}
#[derive(Debug, Clone, derive_more::AsRef)]
pub struct ParsedEd25519Cert {
#[as_ref]
parsed_cert: KeyUnknownCert,
raw: Vec<u8>,
}
impl ParsedEd25519Cert {
pub fn decode(raw: Vec<u8>) -> StdResult<Self, tor_bytes::Error> {
let parsed_cert = Ed25519Cert::decode(&raw)?;
Ok(Self { parsed_cert, raw })
}
pub fn should_be_signed_with(
self,
pkey: &ed25519::Ed25519Identity,
) -> StdResult<UncheckedEd25519Cert, tor_cert::CertError> {
let Self { parsed_cert, raw } = self;
let cert = parsed_cert.should_be_signed_with(pkey)?;
Ok(UncheckedEd25519Cert { cert, raw })
}
}
pub struct UncheckedEd25519Cert {
cert: UncheckedCert,
raw: Vec<u8>,
}
impl tor_checkable::SelfSigned<SigCheckedEd25519Cert> for UncheckedEd25519Cert {
type Error = tor_cert::CertError;
fn is_well_signed(&self) -> StdResult<(), tor_cert::CertError> {
self.cert.is_well_signed()
}
fn dangerously_assume_wellsigned(self) -> SigCheckedEd25519Cert {
let Self { cert, raw } = self;
let cert = cert.dangerously_assume_wellsigned();
SigCheckedEd25519Cert { cert, raw }
}
}
pub struct SigCheckedEd25519Cert {
cert: SigCheckedCert,
raw: Vec<u8>,
}
impl tor_checkable::Timebound<ValidatedEd25519Cert> for SigCheckedEd25519Cert {
type Error = tor_checkable::TimeValidityError;
fn is_valid_at(&self, t: &SystemTime) -> StdResult<(), Self::Error> {
self.cert.is_valid_at(t)
}
fn dangerously_assume_timely(self) -> ValidatedEd25519Cert {
let Self { cert, raw } = self;
let cert = cert.dangerously_assume_timely();
ValidatedEd25519Cert { cert, raw }
}
}
#[derive(Debug, Clone, derive_more::AsRef)]
pub struct ValidatedEd25519Cert {
#[as_ref]
cert: Ed25519Cert,
raw: Vec<u8>,
}
impl ValidatedEd25519Cert {
pub fn subject_key(&self) -> StdResult<&Ed25519Identity, InvalidCertError> {
match self.cert.subject_key() {
tor_cert::CertifiedKey::Ed25519(ed25519_identity) => Ok(ed25519_identity),
_ => Err(InvalidCertError::InvalidSubjectKeyAlgorithm),
}
}
pub fn into_encoded(self) -> EncodedEd25519Cert {
EncodedEd25519Cert::dangerously_from_bytes(&self.raw)
}
}