1use crate::{CertType, InvalidCertError, KeyUnknownCert};
4use tor_cert::{Ed25519Cert, EncodedEd25519Cert, SigCheckedCert, UncheckedCert};
5use tor_checkable::TimeRange;
6use tor_llcrypto::pk::ed25519::{self, Ed25519Identity};
7
8use std::result::Result as StdResult;
9
10#[derive(Clone, Debug)]
12#[non_exhaustive]
13pub enum CertData {
14 TorEd25519Cert(EncodedEd25519Cert),
16}
17
18impl CertData {
19 pub(crate) fn cert_type(&self) -> CertType {
21 match self {
22 CertData::TorEd25519Cert(_) => CertType::Ed25519TorCert,
23 }
24 }
25}
26
27#[derive(Debug, Clone, derive_more::AsRef)]
35pub struct ParsedEd25519Cert {
36 #[as_ref]
38 parsed_cert: KeyUnknownCert,
39 raw: Vec<u8>,
41}
42
43impl ParsedEd25519Cert {
44 pub fn decode(raw: Vec<u8>) -> StdResult<Self, tor_bytes::Error> {
46 let parsed_cert = Ed25519Cert::decode(&raw)?;
47 Ok(Self { parsed_cert, raw })
48 }
49
50 pub fn should_be_signed_with(
54 self,
55 pkey: &ed25519::Ed25519Identity,
56 ) -> StdResult<UncheckedEd25519Cert, tor_cert::CertError> {
57 let Self { parsed_cert, raw } = self;
58
59 let cert = parsed_cert.should_be_signed_with(pkey)?;
60
61 Ok(UncheckedEd25519Cert { cert, raw })
62 }
63}
64
65pub struct UncheckedEd25519Cert {
67 cert: UncheckedCert,
69 raw: Vec<u8>,
71}
72
73impl tor_checkable::SelfSigned<SigCheckedEd25519Cert> for UncheckedEd25519Cert {
74 type Error = tor_cert::CertError;
75
76 fn is_well_signed(&self) -> StdResult<(), tor_cert::CertError> {
77 self.cert.is_well_signed()
78 }
79
80 fn dangerously_assume_wellsigned(self) -> SigCheckedEd25519Cert {
81 let Self { cert, raw } = self;
82
83 let cert = cert.dangerously_assume_wellsigned();
84 SigCheckedEd25519Cert { cert, raw }
85 }
86}
87
88pub struct SigCheckedEd25519Cert {
90 cert: SigCheckedCert,
92 raw: Vec<u8>,
94}
95
96impl tor_checkable::TimeBound for SigCheckedEd25519Cert {
97 type Inner = ValidatedEd25519Cert;
98
99 fn bounds(&self) -> TimeRange {
100 self.cert.bounds()
101 }
102
103 fn dangerously_assume_timely(self) -> ValidatedEd25519Cert {
104 let Self { cert, raw } = self;
105
106 let cert = cert.dangerously_assume_timely();
107 ValidatedEd25519Cert { cert, raw }
108 }
109}
110
111#[derive(Debug, Clone, derive_more::AsRef)]
113pub struct ValidatedEd25519Cert {
114 #[as_ref]
116 cert: Ed25519Cert,
117 raw: Vec<u8>,
119}
120
121impl ValidatedEd25519Cert {
122 pub fn subject_key(&self) -> StdResult<&Ed25519Identity, InvalidCertError> {
124 match self.cert.subject_key() {
125 tor_cert::CertifiedKey::Ed25519(ed25519_identity) => Ok(ed25519_identity),
126 _ => Err(InvalidCertError::InvalidSubjectKeyAlgorithm),
127 }
128 }
129
130 pub fn into_encoded(self) -> EncodedEd25519Cert {
132 EncodedEd25519Cert::dangerously_from_bytes(&self.raw)
133 }
134}